[llvm] [SCEV] Complete instr-types in CanConstantFold (PR #218874)

Ramkumar Ramachandra via llvm-commits llvm-commits at lists.llvm.org
Wed Aug 26 03:01:58 PDT 2026


https://github.com/artagnon created https://github.com/llvm/llvm-project/pull/218874

Match the types in the ConstantFolder. This allows us to compute more trip counts.

Assisted-by: AI, for test cases

>From 0a293fe033dfe4ec0b905f9d536721383cfd58c6 Mon Sep 17 00:00:00 2001
From: Ramkumar Ramachandra <artagnon at tenstorrent.com>
Date: Wed, 26 Aug 2026 10:53:19 +0100
Subject: [PATCH 1/2] [SCEV] Pre-commit exhaustive-trip-counts test

---
 .../ScalarEvolution/exhaustive-trip-counts.ll | 98 +++++++++++++++++++
 1 file changed, 98 insertions(+)

diff --git a/llvm/test/Analysis/ScalarEvolution/exhaustive-trip-counts.ll b/llvm/test/Analysis/ScalarEvolution/exhaustive-trip-counts.ll
index cc08fa5fc7d87..f78727e8c295a 100644
--- a/llvm/test/Analysis/ScalarEvolution/exhaustive-trip-counts.ll
+++ b/llvm/test/Analysis/ScalarEvolution/exhaustive-trip-counts.ll
@@ -177,6 +177,104 @@ exit:
   ret i64 %iv
 }
 
+define i64 @test_fneg() {
+; CHECK-LABEL: 'test_fneg'
+; CHECK-NEXT:  Determining loop execution counts for: @test_fneg
+; CHECK-NEXT:  Loop %loop: Unpredictable backedge-taken count.
+; CHECK-NEXT:  Loop %loop: Unpredictable constant max backedge-taken count.
+; CHECK-NEXT:  Loop %loop: Unpredictable symbolic max backedge-taken count.
+;
+entry:
+  br label %loop
+
+loop:
+  %iv = phi i64 [ 0, %entry ], [ %iv.next, %loop ]
+  %fv = phi double [ 1.000000e+00, %entry ], [ %fv.next, %loop ]
+  call void @use(double %fv)
+  %fv.neg = fneg double %fv
+  %fv.next = fsub double %fv, %fv.neg
+  %iv.next = add i64 %iv, 1
+  %fcmp = fcmp une double %fv, 128.0
+  br i1 %fcmp, label %loop, label %exit
+
+exit:
+  ret i64 %iv
+}
+
+define i64 @test_freeze() {
+; CHECK-LABEL: 'test_freeze'
+; CHECK-NEXT:  Determining loop execution counts for: @test_freeze
+; CHECK-NEXT:  Loop %loop: Unpredictable backedge-taken count.
+; CHECK-NEXT:  Loop %loop: Unpredictable constant max backedge-taken count.
+; CHECK-NEXT:  Loop %loop: Unpredictable symbolic max backedge-taken count.
+;
+entry:
+  br label %loop
+
+loop:
+  %iv = phi i64 [ 0, %entry ], [ %iv.next, %loop ]
+  call void @dummy()
+  %iv.next = add i64 %iv, 1
+  %iv.fr = freeze i64 %iv
+  %icmp = icmp ne i64 %iv.fr, 5
+  br i1 %icmp, label %loop, label %exit
+
+exit:
+  ret i64 %iv
+}
+
+define i64 @test_extract_insert_element() {
+; CHECK-LABEL: 'test_extract_insert_element'
+; CHECK-NEXT:  Determining loop execution counts for: @test_extract_insert_element
+; CHECK-NEXT:  Loop %loop: Unpredictable backedge-taken count.
+; CHECK-NEXT:  Loop %loop: Unpredictable constant max backedge-taken count.
+; CHECK-NEXT:  Loop %loop: Unpredictable symbolic max backedge-taken count.
+;
+entry:
+  br label %loop
+
+loop:
+  %iv = phi i64 [ 0, %entry ], [ %iv.next, %loop ]
+  %vec = phi <2 x i64> [ <i64 0, i64 3>, %entry ], [ %vec.next, %loop ]
+  call void @use.v2i64(<2 x i64> %vec)
+  %el = extractelement <2 x i64> %vec, i32 0
+  %el.next = add i64 %el, 1
+  %vec.next = insertelement <2 x i64> %vec, i64 %el.next, i32 0
+  %iv.next = add i64 %iv, 1
+  %icmp = icmp ne i64 %el, 4
+  br i1 %icmp, label %loop, label %exit
+
+exit:
+  ret i64 %iv
+}
+
+define i64 @test_extract_insert_value() {
+; CHECK-LABEL: 'test_extract_insert_value'
+; CHECK-NEXT:  Determining loop execution counts for: @test_extract_insert_value
+; CHECK-NEXT:  Loop %loop: Unpredictable backedge-taken count.
+; CHECK-NEXT:  Loop %loop: Unpredictable constant max backedge-taken count.
+; CHECK-NEXT:  Loop %loop: Unpredictable symbolic max backedge-taken count.
+;
+entry:
+  br label %loop
+
+loop:
+  %iv = phi i64 [ 0, %entry ], [ %iv.next, %loop ]
+  %agg = phi { i64, i32 } [ { i64 0, i32 3 }, %entry ], [ %agg.next, %loop ]
+  call void @use.agg({ i64, i32 } %agg)
+  %fld = extractvalue { i64, i32 } %agg, 0
+  %fld.next = add i64 %fld, 1
+  %agg.next = insertvalue { i64, i32 } %agg, i64 %fld.next, 0
+  %iv.next = add i64 %iv, 1
+  %icmp = icmp ne i64 %fld, 4
+  br i1 %icmp, label %loop, label %exit
+
+exit:
+  ret i64 %iv
+}
+
 declare void @dummy()
 declare void @use(double %i)
