Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

[SelectionDAG] Prevent combination on inconsistent type in combineCarryDiamond #84888

Merged
merged 1 commit into from
Mar 22, 2024

Conversation

XChy
Copy link
Member

@XChy XChy commented Mar 12, 2024

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.

@llvmbot llvmbot added backend:X86 llvm:SelectionDAG SelectionDAGISel as well labels Mar 12, 2024
@llvmbot
Copy link
Member

llvmbot commented Mar 12, 2024

@llvm/pr-subscribers-backend-x86

@llvm/pr-subscribers-llvm-selectiondag

Author: XChy (XChy)

Changes

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.


Full diff: https://github.com/llvm/llvm-project/pull/84888.diff

2 Files Affected:

  • (modified) llvm/lib/CodeGen/SelectionDAG/DAGCombiner.cpp (+3)
  • (modified) llvm/test/CodeGen/X86/addcarry.ll (+23)
diff --git a/llvm/lib/CodeGen/SelectionDAG/DAGCombiner.cpp b/llvm/lib/CodeGen/SelectionDAG/DAGCombiner.cpp
index cdcb7114640471..7e8b1d82b22504 100644
--- a/llvm/lib/CodeGen/SelectionDAG/DAGCombiner.cpp
+++ b/llvm/lib/CodeGen/SelectionDAG/DAGCombiner.cpp
@@ -3442,6 +3442,9 @@ static SDValue combineCarryDiamond(SelectionDAG &DAG, const TargetLowering &TLI,
     return SDValue();
   if (Opcode != ISD::UADDO && Opcode != ISD::USUBO)
     return SDValue();
+  // Guarantee identical type of CarryOut
+  if (N->getValueType(0) != Carry0.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).
diff --git a/llvm/test/CodeGen/X86/addcarry.ll b/llvm/test/CodeGen/X86/addcarry.ll
index 3fc4ed99fad0fa..f0efd6fe5de370 100644
--- a/llvm/test/CodeGen/X86/addcarry.ll
+++ b/llvm/test/CodeGen/X86/addcarry.ll
@@ -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 %0) {
+; 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
+  %2 = icmp ult i64 0, %0
+  %3 = add i64 0, 1
+  %4 = icmp ult i64 %3, 0
+  %5 = zext i1 %2 to i64
+  %6 = add i64 %3, %5
+  %7 = icmp ult i64 %6, %3
+  %8 = zext i1 %4 to i63
+  %9 = zext i1 %7 to i63
+  %new0 = or i63 %8, %9
+  %last = trunc i63 %new0 to i1
+  ret i1 %last
+}

@RKSimon RKSimon requested a review from deadalnix March 12, 2024 09:28
llvm/test/CodeGen/X86/addcarry.ll Outdated Show resolved Hide resolved
; CHECK-NEXT: setb %al
; CHECK-NEXT: retq
%2 = icmp ult i64 0, %0
%3 = add i64 0, 1
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Are these trivially foldable cases necessary to reproduce? If not they should be folded away

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Yes, I tried to reduce it manually, but every fold stops it crashing llc. I'll add the names related to semantics, so that it can be understood.

@@ -3442,6 +3442,9 @@ static SDValue combineCarryDiamond(SelectionDAG &DAG, const TargetLowering &TLI,
return SDValue();
if (Opcode != ISD::UADDO && Opcode != ISD::USUBO)
return SDValue();
// Guarantee identical type of CarryOut
if (N->getValueType(0) != Carry0.getValue(1).getValueType())
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Most of this code implicitly assumes we're returning == MVT::i1, so maybe:

if (N->getValueType(0) != MVT::i1 || 
    Carry0.getValue(1).getValueType() != MVT::i1 ||
    Carry1.getValue(1).getValueType() != MVT::i1)
  return SDValue();

Copy link
Member Author

@XChy XChy Mar 12, 2024

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

It can be i8 in X86 too. If we only handle i1, we cannot combine addcarry_fake_carry in test/X86/CodeGen/addcarry.ll.
I missed the check for Carry1, and it seems that we should replace MVT::i1 for and operator.

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I don't see how this is implicitly assuming i1? I can see implicitly assuming the uaddo output and input bools are the same

@XChy XChy force-pushed the dagcombine-fix-carry-diamond branch from 168f43e to 050e5ca Compare March 12, 2024 11:09
@XChy
Copy link
Member Author

XChy commented Mar 14, 2024

@RKSimon, any comment on this patch?

@XChy
Copy link
Member Author

XChy commented Mar 21, 2024

@RKSimon gently ping.

@arsenm arsenm merged commit cb4453d into llvm:main Mar 22, 2024
4 checks passed
chencha3 pushed a commit to chencha3/llvm-project that referenced this pull request Mar 23, 2024
…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.
@AreaZR
Copy link
Contributor

AreaZR commented Mar 26, 2024

/cherry-pick cb4453d

@llvmbot
Copy link
Member

llvmbot commented Mar 26, 2024

/cherry-pick cb4453d

Error: Command failed due to missing milestone.

AreaZR pushed a commit to AreaZR/llvm-project that referenced this pull request Mar 26, 2024
…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.

(cherry picked from commit cb4453d)
tstellar pushed a commit to AreaZR/llvm-project that referenced this pull request Apr 16, 2024
…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.

(cherry picked from commit cb4453d)
@pointhex pointhex mentioned this pull request May 7, 2024
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
backend:X86 llvm:SelectionDAG SelectionDAGISel as well
Projects
None yet
5 participants