[llvm] [SCEV] Complete instr-types in CanConstantFold (PR #218874)
via llvm-commits
llvm-commits at lists.llvm.org
Wed Aug 26 03:02:45 PDT 2026
llvmorg-github-actions[bot] wrote:
<!--LLVM PR SUMMARY COMMENT-->
@llvm/pr-subscribers-llvm-analysis
Author: Ramkumar Ramachandra (artagnon)
<details>
<summary>Changes</summary>
Match the types in the ConstantFolder. This allows us to compute more trip counts.
Assisted-by: AI, for test cases
---
Full diff: https://github.com/llvm/llvm-project/pull/218874.diff
2 Files Affected:
- (modified) llvm/lib/Analysis/ScalarEvolution.cpp (+3-3)
- (modified) llvm/test/Analysis/ScalarEvolution/exhaustive-trip-counts.ll (+102)
``````````diff
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 cc08fa5fc7d87..4fc7fc1f530a3 100644
--- a/llvm/test/Analysis/ScalarEvolution/exhaustive-trip-counts.ll
+++ b/llvm/test/Analysis/ScalarEvolution/exhaustive-trip-counts.ll
@@ -177,6 +177,108 @@ 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: 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
+
+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: 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
+
+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: 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
+
+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: 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
+
+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)
``````````
</details>
https://github.com/llvm/llvm-project/pull/218874
More information about the llvm-commits
mailing list