Skip to content

Commit d17b09c

Browse files
Oliver KozulJeffreyALaw
authored andcommitted
[PATCH] RISC-V: optimization on checking certain bits set ((x & mask) == val)
The patch optimizes code generation for comparisons of the form X & C1 == C2 by converting them to (X | ~C1) == (C2 | ~C1). C1 is a constant that requires li and addi to be loaded, while ~C1 requires a single lui instruction. As the values of C1 and C2 are not visible within the equality expression, a plus pattern is matched instead.       PR target/114087 gcc/ChangeLog: * config/riscv/riscv.md (*lui_constraint<ANYI:mode>_and_to_or): New pattern gcc/testsuite/ChangeLog: * gcc.target/riscv/pr114087-1.c: New test.
1 parent d24a5e2 commit d17b09c

File tree

2 files changed

+44
-0
lines changed

2 files changed

+44
-0
lines changed

gcc/config/riscv/riscv.md

Lines changed: 28 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -858,6 +858,34 @@
858858
[(set_attr "type" "arith")
859859
(set_attr "mode" "SI")])
860860

861+
;; Transform (X & C1) + C2 into (X | ~C1) - (-C2 | ~C1)
862+
;; Where C1 is not a LUI operand, but ~C1 is a LUI operand
863+
864+
(define_insn_and_split "*lui_constraint<ANYI:mode>_and_to_or"
865+
[(set (match_operand:ANYI 0 "register_operand" "=r")
866+
(plus:ANYI (and:ANYI (match_operand:ANYI 1 "register_operand" "r")
867+
(match_operand 2 "const_int_operand"))
868+
(match_operand 3 "const_int_operand")))
869+
(clobber (match_scratch:X 4 "=&r"))]
870+
"LUI_OPERAND (~INTVAL (operands[2]))
871+
&& ((INTVAL (operands[2]) & (-INTVAL (operands[3])))
872+
== (-INTVAL (operands[3])))
873+
&& riscv_const_insns (operands[3], false)
874+
&& (riscv_const_insns
875+
(GEN_INT (~INTVAL (operands[2]) | -INTVAL (operands[3])), false)
876+
<= riscv_const_insns (operands[3], false))"
877+
"#"
878+
"&& reload_completed"
879+
[(set (match_dup 4) (match_dup 5))
880+
(set (match_dup 0) (ior:X (match_dup 1) (match_dup 4)))
881+
(set (match_dup 4) (match_dup 6))
882+
(set (match_dup 0) (minus:X (match_dup 0) (match_dup 4)))]
883+
{
884+
operands[5] = GEN_INT (~INTVAL (operands[2]));
885+
operands[6] = GEN_INT ((~INTVAL (operands[2])) | (-INTVAL (operands[3])));
886+
}
887+
[(set_attr "type" "arith")])
888+
861889
;;
862890
;; ....................
863891
;;
Lines changed: 16 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,16 @@
1+
/* { dg-do compile } */
2+
/* { dg-require-effective-target rv64 } */
3+
/* { dg-skip-if "" { *-*-* } { "-O0" "-O1" "-Og" } } */
4+
/* { dg-options "-march=rv64gc -mabi=lp64d" } */
5+
6+
#include <stdbool.h>
7+
#include <stdint.h>
8+
9+
static uint32_t mask1 = 0x55555FFF;
10+
static uint32_t val1 = 0x14501DEF;
11+
12+
bool pred1a(uint32_t x) {
13+
return ((x & mask1) == val1);
14+
}
15+
16+
/* { dg-final { scan-assembler {or\s*[a-x0-9]+,\s*[a-x0-9]+,\s*[a-x0-9]+} } } */

0 commit comments

Comments
 (0)