Skip to content

Commit 4613a92

Browse files
committed
[SelectionDAG] Detect impossible conditions using known bits analysis
1 parent 67b5195 commit 4613a92

File tree

3 files changed

+2160
-16
lines changed

3 files changed

+2160
-16
lines changed

llvm/lib/CodeGen/SelectionDAG/DAGCombiner.cpp

Lines changed: 52 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -13529,6 +13529,58 @@ SDValue DAGCombiner::visitSETCC(SDNode *N) {
1352913529
SDValue N0 = N->getOperand(0), N1 = N->getOperand(1);
1353013530
SDLoc DL(N);
1353113531

13532+
// Detect impossible conditions using known bits analysis.
13533+
if (N1.getOpcode() == ISD::Constant) {
13534+
ConstantSDNode *N1C = cast<ConstantSDNode>(N1);
13535+
APInt C1 = N1C->getAPIntValue();
13536+
KnownBits KnownRHS = KnownBits::makeConstant(C1);
13537+
13538+
// Bail out early if RHS is unknown (shouldn't happen for constants)
13539+
if (KnownRHS.isUnknown())
13540+
return SDValue();
13541+
13542+
std::optional<bool> KnownVal;
13543+
13544+
// Handle special cases first (like GlobalISel does)
13545+
if (KnownRHS.isZero()) {
13546+
// x >=u 0 -> always true
13547+
// x <u 0 -> always false
13548+
if (Cond == ISD::SETUGE)
13549+
KnownVal = true;
13550+
else if (Cond == ISD::SETULT)
13551+
KnownVal = false;
13552+
}
13553+
13554+
// If not handled by special cases, use ICmpInst::compare
13555+
if (!KnownVal) {
13556+
KnownBits KnownLHS = DAG.computeKnownBits(N0);
13557+
13558+
// Convert ISD::CondCode to CmpInst::Predicate
13559+
CmpInst::Predicate Pred;
13560+
switch (Cond) {
13561+
case ISD::SETEQ: Pred = CmpInst::ICMP_EQ; break;
13562+
case ISD::SETNE: Pred = CmpInst::ICMP_NE; break;
13563+
case ISD::SETULT: Pred = CmpInst::ICMP_ULT; break;
13564+
case ISD::SETULE: Pred = CmpInst::ICMP_ULE; break;
13565+
case ISD::SETUGT: Pred = CmpInst::ICMP_UGT; break;
13566+
case ISD::SETUGE: Pred = CmpInst::ICMP_UGE; break;
13567+
case ISD::SETLT: Pred = CmpInst::ICMP_SLT; break;
13568+
case ISD::SETLE: Pred = CmpInst::ICMP_SLE; break;
13569+
case ISD::SETGT: Pred = CmpInst::ICMP_SGT; break;
13570+
case ISD::SETGE: Pred = CmpInst::ICMP_SGE; break;
13571+
default:
13572+
return SDValue(); // Unsupported predicate
13573+
}
13574+
13575+
// Use the same logic as GlobalISel: ICmpInst::compare
13576+
KnownVal = ICmpInst::compare(KnownLHS, KnownRHS, Pred);
13577+
}
13578+
13579+
// If the comparison result is known, replace with constant
13580+
if (KnownVal)
13581+
return DAG.getConstant(*KnownVal ? 1 : 0, DL, VT);
13582+
}
13583+
1353213584
if (SDValue Combined = SimplifySetCC(VT, N0, N1, Cond, DL, !PreferSetCC)) {
1353313585
// If we prefer to have a setcc, and we don't, we'll try our best to
1353413586
// recreate one using rebuildSetCC.

llvm/test/CodeGen/AArch64/arm64-ccmp.ll

Lines changed: 4 additions & 16 deletions
Original file line numberDiff line numberDiff line change
@@ -597,22 +597,10 @@ define i32 @select_andor32(i32 %v1, i32 %v2, i32 %v3) {
597597
}
598598

599599
define i64 @select_noccmp1(i64 %v1, i64 %v2, i64 %v3, i64 %r) {
600-
; SDISEL-LABEL: select_noccmp1:
601-
; SDISEL: ; %bb.0:
602-
; SDISEL-NEXT: cmp x0, #0
603-
; SDISEL-NEXT: ccmp x0, #13, #4, lt
604-
; SDISEL-NEXT: cset w8, gt
605-
; SDISEL-NEXT: cmp x2, #2
606-
; SDISEL-NEXT: ccmp x2, #4, #4, lt
607-
; SDISEL-NEXT: csinc w8, w8, wzr, le
608-
; SDISEL-NEXT: cmp w8, #0
609-
; SDISEL-NEXT: csel x0, xzr, x3, ne
610-
; SDISEL-NEXT: ret
611-
;
612-
; GISEL-LABEL: select_noccmp1:
613-
; GISEL: ; %bb.0:
614-
; GISEL-NEXT: mov x0, x3
615-
; GISEL-NEXT: ret
600+
; CHECK-LABEL: select_noccmp1:
601+
; CHECK: ; %bb.0:
602+
; CHECK-NEXT: mov x0, x3
603+
; CHECK-NEXT: ret
616604
%c0 = icmp slt i64 %v1, 0
617605
%c1 = icmp sgt i64 %v1, 13
618606
%c2 = icmp slt i64 %v3, 2

0 commit comments

Comments
 (0)