diff options
author | Jim Wilson <jimw@sifive.com> | 2018-05-17 22:37:38 +0000 |
---|---|---|
committer | Jim Wilson <wilson@gcc.gnu.org> | 2018-05-17 15:37:38 -0700 |
commit | 7bbce9b50302959286381d9177818642bceaf301 (patch) | |
tree | 0ce4f20f1d1ab9a42ba1843c8d03e69332f11446 /gcc/expr.c | |
parent | 4e0684beff1fcd8398425b1fbe237cdbcb34c359 (diff) | |
download | gcc-7bbce9b50302959286381d9177818642bceaf301.zip gcc-7bbce9b50302959286381d9177818642bceaf301.tar.gz gcc-7bbce9b50302959286381d9177818642bceaf301.tar.bz2 |
RISC-V: Optimize switch with sign-extended index.
gcc/
* expr.c (do_tablejump): When converting index to Pmode, if we have a
sign extended promoted subreg, and the range does not have the sign bit
set, then do a sign extend.
* config/riscv/riscv.c (riscv_extend_comparands): In unsigned QImode
test, check for sign extended subreg and/or constant operands, and
do a sign extend in that case.
gcc/testsuite/
* gcc.target/riscv/switch-qi.c: New.
* gcc.target/riscv/switch-si.c: New.
From-SVN: r260340
Diffstat (limited to 'gcc/expr.c')
-rw-r--r-- | gcc/expr.c | 19 |
1 files changed, 17 insertions, 2 deletions
@@ -11782,11 +11782,26 @@ do_tablejump (rtx index, machine_mode mode, rtx range, rtx table_label, emit_cmp_and_jump_insns (index, range, GTU, NULL_RTX, mode, 1, default_label, default_probability); - /* If index is in range, it must fit in Pmode. Convert to Pmode so we can index with it. */ if (mode != Pmode) - index = convert_to_mode (Pmode, index, 1); + { + unsigned int width; + + /* We know the value of INDEX is between 0 and RANGE. If we have a + sign-extended subreg, and RANGE does not have the sign bit set, then + we have a value that is valid for both sign and zero extension. In + this case, we get better code if we sign extend. */ + if (GET_CODE (index) == SUBREG + && SUBREG_PROMOTED_VAR_P (index) + && SUBREG_PROMOTED_SIGNED_P (index) + && ((width = GET_MODE_PRECISION (as_a <scalar_int_mode> (mode))) + <= HOST_BITS_PER_WIDE_INT) + && ! (UINTVAL (range) & (HOST_WIDE_INT_1U << (width - 1)))) + index = convert_to_mode (Pmode, index, 0); + else + index = convert_to_mode (Pmode, index, 1); + } /* Don't let a MEM slip through, because then INDEX that comes out of PIC_CASE_VECTOR_ADDRESS won't be a valid address, |