summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorPhilipp Tomsich <philipp.tomsich@vrull.eu>2020-06-29 15:15:10 +0200
committerPhilipp Tomsich <philipp.tomsich@vrull.eu>2022-06-14 13:17:14 +0200
commit65d121507de7c2bf711b383befd2ba7af8115de1 (patch)
tree270d02d202852000251fbb4b738505761635f5e3
parentDaily bump. (diff)
downloadgcc-65d121507de7c2bf711b383befd2ba7af8115de1.tar.gz
gcc-65d121507de7c2bf711b383befd2ba7af8115de1.tar.bz2
gcc-65d121507de7c2bf711b383befd2ba7af8115de1.tar.xz
RISC-V: bitmanip: improve constant-loading for (1ULL << 31) in DImode
The SINGLE_BIT_MASK_OPERAND() is overly restrictive, triggering for bits above 31 only (to side-step any issues with the negative SImode value 0x80000000/(-1ull << 31)/(1 << 31)). This moves the special handling of this SImode value (i.e. the check for (-1ull << 31) to riscv.cc and relaxes the SINGLE_BIT_MASK_OPERAND() test. With this, the code-generation for loading (1ULL << 31) from: li a0,1 slli a0,a0,31 to: bseti a0,zero,31 gcc/ChangeLog: * config/riscv/riscv.cc (riscv_build_integer_1): Rewrite value as (-1 << 31) for the single-bit case, when operating on (1 << 31) in SImode. * config/riscv/riscv.h (SINGLE_BIT_MASK_OPERAND): Allow for any single-bit value, moving the special case for (1 << 31) to riscv_build_integer_1 (in riscv.c). Signed-off-by: Philipp Tomsich <philipp.tomsich@vrull.eu> (cherry picked from commit 4e72ccad80d69a76d149fba59603b8173fffe8fe)
-rw-r--r--gcc/config/riscv/riscv.cc9
-rw-r--r--gcc/config/riscv/riscv.h11
2 files changed, 13 insertions, 7 deletions
diff --git a/gcc/config/riscv/riscv.cc b/gcc/config/riscv/riscv.cc
index f3ac0d8865f..4939d9964db 100644
--- a/gcc/config/riscv/riscv.cc
+++ b/gcc/config/riscv/riscv.cc
@@ -420,6 +420,15 @@ riscv_build_integer_1 (struct riscv_integer_op codes[RISCV_MAX_INTEGER_OPS],
420 /* Simply BSETI. */ 420 /* Simply BSETI. */
421 codes[0].code = UNKNOWN; 421 codes[0].code = UNKNOWN;
422 codes[0].value = value; 422 codes[0].value = value;
423
424 /* RISC-V sign-extends all 32bit values that live in a 32bit
425 register. To avoid paradoxes, we thus need to use the
426 sign-extended (negative) representation (-1 << 31) for the
427 value, if we want to build (1 << 31) in SImode. This will
428 then expand to an LUI instruction. */
429 if (mode == SImode && value == (HOST_WIDE_INT_1U << 31))
430 codes[0].value = (HOST_WIDE_INT_M1U << 31);
431
423 return 1; 432 return 1;
424 } 433 }
425 434
diff --git a/gcc/config/riscv/riscv.h b/gcc/config/riscv/riscv.h
index b191606edb4..b3eb6abc2aa 100644
--- a/gcc/config/riscv/riscv.h
+++ b/gcc/config/riscv/riscv.h
@@ -528,13 +528,10 @@ enum reg_class
528 (((VALUE) | ((1UL<<31) - IMM_REACH)) == ((1UL<<31) - IMM_REACH) \ 528 (((VALUE) | ((1UL<<31) - IMM_REACH)) == ((1UL<<31) - IMM_REACH) \
529 || ((VALUE) | ((1UL<<31) - IMM_REACH)) + IMM_REACH == 0) 529 || ((VALUE) | ((1UL<<31) - IMM_REACH)) + IMM_REACH == 0)
530 530
531/* If this is a single bit mask, then we can load it with bseti. But this 531/* If this is a single bit mask, then we can load it with bseti. Special
532 is not useful for any of the low 31 bits because we can use addi or lui 532 handling of SImode 0x80000000 on RV64 is done in riscv_build_integer_1. */
533 to load them. It is wrong for loading SImode 0x80000000 on rv64 because it 533#define SINGLE_BIT_MASK_OPERAND(VALUE) \
534 needs to be sign-extended. So we restrict this to the upper 32-bits 534 (pow2p_hwi (VALUE))
535 only. */
536#define SINGLE_BIT_MASK_OPERAND(VALUE) \
537 (pow2p_hwi (VALUE) && (ctz_hwi (VALUE) >= 32))
538 535
539/* Stack layout; function entry, exit and calling. */ 536/* Stack layout; function entry, exit and calling. */
540 537