Skip to content

Commit 2817873

Browse files
authored
[RISCV] Fold (sext_inreg (setcc), i1) -> (sub 0, (setcc). (llvm#154206)
This helps the 3 vendor extensions that make sext_inreg i1 legal. I'm delaying this until after LegalizeDAG since we normally have sext_inreg i1 up until LegalizeDAG turns it into and+neg. I also delayed the recently added (sext_inreg (xor (setcc), -1), i1) combine. Though the xor isn't likely to appear before LegalizeDAG anyway.
1 parent 00ffd8b commit 2817873

File tree

6 files changed

+252
-8
lines changed

6 files changed

+252
-8
lines changed

llvm/lib/Target/RISCV/RISCVISelLowering.cpp

Lines changed: 13 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -16639,33 +16639,38 @@ static SDValue performSETCCCombine(SDNode *N, SelectionDAG &DAG,
1663916639
}
1664016640

1664116641
static SDValue
16642-
performSIGN_EXTEND_INREGCombine(SDNode *N, SelectionDAG &DAG,
16642+
performSIGN_EXTEND_INREGCombine(SDNode *N, TargetLowering::DAGCombinerInfo &DCI,
1664316643
const RISCVSubtarget &Subtarget) {
16644+
SelectionDAG &DAG = DCI.DAG;
1664416645
SDValue Src = N->getOperand(0);
1664516646
EVT VT = N->getValueType(0);
1664616647
EVT SrcVT = cast<VTSDNode>(N->getOperand(1))->getVT();
1664716648
unsigned Opc = Src.getOpcode();
16649+
SDLoc DL(N);
1664816650

1664916651
// Fold (sext_inreg (fmv_x_anyexth X), i16) -> (fmv_x_signexth X)
1665016652
// Don't do this with Zhinx. We need to explicitly sign extend the GPR.
1665116653
if (Opc == RISCVISD::FMV_X_ANYEXTH && SrcVT.bitsGE(MVT::i16) &&
1665216654
Subtarget.hasStdExtZfhmin())
16653-
return DAG.getNode(RISCVISD::FMV_X_SIGNEXTH, SDLoc(N), VT,
16654-
Src.getOperand(0));
16655+
return DAG.getNode(RISCVISD::FMV_X_SIGNEXTH, DL, VT, Src.getOperand(0));
1665516656

1665616657
// Fold (sext_inreg (shl X, Y), i32) -> (sllw X, Y) iff Y u< 32
1665716658
if (Opc == ISD::SHL && Subtarget.is64Bit() && SrcVT == MVT::i32 &&
1665816659
VT == MVT::i64 && !isa<ConstantSDNode>(Src.getOperand(1)) &&
1665916660
DAG.computeKnownBits(Src.getOperand(1)).countMaxActiveBits() <= 5)
16660-
return DAG.getNode(RISCVISD::SLLW, SDLoc(N), VT, Src.getOperand(0),
16661+
return DAG.getNode(RISCVISD::SLLW, DL, VT, Src.getOperand(0),
1666116662
Src.getOperand(1));
1666216663

16664+
// Fold (sext_inreg (setcc), i1) -> (sub 0, (setcc))
16665+
if (Opc == ISD::SETCC && SrcVT == MVT::i1 && DCI.isAfterLegalizeDAG())
16666+
return DAG.getNode(ISD::SUB, DL, VT, DAG.getConstant(0, DL, VT), Src);
16667+
1666316668
// Fold (sext_inreg (xor (setcc), -1), i1) -> (add (setcc), -1)
1666416669
if (Opc == ISD::XOR && SrcVT == MVT::i1 &&
1666516670
isAllOnesConstant(Src.getOperand(1)) &&
16666-
Src.getOperand(0).getOpcode() == ISD::SETCC)
16667-
return DAG.getNode(ISD::ADD, SDLoc(N), VT, Src.getOperand(0),
16668-
DAG.getAllOnesConstant(SDLoc(N), VT));
16671+
Src.getOperand(0).getOpcode() == ISD::SETCC && DCI.isAfterLegalizeDAG())
16672+
return DAG.getNode(ISD::ADD, DL, VT, Src.getOperand(0),
16673+
DAG.getAllOnesConstant(DL, VT));
1666916674

1667016675
return SDValue();
1667116676
}
@@ -20088,7 +20093,7 @@ SDValue RISCVTargetLowering::PerformDAGCombine(SDNode *N,
2008820093
case ISD::SETCC:
2008920094
return performSETCCCombine(N, DAG, Subtarget);
2009020095
case ISD::SIGN_EXTEND_INREG:
20091-
return performSIGN_EXTEND_INREGCombine(N, DAG, Subtarget);
20096+
return performSIGN_EXTEND_INREGCombine(N, DCI, Subtarget);
2009220097
case ISD::ZERO_EXTEND:
2009320098
// Fold (zero_extend (fp_to_uint X)) to prevent forming fcvt+zexti32 during
2009420099
// type legalization. This is safe because fp_to_uint produces poison if

llvm/test/CodeGen/RISCV/rv32xandesperf.ll

Lines changed: 25 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -346,6 +346,31 @@ define zeroext i8 @sexti1_i32_setcc(i32 signext %a) {
346346
ret i8 %sext
347347
}
348348

349+
; Make sure we don't use seqz+nds.bfos instead of snez+addi
350+
define i32 @sexti1_i32_setcc_2(i32 %a, i32 %b) {
351+
; CHECK-LABEL: sexti1_i32_setcc_2:
352+
; CHECK: # %bb.0:
353+
; CHECK-NEXT: xor a0, a0, a1
354+
; CHECK-NEXT: snez a0, a0
355+
; CHECK-NEXT: addi a0, a0, -1
356+
; CHECK-NEXT: ret
357+
%icmp = icmp eq i32 %a, %b
358+
%sext = sext i1 %icmp to i32
359+
ret i32 %sext
360+
}
361+
362+
; Make sure we don't use nds.bfos instead of neg.
363+
define i32 @sexti1_i32_setcc_3(i32 %a, i32 %b) {
364+
; CHECK-LABEL: sexti1_i32_setcc_3:
365+
; CHECK: # %bb.0:
366+
; CHECK-NEXT: slt a0, a0, a1
367+
; CHECK-NEXT: neg a0, a0
368+
; CHECK-NEXT: ret
369+
%icmp = icmp slt i32 %a, %b
370+
%sext = sext i1 %icmp to i32
371+
ret i32 %sext
372+
}
373+
349374
define i32 @sexti8_i32(i32 %a) {
350375
; CHECK-LABEL: sexti8_i32:
351376
; CHECK: # %bb.0:

llvm/test/CodeGen/RISCV/rv32xtheadbb.ll

Lines changed: 38 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -372,6 +372,44 @@ define zeroext i8 @sexti1_i32_setcc(i32 signext %a) {
372372
ret i8 %sext
373373
}
374374

375+
; Make sure we don't use seqz+th.ext instead of snez+addi
376+
define i32 @sexti1_i32_setcc_2(i32 %a, i32 %b) {
377+
; RV32I-LABEL: sexti1_i32_setcc_2:
378+
; RV32I: # %bb.0:
379+
; RV32I-NEXT: xor a0, a0, a1
380+
; RV32I-NEXT: snez a0, a0
381+
; RV32I-NEXT: addi a0, a0, -1
382+
; RV32I-NEXT: ret
383+
;
384+
; RV32XTHEADBB-LABEL: sexti1_i32_setcc_2:
385+
; RV32XTHEADBB: # %bb.0:
386+
; RV32XTHEADBB-NEXT: xor a0, a0, a1
387+
; RV32XTHEADBB-NEXT: snez a0, a0
388+
; RV32XTHEADBB-NEXT: addi a0, a0, -1
389+
; RV32XTHEADBB-NEXT: ret
390+
%icmp = icmp eq i32 %a, %b
391+
%sext = sext i1 %icmp to i32
392+
ret i32 %sext
393+
}
394+
395+
; Make sure we don't use th.ext instead of neg.
396+
define i32 @sexti1_i32_setcc_3(i32 %a, i32 %b) {
397+
; RV32I-LABEL: sexti1_i32_setcc_3:
398+
; RV32I: # %bb.0:
399+
; RV32I-NEXT: slt a0, a0, a1
400+
; RV32I-NEXT: neg a0, a0
401+
; RV32I-NEXT: ret
402+
;
403+
; RV32XTHEADBB-LABEL: sexti1_i32_setcc_3:
404+
; RV32XTHEADBB: # %bb.0:
405+
; RV32XTHEADBB-NEXT: slt a0, a0, a1
406+
; RV32XTHEADBB-NEXT: neg a0, a0
407+
; RV32XTHEADBB-NEXT: ret
408+
%icmp = icmp slt i32 %a, %b
409+
%sext = sext i1 %icmp to i32
410+
ret i32 %sext
411+
}
412+
375413
define i32 @sextb_i32(i32 %a) nounwind {
376414
; RV32I-LABEL: sextb_i32:
377415
; RV32I: # %bb.0:

llvm/test/CodeGen/RISCV/rv64xandesperf.ll

Lines changed: 50 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -290,6 +290,31 @@ define zeroext i8 @sexti1_i32_setcc(i32 signext %a) {
290290
ret i8 %sext
291291
}
292292

293+
; Make sure we don't use seqz+nds.bfos instead of snez+addi
294+
define signext i32 @sexti1_i32_setcc_2(i32 signext %a, i32 signext %b) {
295+
; CHECK-LABEL: sexti1_i32_setcc_2:
296+
; CHECK: # %bb.0:
297+
; CHECK-NEXT: xor a0, a0, a1
298+
; CHECK-NEXT: snez a0, a0
299+
; CHECK-NEXT: addi a0, a0, -1
300+
; CHECK-NEXT: ret
301+
%icmp = icmp eq i32 %a, %b
302+
%sext = sext i1 %icmp to i32
303+
ret i32 %sext
304+
}
305+
306+
; Make sure we don't use nds.bfos instead of neg.
307+
define signext i32 @sexti1_i32_setcc_3(i32 signext %a, i32 signext %b) {
308+
; CHECK-LABEL: sexti1_i32_setcc_3:
309+
; CHECK: # %bb.0:
310+
; CHECK-NEXT: slt a0, a0, a1
311+
; CHECK-NEXT: neg a0, a0
312+
; CHECK-NEXT: ret
313+
%icmp = icmp slt i32 %a, %b
314+
%sext = sext i1 %icmp to i32
315+
ret i32 %sext
316+
}
317+
293318
define signext i32 @sexti8_i32(i32 signext %a) {
294319
; CHECK-LABEL: sexti8_i32:
295320
; CHECK: # %bb.0:
@@ -360,6 +385,31 @@ define zeroext i8 @sexti1_i64_setcc(i64 %a) {
360385
ret i8 %sext
361386
}
362387

388+
; Make sure we don't use seqz+nds.bfos instead of snez+addi
389+
define i64 @sexti1_i64_setcc_2(i64 %a, i64 %b) {
390+
; CHECK-LABEL: sexti1_i64_setcc_2:
391+
; CHECK: # %bb.0:
392+
; CHECK-NEXT: xor a0, a0, a1
393+
; CHECK-NEXT: snez a0, a0
394+
; CHECK-NEXT: addi a0, a0, -1
395+
; CHECK-NEXT: ret
396+
%icmp = icmp eq i64 %a, %b
397+
%sext = sext i1 %icmp to i64
398+
ret i64 %sext
399+
}
400+
401+
; Make sure we don't use nds.bfos instead of neg.
402+
define i64 @sexti1_i64_setcc_3(i64 %a, i64 %b) {
403+
; CHECK-LABEL: sexti1_i64_setcc_3:
404+
; CHECK: # %bb.0:
405+
; CHECK-NEXT: slt a0, a0, a1
406+
; CHECK-NEXT: neg a0, a0
407+
; CHECK-NEXT: ret
408+
%icmp = icmp slt i64 %a, %b
409+
%sext = sext i1 %icmp to i64
410+
ret i64 %sext
411+
}
412+
363413
define i64 @sexti8_i64(i64 %a) {
364414
; CHECK-LABEL: sexti8_i64:
365415
; CHECK: # %bb.0:

llvm/test/CodeGen/RISCV/rv64xtheadbb.ll

Lines changed: 76 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -729,6 +729,44 @@ define zeroext i8 @sexti1_i32_setcc(i32 signext %a) {
729729
ret i8 %sext
730730
}
731731

732+
; Make sure we don't use seqz+th.ext instead of snez+addi
733+
define signext i32 @sexti1_i32_setcc_2(i32 signext %a, i32 signext %b) {
734+
; RV64I-LABEL: sexti1_i32_setcc_2:
735+
; RV64I: # %bb.0:
736+
; RV64I-NEXT: xor a0, a0, a1
737+
; RV64I-NEXT: snez a0, a0
738+
; RV64I-NEXT: addi a0, a0, -1
739+
; RV64I-NEXT: ret
740+
;
741+
; RV64XTHEADBB-LABEL: sexti1_i32_setcc_2:
742+
; RV64XTHEADBB: # %bb.0:
743+
; RV64XTHEADBB-NEXT: xor a0, a0, a1
744+
; RV64XTHEADBB-NEXT: snez a0, a0
745+
; RV64XTHEADBB-NEXT: addi a0, a0, -1
746+
; RV64XTHEADBB-NEXT: ret
747+
%icmp = icmp eq i32 %a, %b
748+
%sext = sext i1 %icmp to i32
749+
ret i32 %sext
750+
}
751+
752+
; Make sure we don't use th.ext instead of neg.
753+
define signext i32 @sexti1_i32_setcc_3(i32 signext %a, i32 signext %b) {
754+
; RV64I-LABEL: sexti1_i32_setcc_3:
755+
; RV64I: # %bb.0:
756+
; RV64I-NEXT: slt a0, a0, a1
757+
; RV64I-NEXT: neg a0, a0
758+
; RV64I-NEXT: ret
759+
;
760+
; RV64XTHEADBB-LABEL: sexti1_i32_setcc_3:
761+
; RV64XTHEADBB: # %bb.0:
762+
; RV64XTHEADBB-NEXT: slt a0, a0, a1
763+
; RV64XTHEADBB-NEXT: neg a0, a0
764+
; RV64XTHEADBB-NEXT: ret
765+
%icmp = icmp slt i32 %a, %b
766+
%sext = sext i1 %icmp to i32
767+
ret i32 %sext
768+
}
769+
732770
define i64 @sexti1_i64(i64 %a) nounwind {
733771
; RV64I-LABEL: sexti1_i64:
734772
; RV64I: # %bb.0:
@@ -780,6 +818,44 @@ define zeroext i8 @sexti1_i64_setcc(i64 %a) {
780818
ret i8 %sext
781819
}
782820

821+
; Make sure we don't use seqz+th.ext instead of snez+addi
822+
define i64 @sexti1_i64_setcc_2(i64 %a, i64 %b) {
823+
; RV64I-LABEL: sexti1_i64_setcc_2:
824+
; RV64I: # %bb.0:
825+
; RV64I-NEXT: xor a0, a0, a1
826+
; RV64I-NEXT: snez a0, a0
827+
; RV64I-NEXT: addi a0, a0, -1
828+
; RV64I-NEXT: ret
829+
;
830+
; RV64XTHEADBB-LABEL: sexti1_i64_setcc_2:
831+
; RV64XTHEADBB: # %bb.0:
832+
; RV64XTHEADBB-NEXT: xor a0, a0, a1
833+
; RV64XTHEADBB-NEXT: snez a0, a0
834+
; RV64XTHEADBB-NEXT: addi a0, a0, -1
835+
; RV64XTHEADBB-NEXT: ret
836+
%icmp = icmp eq i64 %a, %b
837+
%sext = sext i1 %icmp to i64
838+
ret i64 %sext
839+
}
840+
841+
; Make sure we don't use th.ext instead of neg.
842+
define i64 @sexti1_i64_setcc_3(i64 %a, i64 %b) {
843+
; RV64I-LABEL: sexti1_i64_setcc_3:
844+
; RV64I: # %bb.0:
845+
; RV64I-NEXT: slt a0, a0, a1
846+
; RV64I-NEXT: neg a0, a0
847+
; RV64I-NEXT: ret
848+
;
849+
; RV64XTHEADBB-LABEL: sexti1_i64_setcc_3:
850+
; RV64XTHEADBB: # %bb.0:
851+
; RV64XTHEADBB-NEXT: slt a0, a0, a1
852+
; RV64XTHEADBB-NEXT: neg a0, a0
853+
; RV64XTHEADBB-NEXT: ret
854+
%icmp = icmp slt i64 %a, %b
855+
%sext = sext i1 %icmp to i64
856+
ret i64 %sext
857+
}
858+
783859
define signext i32 @sextb_i32(i32 signext %a) nounwind {
784860
; RV64I-LABEL: sextb_i32:
785861
; RV64I: # %bb.0:

llvm/test/CodeGen/RISCV/xqcibm-extract.ll

Lines changed: 50 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -74,6 +74,56 @@ define zeroext i8 @sexti1_i32_setcc(i32 signext %a) {
7474
ret i8 %sext
7575
}
7676

77+
; Make sure we don't use seqz+qc.ext instead of snez+addi
78+
define i32 @sexti1_i32_setcc_2(i32 %a, i32 %b) {
79+
; RV32I-LABEL: sexti1_i32_setcc_2:
80+
; RV32I: # %bb.0:
81+
; RV32I-NEXT: xor a0, a0, a1
82+
; RV32I-NEXT: snez a0, a0
83+
; RV32I-NEXT: addi a0, a0, -1
84+
; RV32I-NEXT: ret
85+
;
86+
; RV32XQCIBM-LABEL: sexti1_i32_setcc_2:
87+
; RV32XQCIBM: # %bb.0:
88+
; RV32XQCIBM-NEXT: xor a0, a0, a1
89+
; RV32XQCIBM-NEXT: snez a0, a0
90+
; RV32XQCIBM-NEXT: addi a0, a0, -1
91+
; RV32XQCIBM-NEXT: ret
92+
;
93+
; RV32XQCIBMZBB-LABEL: sexti1_i32_setcc_2:
94+
; RV32XQCIBMZBB: # %bb.0:
95+
; RV32XQCIBMZBB-NEXT: xor a0, a0, a1
96+
; RV32XQCIBMZBB-NEXT: snez a0, a0
97+
; RV32XQCIBMZBB-NEXT: addi a0, a0, -1
98+
; RV32XQCIBMZBB-NEXT: ret
99+
%icmp = icmp eq i32 %a, %b
100+
%sext = sext i1 %icmp to i32
101+
ret i32 %sext
102+
}
103+
104+
; Make sure we don't use qc.ext instead of neg.
105+
define i32 @sexti1_i32_setcc_3(i32 %a, i32 %b) {
106+
; RV32I-LABEL: sexti1_i32_setcc_3:
107+
; RV32I: # %bb.0:
108+
; RV32I-NEXT: slt a0, a0, a1
109+
; RV32I-NEXT: neg a0, a0
110+
; RV32I-NEXT: ret
111+
;
112+
; RV32XQCIBM-LABEL: sexti1_i32_setcc_3:
113+
; RV32XQCIBM: # %bb.0:
114+
; RV32XQCIBM-NEXT: slt a0, a0, a1
115+
; RV32XQCIBM-NEXT: neg a0, a0
116+
; RV32XQCIBM-NEXT: ret
117+
;
118+
; RV32XQCIBMZBB-LABEL: sexti1_i32_setcc_3:
119+
; RV32XQCIBMZBB: # %bb.0:
120+
; RV32XQCIBMZBB-NEXT: slt a0, a0, a1
121+
; RV32XQCIBMZBB-NEXT: neg a0, a0
122+
; RV32XQCIBMZBB-NEXT: ret
123+
%icmp = icmp slt i32 %a, %b
124+
%sext = sext i1 %icmp to i32
125+
ret i32 %sext
126+
}
77127

78128
define i32 @sexti8_i32(i8 %a) nounwind {
79129
; RV32I-LABEL: sexti8_i32:

0 commit comments

Comments
 (0)