+declare void @use.v2i64(<2 x i64>)
+declare void @use.agg({ i64, i32 })
 declare double @llvm.sin.f64(double)

>From c199bebbdebd8349cfe3c5026ec49b8815436b06 Mon Sep 17 00:00:00 2001
From: Ramkumar Ramachandra <artagnon at tenstorrent.com>
Date: Wed, 26 Aug 2026 08:16:37 +0100
Subject: [PATCH 2/2] [SCEV] Complete instr-types in CanConstantFold

Match the types in the ConstantFolder. This allows us to compute more
trip counts.

Assisted-by: AI, for test cases
---
 llvm/lib/Analysis/ScalarEvolution.cpp         |  6 ++--
 .../ScalarEvolution/exhaustive-trip-counts.ll | 28 +++++++++++--------
 2 files changed, 19 insertions(+), 15 deletions(-)

diff --git a/llvm/lib/Analysis/ScalarEvolution.cpp b/llvm/lib/Analysis/ScalarEvolution.cpp
index f6ad701ce819e..7874bd7ca4b53 100644
--- a/llvm/lib/Analysis/ScalarEvolution.cpp
+++ b/llvm/lib/Analysis/ScalarEvolution.cpp
@@ -9741,9 +9741,9 @@ ScalarEvolution::ExitLimit ScalarEvolution::computeShiftCompareExitLimit(
 /// Return true if we can constant fold an instruction of the specified type,
 /// assuming that all operands were constants.
 static bool CanConstantFold(const Instruction *I) {
-  if (isa<BinaryOperator>(I) || isa<CmpInst>(I) ||
-      isa<SelectInst>(I) || isa<CastInst>(I) || isa<GetElementPtrInst>(I) ||
-      isa<LoadInst>(I) || isa<ExtractValueInst>(I))
+  if (isa<BinaryOperator, UnaryOperator, GEPOperator, FreezeInst, CmpInst,
+          SelectInst, CastInst, LoadInst, ExtractElementInst, InsertElementInst,
+          ExtractValueInst, InsertValueInst>(I))
     return true;
 
   if (const CallInst *CI = dyn_cast<CallInst>(I))
diff --git a/llvm/test/Analysis/ScalarEvolution/exhaustive-trip-counts.ll b/llvm/test/Analysis/ScalarEvolution/exhaustive-trip-counts.ll
index f78727e8c295a..4fc7fc1f530a3 100644
--- a/llvm/test/Analysis/ScalarEvolution/exhaustive-trip-counts.ll
+++ b/llvm/test/Analysis/ScalarEvolution/exhaustive-trip-counts.ll
@@ -180,9 +180,10 @@ exit:
 define i64 @test_fneg() {
 ; CHECK-LABEL: 'test_fneg'
 ; CHECK-NEXT:  Determining loop execution counts for: @test_fneg
-; CHECK-NEXT:  Loop %loop: Unpredictable backedge-taken count.
-; CHECK-NEXT:  Loop %loop: Unpredictable constant max backedge-taken count.
-; CHECK-NEXT:  Loop %loop: Unpredictable symbolic max backedge-taken count.
+; CHECK-NEXT:  Loop %loop: backedge-taken count is i32 7
+; CHECK-NEXT:  Loop %loop: constant max backedge-taken count is i32 7
+; CHECK-NEXT:  Loop %loop: symbolic max backedge-taken count is i32 7
+; CHECK-NEXT:  Loop %loop: Trip multiple is 8
 ;
 entry:
   br label %loop
@@ -204,9 +205,10 @@ exit:
 define i64 @test_freeze() {
 ; CHECK-LABEL: 'test_freeze'
 ; CHECK-NEXT:  Determining loop execution counts for: @test_freeze
-; CHECK-NEXT:  Loop %loop: Unpredictable backedge-taken count.
-; CHECK-NEXT:  Loop %loop: Unpredictable constant max backedge-taken count.
-; CHECK-NEXT:  Loop %loop: Unpredictable symbolic max backedge-taken count.
+; CHECK-NEXT:  Loop %loop: backedge-taken count is i32 5
+; CHECK-NEXT:  Loop %loop: constant max backedge-taken count is i32 5
+; CHECK-NEXT:  Loop %loop: symbolic max backedge-taken count is i32 5
+; CHECK-NEXT:  Loop %loop: Trip multiple is 6
 ;
 entry:
   br label %loop
@@ -226,9 +228,10 @@ exit:
 define i64 @test_extract_insert_element() {
 ; CHECK-LABEL: 'test_extract_insert_element'
 ; CHECK-NEXT:  Determining loop execution counts for: @test_extract_insert_element
-; CHECK-NEXT:  Loop %loop: Unpredictable backedge-taken count.
-; CHECK-NEXT:  Loop %loop: Unpredictable constant max backedge-taken count.
-; CHECK-NEXT:  Loop %loop: Unpredictable symbolic max backedge-taken count.
+; CHECK-NEXT:  Loop %loop: backedge-taken count is i32 4
+; CHECK-NEXT:  Loop %loop: constant max backedge-taken count is i32 4
+; CHECK-NEXT:  Loop %loop: symbolic max backedge-taken count is i32 4
+; CHECK-NEXT:  Loop %loop: Trip multiple is 5
 ;
 entry:
   br label %loop
@@ -251,9 +254,10 @@ exit:
 define i64 @test_extract_insert_value() {
 ; CHECK-LABEL: 'test_extract_insert_value'
 ; CHECK-NEXT:  Determining loop execution counts for: @test_extract_insert_value
-; CHECK-NEXT:  Loop %loop: Unpredictable backedge-taken count.
-; CHECK-NEXT:  Loop %loop: Unpredictable constant max backedge-taken count.
-; CHECK-NEXT:  Loop %loop: Unpredictable symbolic max backedge-taken count.
+; CHECK-NEXT:  Loop %loop: backedge-taken count is i32 4
+; CHECK-NEXT:  Loop %loop: constant max backedge-taken count is i32 4
+; CHECK-NEXT:  Loop %loop: symbolic max backedge-taken count is i32 4
+; CHECK-NEXT:  Loop %loop: Trip multiple is 5
 ;
 entry:
   br label %loop



More information about the llvm-commits mailing list