Skip to content

[IndVarSimplify] Handle the case where both operands are the same when widening IV #135207

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 2 commits into from
Apr 11, 2025

Conversation

dtcxzyw
Copy link
Member

@dtcxzyw dtcxzyw commented Apr 10, 2025

WidenIV::widenWithVariantUse assumes that exactly one of the binop operands is the IV to be widened. This miscompilation happens when it tries to sign-extend the "NonIV" operand while the IV is zero-extended.
Closes #135182.

BTW, I found that WidenIV::cloneArithmeticIVUser makes the same assumption as this method. But it looks safe.

@llvmbot
Copy link
Member

llvmbot commented Apr 10, 2025

@llvm/pr-subscribers-llvm-transforms

Author: Yingwei Zheng (dtcxzyw)

Changes

WidenIV::widenWithVariantUse assumes that exactly one of the binop operands is the IV to be widened. This miscompilation happens when it tries to sign-extend the "NonIV" operand while the IV is zero-extended.
Closes #135182.

BTW, I found that WidenIV::cloneArithmeticIVUser makes the same assumption as this method. But it looks safe.


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

2 Files Affected:

  • (modified) llvm/lib/Transforms/Utils/SimplifyIndVar.cpp (+3)
  • (added) llvm/test/Transforms/IndVarSimplify/pr135182.ll (+27)
diff --git a/llvm/lib/Transforms/Utils/SimplifyIndVar.cpp b/llvm/lib/Transforms/Utils/SimplifyIndVar.cpp
index 7b9c5c77cbe98..5a76bec017655 100644
--- a/llvm/lib/Transforms/Utils/SimplifyIndVar.cpp
+++ b/llvm/lib/Transforms/Utils/SimplifyIndVar.cpp
@@ -1743,6 +1743,9 @@ bool WidenIV::widenWithVariantUse(WidenIV::NarrowIVDefUse DU) {
     // TODO: Support case for NarrowDef = NarrowUse->getOperand(1).
     if (NarrowUse->getOperand(0) != NarrowDef)
       return false;
+    // We cannot use a different extend kind for the same operand.
+    if (NarrowUse->getOperand(1) == NarrowDef)
+      return false;
     if (!SE->isKnownNegative(RHS))
       return false;
     bool ProvedSubNUW = SE->isKnownPredicateAt(ICmpInst::ICMP_UGE, LHS,
diff --git a/llvm/test/Transforms/IndVarSimplify/pr135182.ll b/llvm/test/Transforms/IndVarSimplify/pr135182.ll
new file mode 100644
index 0000000000000..1db96872cffc4
--- /dev/null
+++ b/llvm/test/Transforms/IndVarSimplify/pr135182.ll
@@ -0,0 +1,27 @@
+; NOTE: Assertions have been autogenerated by utils/update_test_checks.py UTC_ARGS: --version 5
+; RUN: opt -S -passes=indvars < %s | FileCheck %s
+
+target datalayout = "e-m:e-p270:32:32-p271:32:32-p272:64:64-i64:64-i128:128-f80:128-n8:16:32:64-S128"
+
+define i32 @pr135182() {
+; CHECK-LABEL: define i32 @pr135182() {
+; CHECK-NEXT:  [[ENTRY:.*:]]
+; CHECK-NEXT:    br label %[[FOR_BODY:.*]]
+; CHECK:       [[FOR_BODY]]:
+; CHECK-NEXT:    br i1 false, label %[[FOR_BODY]], label %[[FOR_END:.*]]
+; CHECK:       [[FOR_END]]:
+; CHECK-NEXT:    ret i32 65512
+;
+entry:
+  br label %for.body
+
+for.body:
+  %indvar = phi i16 [ -12, %entry ], [ %indvar.next, %for.body ]
+  %add = add i16 %indvar, %indvar
+  %ext = zext i16 %add to i32
+  %indvar.next = add i16 %indvar, 1
+  br i1 false, label %for.body, label %for.end
+
+for.end:
+  ret i32 %ext
+}

Copy link
Contributor

@nikic nikic left a comment

Choose a reason for hiding this comment

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

LGTM

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

@dtcxzyw dtcxzyw merged commit d14acb7 into llvm:main Apr 11, 2025
13 checks passed
@dtcxzyw dtcxzyw deleted the fix-135182 branch April 11, 2025 01:03
@dtcxzyw dtcxzyw added this to the LLVM 20.X Release milestone Apr 11, 2025
@github-project-automation github-project-automation bot moved this to Needs Triage in LLVM Release Status Apr 11, 2025
@dtcxzyw
Copy link
Member Author

dtcxzyw commented Apr 11, 2025

/cherry-pick d14acb7

@llvmbot
Copy link
Member

llvmbot commented Apr 11, 2025

/pull-request #135291

@llvmbot llvmbot moved this from Needs Triage to Done in LLVM Release Status Apr 11, 2025
swift-ci pushed a commit to swiftlang/llvm-project that referenced this pull request Apr 11, 2025
…n widening IV (llvm#135207)

`WidenIV::widenWithVariantUse` assumes that exactly one of the binop
operands is the IV to be widened. This miscompilation happens when it
tries to sign-extend the "NonIV" operand while the IV is zero-extended.
Closes llvm#135182.

(cherry picked from commit d14acb7)
var-const pushed a commit to ldionne/llvm-project that referenced this pull request Apr 17, 2025
…n widening IV (llvm#135207)

`WidenIV::widenWithVariantUse` assumes that exactly one of the binop
operands is the IV to be widened. This miscompilation happens when it
tries to sign-extend the "NonIV" operand while the IV is zero-extended.
Closes llvm#135182.
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Projects
Development

Successfully merging this pull request may close these issues.

[IndVarSimplify] Miscompilation at -O3
4 participants