Skip to content

Commit

Permalink
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
[SelectionDAG] Prevent combination on inconsistent type in `combineCa…
Browse files Browse the repository at this point in the history
…rryDiamond` (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.
XChy authored and chencha3 committed Mar 22, 2024
1 parent b859b95 commit e0e6f93
Showing 2 changed files with 29 additions and 1 deletion.
7 changes: 6 additions & 1 deletion llvm/lib/CodeGen/SelectionDAG/DAGCombiner.cpp
Original file line number Diff line number Diff line change
@@ -3473,6 +3473,11 @@ static SDValue combineCarryDiamond(SelectionDAG &DAG, const TargetLowering &TLI,
return SDValue();
if (Opcode != ISD::UADDO && Opcode != ISD::USUBO)
return SDValue();
// Guarantee identical type of CarryOut
EVT CarryOutType = N->getValueType(0);
if (CarryOutType != Carry0.getValue(1).getValueType() ||
CarryOutType != Carry1.getValue(1).getValueType())
return SDValue();

// Canonicalize the add/sub of A and B (the top node in the above ASCII art)
// 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,
// TODO: match other operations that can merge flags (ADD, etc)
DAG.ReplaceAllUsesOfValueWith(Carry1.getValue(0), Merged.getValue(0));
if (N->getOpcode() == ISD::AND)
return DAG.getConstant(0, DL, MVT::i1);
return DAG.getConstant(0, DL, CarryOutType);
return Merged.getValue(1);
}

23 changes: 23 additions & 0 deletions llvm/test/CodeGen/X86/addcarry.ll
Original file line number Diff line number Diff line change
@@ -1490,3 +1490,26 @@ define { i64, i64 } @addcarry_commutative_2(i64 %x0, i64 %x1, i64 %y0, i64 %y1)
%r1 = insertvalue { i64, i64 } %r0, i64 %b1s, 1
ret { i64, i64 } %r1
}

define i1 @pr84831(i64 %arg) {
; CHECK-LABEL: pr84831:
; CHECK: # %bb.0:
; CHECK-NEXT: testq %rdi, %rdi
; CHECK-NEXT: setne %al
; CHECK-NEXT: xorl %ecx, %ecx
; CHECK-NEXT: addb $-1, %al
; CHECK-NEXT: adcq $1, %rcx
; CHECK-NEXT: setb %al
; CHECK-NEXT: retq
%a = icmp ult i64 0, %arg
%add1 = add i64 0, 1
%carryout1 = icmp ult i64 %add1, 0
%b = zext i1 %a to i64
%add2 = add i64 %add1, %b
%carryout2 = icmp ult i64 %add2, %add1
%zc1 = zext i1 %carryout1 to i63
%zc2 = zext i1 %carryout2 to i63
%or = or i63 %zc1, %zc2
%trunc = trunc i63 %or to i1
ret i1 %trunc
}

0 comments on commit e0e6f93

Please sign in to comment.