[llvm] 1a656be - [SCEV] Complete instr-types in CanConstantFold (#218874)
via llvm-commits
llvm-commits at lists.llvm.org
Thu Sep 3 06:48:30 PDT 2026
Author: Ramkumar Ramachandra
Date: 2026-09-03T13:48:24Z
New Revision: 1a656be2fb6902d532c71297b6da0d063ffa72b2
URL: https://github.com/llvm/llvm-project/commit/1a656be2fb6902d532c71297b6da0d063ffa72b2
DIFF: https://github.com/llvm/llvm-project/commit/1a656be2fb6902d532c71297b6da0d063ffa72b2.diff
LOG: [SCEV] Complete instr-types in CanConstantFold (#218874)
Match the types in the ConstantFolder. This allows us to compute more
trip counts.
Assisted-by: AI, for test cases
Added:
Modified:
llvm/lib/Analysis/ScalarEvolution.cpp
llvm/test/Analysis/ScalarEvolution/exhaustive-trip-counts.ll
Removed:
################################################################################
diff --git a/llvm/lib/Analysis/ScalarEvolution.cpp b/llvm/lib/Analysis/ScalarEvolution.cpp
index efbc1abee06d0..e81cd47c201cc 100644
--- a/llvm/lib/Analysis/ScalarEvolution.cpp
+++ b/llvm/lib/Analysis/ScalarEvolution.cpp
@@ -9688,9 +9688,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 6b5213379d2f9..fae671d698e6f 100644
--- a/llvm/test/Analysis/ScalarEvolution/exhaustive-trip-counts.ll
+++ b/llvm/test/Analysis/ScalarEvolution/exhaustive-trip-counts.ll
@@ -267,6 +267,108 @@ exit:
ret i64 %sum
}
+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)
More information about the llvm-commits
mailing list