Skip to content

Commit e0e6f93

Browse files
XChychencha3
authored andcommitted
[SelectionDAG] Prevent combination on inconsistent type in combineCarryDiamond (llvm#84888)
Fixes llvm#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.
1 parent b859b95 commit e0e6f93

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
@@ -3473,6 +3473,11 @@ static SDValue combineCarryDiamond(SelectionDAG &DAG, const TargetLowering &TLI,
34733473
return SDValue();
34743474
if (Opcode != ISD::UADDO && Opcode != ISD::USUBO)
34753475
return SDValue();
3476+
// Guarantee identical type of CarryOut
3477+
EVT CarryOutType = N->getValueType(0);
3478+
if (CarryOutType != Carry0.getValue(1).getValueType() ||
3479+
CarryOutType != Carry1.getValue(1).getValueType())
3480+
return SDValue();
34763481

34773482
// Canonicalize the add/sub of A and B (the top node in the above ASCII art)
34783483
// as Carry0 and the add/sub of the carry in as Carry1 (the middle node).
@@ -3520,7 +3525,7 @@ static SDValue combineCarryDiamond(SelectionDAG &DAG, const TargetLowering &TLI,
35203525
// TODO: match other operations that can merge flags (ADD, etc)
35213526
DAG.ReplaceAllUsesOfValueWith(Carry1.getValue(0), Merged.getValue(0));
35223527
if (N->getOpcode() == ISD::AND)
3523-
return DAG.getConstant(0, DL, MVT::i1);
3528+
return DAG.getConstant(0, DL, CarryOutType);
35243529
return Merged.getValue(1);
35253530
}
35263531

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)