Skip to content

Commit 2573dfb

Browse files
committed
[SelectionDAG] Detect impossible conditions using known bits analysis
1 parent b9adc4a commit 2573dfb

File tree

3 files changed

+2161
-16
lines changed

3 files changed

+2161
-16
lines changed

llvm/lib/CodeGen/SelectionDAG/DAGCombiner.cpp

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

13514+
// Detect impossible conditions using known bits analysis.
13515+
if (N1.getOpcode() == ISD::Constant) {
13516+
ConstantSDNode *N1C = cast<ConstantSDNode>(N1);
13517+
APInt C1 = N1C->getAPIntValue();
13518+
KnownBits KnownRHS = KnownBits::makeConstant(C1);
13519+
13520+
// Bail out early if RHS is unknown (shouldn't happen for constants)
13521+
if (KnownRHS.isUnknown())
13522+
return SDValue();
13523+
13524+
std::optional<bool> KnownVal;
13525+
13526+
// Handle special cases first (like GlobalISel does)
13527+
if (KnownRHS.isZero()) {
13528+
// x >=u 0 -> always true
13529+
// x <u 0 -> always false
13530+
if (Cond == ISD::SETUGE)
13531+
KnownVal = true;
13532+
else if (Cond == ISD::SETULT)
13533+
KnownVal = false;
13534+
}
13535+
13536+
// If not handled by special cases, use ICmpInst::compare
13537+
if (!KnownVal) {
13538+
KnownBits KnownLHS = DAG.computeKnownBits(N0);
13539+
13540+
// Convert ISD::CondCode to CmpInst::Predicate
13541+
CmpInst::Predicate Pred;
13542+
switch (Cond) {
13543+
case ISD::SETEQ: Pred = CmpInst::ICMP_EQ; break;
13544+
case ISD::SETNE: Pred = CmpInst::ICMP_NE; break;
13545+
case ISD::SETULT: Pred = CmpInst::ICMP_ULT; break;
13546+
case ISD::SETULE: Pred = CmpInst::ICMP_ULE; break;
13547+
case ISD::SETUGT: Pred = CmpInst::ICMP_UGT; break;
13548+
case ISD::SETUGE: Pred = CmpInst::ICMP_UGE; break;
13549+
case ISD::SETLT: Pred = CmpInst::ICMP_SLT; break;
13550+
case ISD::SETLE: Pred = CmpInst::ICMP_SLE; break;
13551+
case ISD::SETGT: Pred = CmpInst::ICMP_SGT; break;
13552+
case ISD::SETGE: Pred = CmpInst::ICMP_SGE; break;
13553+
default:
13554+
return SDValue(); // Unsupported predicate
13555+
}
13556+
13557+
// Use the same logic as GlobalISel: ICmpInst::compare
13558+
KnownVal = ICmpInst::compare(KnownLHS, KnownRHS, Pred);
13559+
}
13560+
13561+
// If the comparison result is known, replace with constant
13562+
if (KnownVal)
13563+
return DAG.getConstant(*KnownVal ? 1 : 0, DL, VT);
13564+
}
13565+
1351413566
if (SDValue Combined = SimplifySetCC(VT, N0, N1, Cond, DL, !PreferSetCC)) {
1351513567
// If we prefer to have a setcc, and we don't, we'll try our best to
1351613568
// 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)