Skip to content

Commit 944f4ad

Browse files
authored
[RISCV][ISel] Select binvi for pattern icmp eq/ne X, pow2 (#110957)
This patch selects `binvi` for pattern `icmp eq/ne X, pow2` when zbs is available.
1 parent b0b1a11 commit 944f4ad

File tree

3 files changed

+118
-0
lines changed

3 files changed

+118
-0
lines changed

llvm/lib/Target/RISCV/RISCVISelDAGToDAG.cpp

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -2938,6 +2938,14 @@ bool RISCVDAGToDAGISel::selectSETCC(SDValue N, ISD::CondCode ExpectedCCVal,
29382938
0);
29392939
return true;
29402940
}
2941+
if (isPowerOf2_64(CVal) && Subtarget->hasStdExtZbs()) {
2942+
Val = SDValue(
2943+
CurDAG->getMachineNode(
2944+
RISCV::BINVI, DL, N->getValueType(0), LHS,
2945+
CurDAG->getTargetConstant(Log2_64(CVal), DL, N->getValueType(0))),
2946+
0);
2947+
return true;
2948+
}
29412949
}
29422950

29432951
// If nothing else we can XOR the LHS and RHS to produce zero if they are

llvm/test/CodeGen/RISCV/rv32zbs.ll

Lines changed: 46 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -837,3 +837,49 @@ define i64 @bset_trailing_ones_i64_no_mask(i64 %a) nounwind {
837837
%not = xor i64 %shift, -1
838838
ret i64 %not
839839
}
840+
841+
define i1 @icmp_eq_pow2(i32 %x) nounwind {
842+
; RV32I-LABEL: icmp_eq_pow2:
843+
; RV32I: # %bb.0:
844+
; RV32I-NEXT: lui a1, 8
845+
; RV32I-NEXT: xor a0, a0, a1
846+
; RV32I-NEXT: seqz a0, a0
847+
; RV32I-NEXT: ret
848+
;
849+
; RV32ZBS-LABEL: icmp_eq_pow2:
850+
; RV32ZBS: # %bb.0:
851+
; RV32ZBS-NEXT: binvi a0, a0, 15
852+
; RV32ZBS-NEXT: seqz a0, a0
853+
; RV32ZBS-NEXT: ret
854+
%cmp = icmp eq i32 %x, 32768
855+
ret i1 %cmp
856+
}
857+
858+
define i1 @icmp_ne_pow2(i32 %x) nounwind {
859+
; RV32I-LABEL: icmp_ne_pow2:
860+
; RV32I: # %bb.0:
861+
; RV32I-NEXT: lui a1, 8
862+
; RV32I-NEXT: xor a0, a0, a1
863+
; RV32I-NEXT: seqz a0, a0
864+
; RV32I-NEXT: ret
865+
;
866+
; RV32ZBS-LABEL: icmp_ne_pow2:
867+
; RV32ZBS: # %bb.0:
868+
; RV32ZBS-NEXT: binvi a0, a0, 15
869+
; RV32ZBS-NEXT: seqz a0, a0
870+
; RV32ZBS-NEXT: ret
871+
%cmp = icmp eq i32 %x, 32768
872+
ret i1 %cmp
873+
}
874+
875+
define i1 @icmp_eq_nonpow2(i32 %x) nounwind {
876+
; CHECK-LABEL: icmp_eq_nonpow2:
877+
; CHECK: # %bb.0:
878+
; CHECK-NEXT: lui a1, 8
879+
; CHECK-NEXT: addi a1, a1, -1
880+
; CHECK-NEXT: xor a0, a0, a1
881+
; CHECK-NEXT: seqz a0, a0
882+
; CHECK-NEXT: ret
883+
%cmp = icmp eq i32 %x, 32767
884+
ret i1 %cmp
885+
}

llvm/test/CodeGen/RISCV/rv64zbs.ll

Lines changed: 64 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1146,3 +1146,67 @@ define signext i64 @bset_trailing_ones_i64_no_mask(i64 signext %a) nounwind {
11461146
%not = xor i64 %shift, -1
11471147
ret i64 %not
11481148
}
1149+
1150+
define i1 @icmp_eq_pow2(i32 signext %x) nounwind {
1151+
; RV64I-LABEL: icmp_eq_pow2:
1152+
; RV64I: # %bb.0:
1153+
; RV64I-NEXT: lui a1, 8
1154+
; RV64I-NEXT: xor a0, a0, a1
1155+
; RV64I-NEXT: seqz a0, a0
1156+
; RV64I-NEXT: ret
1157+
;
1158+
; RV64ZBS-LABEL: icmp_eq_pow2:
1159+
; RV64ZBS: # %bb.0:
1160+
; RV64ZBS-NEXT: binvi a0, a0, 15
1161+
; RV64ZBS-NEXT: seqz a0, a0
1162+
; RV64ZBS-NEXT: ret
1163+
%cmp = icmp eq i32 %x, 32768
1164+
ret i1 %cmp
1165+
}
1166+
1167+
define i1 @icmp_eq_pow2_64(i64 %x) nounwind {
1168+
; RV64I-LABEL: icmp_eq_pow2_64:
1169+
; RV64I: # %bb.0:
1170+
; RV64I-NEXT: li a1, 1
1171+
; RV64I-NEXT: slli a1, a1, 40
1172+
; RV64I-NEXT: xor a0, a0, a1
1173+
; RV64I-NEXT: seqz a0, a0
1174+
; RV64I-NEXT: ret
1175+
;
1176+
; RV64ZBS-LABEL: icmp_eq_pow2_64:
1177+
; RV64ZBS: # %bb.0:
1178+
; RV64ZBS-NEXT: binvi a0, a0, 40
1179+
; RV64ZBS-NEXT: seqz a0, a0
1180+
; RV64ZBS-NEXT: ret
1181+
%cmp = icmp eq i64 %x, 1099511627776
1182+
ret i1 %cmp
1183+
}
1184+
1185+
define i1 @icmp_ne_pow2(i32 signext %x) nounwind {
1186+
; RV64I-LABEL: icmp_ne_pow2:
1187+
; RV64I: # %bb.0:
1188+
; RV64I-NEXT: lui a1, 8
1189+
; RV64I-NEXT: xor a0, a0, a1
1190+
; RV64I-NEXT: seqz a0, a0
1191+
; RV64I-NEXT: ret
1192+
;
1193+
; RV64ZBS-LABEL: icmp_ne_pow2:
1194+
; RV64ZBS: # %bb.0:
1195+
; RV64ZBS-NEXT: binvi a0, a0, 15
1196+
; RV64ZBS-NEXT: seqz a0, a0
1197+
; RV64ZBS-NEXT: ret
1198+
%cmp = icmp eq i32 %x, 32768
1199+
ret i1 %cmp
1200+
}
1201+
1202+
define i1 @icmp_eq_nonpow2(i32 signext %x) nounwind {
1203+
; CHECK-LABEL: icmp_eq_nonpow2:
1204+
; CHECK: # %bb.0:
1205+
; CHECK-NEXT: lui a1, 8
1206+
; CHECK-NEXT: addiw a1, a1, -1
1207+
; CHECK-NEXT: xor a0, a0, a1
1208+
; CHECK-NEXT: seqz a0, a0
1209+
; CHECK-NEXT: ret
1210+
%cmp = icmp eq i32 %x, 32767
1211+
ret i1 %cmp
1212+
}

0 commit comments

Comments
 (0)