Skip to content

[SCEV] Fix sext handling for getConstantMultiple #117093

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
Nov 21, 2024
Merged

Conversation

dtcxzyw
Copy link
Member

@dtcxzyw dtcxzyw commented Nov 21, 2024

Counterexample: 219 is a multiple of 73. But sext i8 219 to i16 = 65499 is not.
Fixes #116483.

@dtcxzyw dtcxzyw requested a review from nikic as a code owner November 21, 2024 01:40
@llvmbot llvmbot added llvm:analysis Includes value tracking, cost tables and constant folding llvm:transforms labels Nov 21, 2024
@llvmbot
Copy link
Member

llvmbot commented Nov 21, 2024

@llvm/pr-subscribers-llvm-analysis

@llvm/pr-subscribers-llvm-transforms

Author: Yingwei Zheng (dtcxzyw)

Changes

Counterexample: 219 is a multiple of 73. But sext i8 219 to i16 = 65499 is not.
Fixes #116483.


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

3 Files Affected:

  • (modified) llvm/lib/Analysis/ScalarEvolution.cpp (+3-1)
  • (added) llvm/test/Analysis/ScalarEvolution/pr116483.ll (+26)
  • (added) llvm/test/Transforms/IndVarSimplify/pr116483.ll (+36)
diff --git a/llvm/lib/Analysis/ScalarEvolution.cpp b/llvm/lib/Analysis/ScalarEvolution.cpp
index 46b108606f6a62..0ff4e0f74fb675 100644
--- a/llvm/lib/Analysis/ScalarEvolution.cpp
+++ b/llvm/lib/Analysis/ScalarEvolution.cpp
@@ -6314,8 +6314,10 @@ APInt ScalarEvolution::getConstantMultipleImpl(const SCEV *S) {
     return getConstantMultiple(Z->getOperand()).zext(BitWidth);
   }
   case scSignExtend: {
+    // Only multiples that are a power of 2 will hold after sext.
     const SCEVSignExtendExpr *E = cast<SCEVSignExtendExpr>(S);
-    return getConstantMultiple(E->getOperand()).sext(BitWidth);
+    uint32_t TZ = getMinTrailingZeros(E->getOperand());
+    return GetShiftedByZeros(TZ);
   }
   case scMulExpr: {
     const SCEVMulExpr *M = cast<SCEVMulExpr>(S);
diff --git a/llvm/test/Analysis/ScalarEvolution/pr116483.ll b/llvm/test/Analysis/ScalarEvolution/pr116483.ll
new file mode 100644
index 00000000000000..cc2334e9c64f92
--- /dev/null
+++ b/llvm/test/Analysis/ScalarEvolution/pr116483.ll
@@ -0,0 +1,26 @@
+; NOTE: Assertions have been autogenerated by utils/update_analyze_test_checks.py UTC_ARGS: --version 5
+; RUN: opt -S -disable-output "-passes=print<scalar-evolution>" < %s 2>&1 | FileCheck %s
+
+define i16 @test() {
+; CHECK-LABEL: 'test'
+; CHECK-NEXT:  Classifying expressions for: @test
+; CHECK-NEXT:    %xor = xor i32 0, 3
+; CHECK-NEXT:    --> %xor U: [3,4) S: [3,4)
+; CHECK-NEXT:    %mul = mul i32 %xor, 329
+; CHECK-NEXT:    --> (329 * %xor)<nuw><nsw> U: [987,988) S: [987,988)
+; CHECK-NEXT:    %conv = trunc i32 %mul to i16
+; CHECK-NEXT:    --> (329 * (trunc i32 %xor to i16))<nuw><nsw> U: [987,988) S: [987,988)
+; CHECK-NEXT:    %sext = shl i16 %conv, 8
+; CHECK-NEXT:    --> (18688 * (trunc i32 %xor to i16))<nuw> U: [-9472,-9471) S: [-9472,-9471)
+; CHECK-NEXT:    %conv1 = ashr i16 %sext, 8
+; CHECK-NEXT:    --> (sext i8 (73 * (trunc i32 %xor to i8))<nuw> to i16) U: [-37,-36) S: [-37,-36)
+; CHECK-NEXT:  Determining loop execution counts for: @test
+;
+entry:
+  %xor = xor i32 0, 3
+  %mul = mul i32 %xor, 329
+  %conv = trunc i32 %mul to i16
+  %sext = shl i16 %conv, 8
+  %conv1 = ashr i16 %sext, 8
+  ret i16 %conv1
+}
diff --git a/llvm/test/Transforms/IndVarSimplify/pr116483.ll b/llvm/test/Transforms/IndVarSimplify/pr116483.ll
new file mode 100644
index 00000000000000..ae108a525223e0
--- /dev/null
+++ b/llvm/test/Transforms/IndVarSimplify/pr116483.ll
@@ -0,0 +1,36 @@
+; NOTE: Assertions have been autogenerated by utils/update_test_checks.py UTC_ARGS: --version 5
+; RUN: opt -S -passes=indvars < %s | FileCheck %s
+
+define i32 @test() {
+; CHECK-LABEL: define i32 @test() {
+; CHECK-NEXT:  [[ENTRY:.*:]]
+; CHECK-NEXT:    [[XOR:%.*]] = xor i32 0, 3
+; CHECK-NEXT:    [[MUL:%.*]] = mul i32 [[XOR]], 329
+; CHECK-NEXT:    [[CONV:%.*]] = trunc i32 [[MUL]] to i16
+; CHECK-NEXT:    [[SEXT:%.*]] = shl i16 [[CONV]], 8
+; CHECK-NEXT:    [[CONV1:%.*]] = ashr i16 [[SEXT]], 8
+; CHECK-NEXT:    br label %[[LOOP_BODY:.*]]
+; CHECK:       [[LOOP_BODY]]:
+; CHECK-NEXT:    br i1 true, label %[[EXIT:.*]], label %[[LOOP_BODY]]
+; CHECK:       [[EXIT]]:
+; CHECK-NEXT:    [[CONV3:%.*]] = zext i16 [[CONV1]] to i32
+; CHECK-NEXT:    ret i32 [[CONV3]]
+;
+entry:
+  %xor = xor i32 0, 3
+  %mul = mul i32 %xor, 329
+  %conv = trunc i32 %mul to i16
+  %sext = shl i16 %conv, 8
+  %conv1 = ashr i16 %sext, 8
+  %conv3 = zext i16 %conv1 to i32
+  br label %loop.body
+
+loop.body:
+  %indvar = phi i32 [ %indvar.inc, %loop.body ], [ 1, %entry ]
+  %indvar.inc = add nuw i32 %indvar, 1
+  %exitcond = icmp eq i32 %indvar, %conv3
+  br i1 %exitcond, label %exit, label %loop.body
+
+exit:
+  ret i32 %conv3
+}

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

@antoniofrighetto antoniofrighetto 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 for the fix!

@dtcxzyw dtcxzyw merged commit 458dfbd into llvm:main Nov 21, 2024
9 of 11 checks passed
@dtcxzyw dtcxzyw deleted the fix-pr116483 branch November 21, 2024 09:23
@dtcxzyw
Copy link
Member Author

dtcxzyw commented Nov 21, 2024

/cherry-pick 458dfbd

@llvmbot
Copy link
Member

llvmbot commented Nov 21, 2024

/cherry-pick 458dfbd

Error: Command failed due to missing milestone.

@dtcxzyw dtcxzyw added this to the LLVM 19.X Release milestone Nov 21, 2024
@dtcxzyw
Copy link
Member Author

dtcxzyw commented Nov 21, 2024

/cherry-pick 458dfbd

@llvmbot
Copy link
Member

llvmbot commented Nov 21, 2024

/pull-request #117136

tru pushed a commit to llvmbot/llvm-project that referenced this pull request Nov 25, 2024
Counterexample: 219 is a multiple of 73. But `sext i8 219 to i16 =
65499` is not.
Fixes llvm#116483.

(cherry picked from commit 458dfbd)
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
llvm:analysis Includes value tracking, cost tables and constant folding llvm:transforms
Projects
Development

Successfully merging this pull request may close these issues.

[clang] Miscompile at O3 with SIGKILL
4 participants