Skip to content

Commit 647fbc7

Browse files
XChytstellar
authored andcommitted
[SelectionDAG] Prevent combination on inconsistent type in combineCarryDiamond (#84888)
Fixes #84831 When matching carry pattern with `getAsCarry`, it may produce different type of carryout. This patch checks such case and does early exit. I'm new to DAG, any suggestion is appreciated. (cherry picked from commit cb4453d)
1 parent eaae766 commit 647fbc7

File tree

2 files changed

+29
-1
lines changed

2 files changed

+29
-1
lines changed

llvm/lib/CodeGen/SelectionDAG/DAGCombiner.cpp

Lines changed: 6 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -3575,6 +3575,11 @@ static SDValue combineCarryDiamond(SelectionDAG &DAG, const TargetLowering &TLI,
35753575
return SDValue();
35763576
if (Opcode != ISD::UADDO && Opcode != ISD::USUBO)
35773577
return SDValue();
3578+
// Guarantee identical type of CarryOut
3579+
EVT CarryOutType = N->getValueType(0);
3580+
if (CarryOutType != Carry0.getValue(1).getValueType() ||
3581+
CarryOutType != Carry1.getValue(1).getValueType())
3582+
return SDValue();
35783583

35793584
// Canonicalize the add/sub of A and B (the top node in the above ASCII art)
35803585
// as Carry0 and the add/sub of the carry in as Carry1 (the middle node).
@@ -3622,7 +3627,7 @@ static SDValue combineCarryDiamond(SelectionDAG &DAG, const TargetLowering &TLI,
36223627
// TODO: match other operations that can merge flags (ADD, etc)
36233628
DAG.ReplaceAllUsesOfValueWith(Carry1.getValue(0), Merged.getValue(0));
36243629
if (N->getOpcode() == ISD::AND)
3625-
return DAG.getConstant(0, DL, MVT::i1);
3630+
return DAG.getConstant(0, DL, CarryOutType);
36263631
return Merged.getValue(1);
36273632
}
36283633

llvm/test/CodeGen/X86/addcarry.ll

Lines changed: 23 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1490,3 +1490,26 @@ define { i64, i64 } @addcarry_commutative_2(i64 %x0, i64 %x1, i64 %y0, i64 %y1)
14901490
%r1 = insertvalue { i64, i64 } %r0, i64 %b1s, 1
14911491
ret { i64, i64 } %r1
14921492
}
1493+
1494+
define i1 @pr84831(i64 %arg) {
1495+
; CHECK-LABEL: pr84831:
1496+
; CHECK: # %bb.0:
1497+
; CHECK-NEXT: testq %rdi, %rdi
1498+
; CHECK-NEXT: setne %al
1499+
; CHECK-NEXT: xorl %ecx, %ecx
1500+
; CHECK-NEXT: addb $-1, %al
1501+
; CHECK-NEXT: adcq $1, %rcx
1502+
; CHECK-NEXT: setb %al
1503+
; CHECK-NEXT: retq
1504+
%a = icmp ult i64 0, %arg
1505+
%add1 = add i64 0, 1
1506+
%carryout1 = icmp ult i64 %add1, 0
1507+
%b = zext i1 %a to i64
1508+
%add2 = add i64 %add1, %b
1509+
%carryout2 = icmp ult i64 %add2, %add1
1510+
%zc1 = zext i1 %carryout1 to i63
1511+
%zc2 = zext i1 %carryout2 to i63
1512+
%or = or i63 %zc1, %zc2
1513+
%trunc = trunc i63 %or to i1
1514+
ret i1 %trunc
1515+
}

0 commit comments

Comments
 (0)