Skip to content

Commit 0c1ab02

Browse files
authored
[RISCV] Use bseti 31 for (or X, -2147483648) when upper 32 bits aren't used. (#159678)
If the original type was i32, type legalization will sign extend the constant. This prevents it from having a single bit set or clear so other patterns can't match. If the upper bits aren't used, we can ignore the sign extension. Similar for bclri and binvi.
1 parent dda7ce6 commit 0c1ab02

File tree

2 files changed

+68
-1
lines changed

2 files changed

+68
-1
lines changed

llvm/lib/Target/RISCV/RISCVInstrInfoZb.td

Lines changed: 13 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -574,6 +574,19 @@ def : Pat<(XLenVT (and GPR:$r, BCLRIANDIMask:$i)),
574574
(BCLRITwoBitsMaskHigh BCLRIANDIMask:$i))>;
575575
} // Predicates = [HasStdExtZbs]
576576

577+
let Predicates = [HasStdExtZbs, IsRV64] in {
578+
// If the original code was setting, clearing, or inverting bit 31 of an i32,
579+
// type legalization might have sign extended the constant so it doesn't have a
580+
// single 0 or 1 bit. If the upper 32 bits aren't used by later instructions we
581+
// can still use bseti/bclri.
582+
def : Pat<(binop_allwusers<and> GPR:$rs1, (XLenVT 2147483647)),
583+
(BCLRI GPR:$rs1, 31)>;
584+
def : Pat<(binop_allwusers<or> GPR:$rs1, (XLenVT -2147483648)),
585+
(BSETI GPR:$rs1, 31)>;
586+
def : Pat<(binop_allwusers<xor> GPR:$rs1, (XLenVT -2147483648)),
587+
(BINVI GPR:$rs1, 31)>;
588+
}
589+
577590
let Predicates = [HasStdExtZbb] in
578591
def : PatGpr<riscv_orc_b, ORC_B>;
579592

llvm/test/CodeGen/RISCV/rv64zbs.ll

Lines changed: 55 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -547,10 +547,28 @@ define signext i32 @bclri_i32_31(i32 signext %a) nounwind {
547547
; CHECK-NEXT: slli a0, a0, 33
548548
; CHECK-NEXT: srli a0, a0, 33
549549
; CHECK-NEXT: ret
550-
%and = and i32 %a, -2147483649
550+
%and = and i32 %a, 2147483647
551551
ret i32 %and
552552
}
553553

554+
define signext i32 @bclri_i32_31_allWUsers(i32 signext %a) nounwind {
555+
; RV64I-LABEL: bclri_i32_31_allWUsers:
556+
; RV64I: # %bb.0:
557+
; RV64I-NEXT: slli a0, a0, 33
558+
; RV64I-NEXT: srli a0, a0, 33
559+
; RV64I-NEXT: addiw a0, a0, 1
560+
; RV64I-NEXT: ret
561+
;
562+
; RV64ZBS-LABEL: bclri_i32_31_allWUsers:
563+
; RV64ZBS: # %bb.0:
564+
; RV64ZBS-NEXT: bclri a0, a0, 31
565+
; RV64ZBS-NEXT: addiw a0, a0, 1
566+
; RV64ZBS-NEXT: ret
567+
%and = and i32 %a, 2147483647
568+
%add = add i32 %and, 1
569+
ret i32 %add
570+
}
571+
554572
define i64 @bclri_i64_10(i64 %a) nounwind {
555573
; CHECK-LABEL: bclri_i64_10:
556574
; CHECK: # %bb.0:
@@ -724,6 +742,24 @@ define signext i32 @bseti_i32_31(i32 signext %a) nounwind {
724742
ret i32 %or
725743
}
726744

745+
define signext i32 @bseti_i32_31_allWUsers(i32 signext %a) nounwind {
746+
; RV64I-LABEL: bseti_i32_31_allWUsers:
747+
; RV64I: # %bb.0:
748+
; RV64I-NEXT: lui a1, 524288
749+
; RV64I-NEXT: or a0, a0, a1
750+
; RV64I-NEXT: addiw a0, a0, 1
751+
; RV64I-NEXT: ret
752+
;
753+
; RV64ZBS-LABEL: bseti_i32_31_allWUsers:
754+
; RV64ZBS: # %bb.0:
755+
; RV64ZBS-NEXT: bseti a0, a0, 31
756+
; RV64ZBS-NEXT: addiw a0, a0, 1
757+
; RV64ZBS-NEXT: ret
758+
%or = or i32 %a, 2147483648
759+
%add = add i32 %or, 1
760+
ret i32 %add
761+
}
762+
727763
define i64 @bseti_i64_10(i64 %a) nounwind {
728764
; CHECK-LABEL: bseti_i64_10:
729765
; CHECK: # %bb.0:
@@ -862,6 +898,24 @@ define signext i32 @binvi_i32_31(i32 signext %a) nounwind {
862898
ret i32 %xor
863899
}
864900

901+
define void @binvi_i32_31_allWUsers(i32 signext %a, ptr %p) nounwind {
902+
; RV64I-LABEL: binvi_i32_31_allWUsers:
903+
; RV64I: # %bb.0:
904+
; RV64I-NEXT: lui a2, 524288
905+
; RV64I-NEXT: xor a0, a0, a2
906+
; RV64I-NEXT: sw a0, 0(a1)
907+
; RV64I-NEXT: ret
908+
;
909+
; RV64ZBS-LABEL: binvi_i32_31_allWUsers:
910+
; RV64ZBS: # %bb.0:
911+
; RV64ZBS-NEXT: binvi a0, a0, 31
912+
; RV64ZBS-NEXT: sw a0, 0(a1)
913+
; RV64ZBS-NEXT: ret
914+
%xor = xor i32 %a, 2147483648
915+
store i32 %xor, ptr %p
916+
ret void
917+
}
918+
865919
define i64 @binvi_i64_10(i64 %a) nounwind {
866920
; CHECK-LABEL: binvi_i64_10:
867921
; CHECK: # %bb.0:

0 commit comments

Comments
 (0)