Skip to content

[ConstraintElim] Don't decompose values wider than 64 bits #68803

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

Merged
merged 1 commit into from
Oct 16, 2023

Conversation

nikic
Copy link
Contributor

@nikic nikic commented Oct 11, 2023

Our coefficients are 64-bits, so adding/multiplying them can wrap in 64-bits even if there would be no wrapping the full bit width.

The alternative would be to check for overflows during all adds/muls in decomposition. I assume that we don't particularly care about handling wide integers here, so I've opted to bail out.

Fixes #68751.

Our coefficients are 64-bits, so adding/multiplying them can
wrap in 64-bits even if there would be no wrapping the full
bit width.

The alternative would be to check for overflows during all
adds/muls in decomposition. I assume that we don't particularly
care about handling wide integers here, so I've opted to bail out.

Fixes llvm#68751.
@llvmbot
Copy link
Member

llvmbot commented Oct 11, 2023

@llvm/pr-subscribers-llvm-transforms

Author: Nikita Popov (nikic)

Changes

Our coefficients are 64-bits, so adding/multiplying them can wrap in 64-bits even if there would be no wrapping the full bit width.

The alternative would be to check for overflows during all adds/muls in decomposition. I assume that we don't particularly care about handling wide integers here, so I've opted to bail out.

Fixes #68751.


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

3 Files Affected:

  • (modified) llvm/lib/Transforms/Scalar/ConstraintElimination.cpp (+13-3)
  • (modified) llvm/test/Transforms/ConstraintElimination/large-constant-ints.ll (+5-3)
  • (modified) llvm/test/Transforms/ConstraintElimination/shl.ll (+2-1)
diff --git a/llvm/lib/Transforms/Scalar/ConstraintElimination.cpp b/llvm/lib/Transforms/Scalar/ConstraintElimination.cpp
index 1eb7e481d43cd2b..37f720ec40f4e54 100644
--- a/llvm/lib/Transforms/Scalar/ConstraintElimination.cpp
+++ b/llvm/lib/Transforms/Scalar/ConstraintElimination.cpp
@@ -451,6 +451,19 @@ static Decomposition decompose(Value *V,
     return ResA;
   };
 
+  Type *Ty = V->getType()->getScalarType();
+  if (Ty->isPointerTy() && !IsSigned) {
+    if (auto *GEP = dyn_cast<GEPOperator>(V))
+      return decomposeGEP(*GEP, Preconditions, IsSigned, DL);
+    return V;
+  }
+
+  // Don't handle integers > 64 bit. Our coefficients are 64-bit large, so
+  // coefficient add/mul may wrap, while the operation in the full bit width
+  // would not.
+  if (!Ty->isIntegerTy() || Ty->getIntegerBitWidth() > 64)
+    return V;
+
   // Decompose \p V used with a signed predicate.
   if (IsSigned) {
     if (auto *CI = dyn_cast<ConstantInt>(V)) {
@@ -478,9 +491,6 @@ static Decomposition decompose(Value *V,
     return int64_t(CI->getZExtValue());
   }
 
-  if (auto *GEP = dyn_cast<GEPOperator>(V))
-    return decomposeGEP(*GEP, Preconditions, IsSigned, DL);
-
   Value *Op0;
   bool IsKnownNonNegative = false;
   if (match(V, m_ZExt(m_Value(Op0)))) {
diff --git a/llvm/test/Transforms/ConstraintElimination/large-constant-ints.ll b/llvm/test/Transforms/ConstraintElimination/large-constant-ints.ll
index 6b616aa700330a9..9568b155af13ae9 100644
--- a/llvm/test/Transforms/ConstraintElimination/large-constant-ints.ll
+++ b/llvm/test/Transforms/ConstraintElimination/large-constant-ints.ll
@@ -96,6 +96,7 @@ else:
   ret i1 false
 }
 
+; TODO: This could be folded.
 define i1 @sub_decomp_i80(i80 %a) {
 ; CHECK-LABEL: @sub_decomp_i80(
 ; CHECK-NEXT:  entry:
@@ -104,7 +105,8 @@ define i1 @sub_decomp_i80(i80 %a) {
 ; CHECK-NEXT:    br i1 [[C]], label [[THEN:%.*]], label [[ELSE:%.*]]
 ; CHECK:       then:
 ; CHECK-NEXT:    [[SUB_1:%.*]] = sub nuw i80 [[A]], 1973801615886922022913
-; CHECK-NEXT:    ret i1 true
+; CHECK-NEXT:    [[C_1:%.*]] = icmp ult i80 [[SUB_1]], 1346612317380797267967
+; CHECK-NEXT:    ret i1 [[C_1]]
 ; CHECK:       else:
 ; CHECK-NEXT:    ret i1 false
 ;
@@ -418,12 +420,12 @@ entry:
   ret i1 %res
 }
 
-; FIXME: This is a miscompile.
 define i1 @pr68751(i128 %arg) {
 ; CHECK-LABEL: @pr68751(
 ; CHECK-NEXT:    [[SHL1:%.*]] = shl nuw nsw i128 [[ARG:%.*]], 32
 ; CHECK-NEXT:    [[SHL2:%.*]] = shl nuw nsw i128 [[SHL1]], 32
-; CHECK-NEXT:    ret i1 true
+; CHECK-NEXT:    [[CMP:%.*]] = icmp eq i128 [[SHL2]], 0
+; CHECK-NEXT:    ret i1 [[CMP]]
 ;
   %shl1 = shl nuw nsw i128 %arg, 32
   %shl2 = shl nuw nsw i128 %shl1, 32
diff --git a/llvm/test/Transforms/ConstraintElimination/shl.ll b/llvm/test/Transforms/ConstraintElimination/shl.ll
index 982e0e745833351..9f98a9d3a57caef 100644
--- a/llvm/test/Transforms/ConstraintElimination/shl.ll
+++ b/llvm/test/Transforms/ConstraintElimination/shl.ll
@@ -1277,7 +1277,8 @@ define i1 @shl_55() {
 ; CHECK-LABEL: @shl_55(
 ; CHECK-NEXT:  entry:
 ; CHECK-NEXT:    [[SHL_UB:%.*]] = shl nuw nsw i256 1, 55
-; CHECK-NEXT:    ret i1 true
+; CHECK-NEXT:    [[SHL_CMP:%.*]] = icmp uge i256 [[SHL_UB]], 1
+; CHECK-NEXT:    ret i1 [[SHL_CMP]]
 ;
 entry:
   %shl.ub = shl nuw nsw i256 1, 55

@tru
Copy link
Collaborator

tru commented Oct 16, 2023

@nikic you put this in the 17.x milestone, should we try to get that into 17.0.3 tomorrow? Maybe optimistic since it's not even in main yet.

Copy link
Contributor

@fhahn fhahn left a comment

Choose a reason for hiding this comment

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

LGTM, thanks!

@nikic nikic merged commit 1d43096 into llvm:main Oct 16, 2023
nikic added a commit to nikic/llvm-project that referenced this pull request Oct 16, 2023
Our coefficients are 64-bits, so adding/multiplying them can wrap in
64-bits even if there would be no wrapping the full bit width.

The alternative would be to check for overflows during all adds/muls in
decomposition. I assume that we don't particularly care about handling
wide integers here, so I've opted to bail out.

Fixes llvm#68751.

(cherry picked from commit 1d43096)
tru pushed a commit that referenced this pull request Oct 24, 2023
Our coefficients are 64-bits, so adding/multiplying them can wrap in
64-bits even if there would be no wrapping the full bit width.

The alternative would be to check for overflows during all adds/muls in
decomposition. I assume that we don't particularly care about handling
wide integers here, so I've opted to bail out.

Fixes #68751.

(cherry picked from commit 1d43096)
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Projects
None yet
Development

Successfully merging this pull request may close these issues.

ConstraintEliminationPass incorrectly replaces a i256 ne with a constant false.
4 participants