[llvm] [SCCP] Enable PredicateInfo for non-interprocedural SCCP (PR #153003)

via llvm-commits llvm-commits at lists.llvm.org
Mon Aug 11 06:07:03 PDT 2025


llvmbot wrote:


<!--LLVM PR SUMMARY COMMENT-->

@llvm/pr-subscribers-llvm-transforms

Author: Nikita Popov (nikic)

<details>
<summary>Changes</summary>

SCCP can use PredicateInfo to constrain ranges based on assume and branch conditions. Currently, this is only enabled during IPSCCP.

This enables it for SCCP as well, which runs after functions have already been simplified, while IPSCCP runs pre-inline. To a large degree, CVP already handles range-based optimizations, but SCCP is more reliable for the cases it can handled. In particular, SCCP works reliably inside loops, which is something that CVP struggles with due to LVI cycles.

I have made various optimizations to make PredicateInfo more efficient, but unfortunately this still has significant compile-time cost (around 0.1-0.2%). See: https://llvm-compile-time-tracker.com/compare.php?from=35bad229c1bc1f27fe58f9d37f8592fc67a7112c&to=216b04028ac670e9083c7f026311005276da9d32&stat=instructions:u

---

Patch is 26.86 KiB, truncated to 20.00 KiB below, full version: https://github.com/llvm/llvm-project/pull/153003.diff


6 Files Affected:

- (modified) llvm/lib/Transforms/Scalar/SCCP.cpp (+12-4) 
- (modified) llvm/test/Transforms/PhaseOrdering/deletion-of-loops-that-became-side-effect-free.ll (+8-29) 
- (modified) llvm/test/Transforms/SCCP/pr27712.ll (+1-1) 
- (modified) llvm/test/Transforms/SCCP/sccptest.ll (+1-1) 
- (modified) llvm/test/Transforms/SCCP/undef-resolve.ll (+3-4) 
- (modified) llvm/test/Transforms/SCCP/widening.ll (+108-217) 


``````````diff
diff --git a/llvm/lib/Transforms/Scalar/SCCP.cpp b/llvm/lib/Transforms/Scalar/SCCP.cpp
index 8be2f78187a0c..feee794ffeae1 100644
--- a/llvm/lib/Transforms/Scalar/SCCP.cpp
+++ b/llvm/lib/Transforms/Scalar/SCCP.cpp
@@ -20,6 +20,7 @@
 #include "llvm/ADT/SmallPtrSet.h"
 #include "llvm/ADT/SmallVector.h"
 #include "llvm/ADT/Statistic.h"
+#include "llvm/Analysis/AssumptionCache.h"
 #include "llvm/Analysis/DomTreeUpdater.h"
 #include "llvm/Analysis/GlobalsModRef.h"
 #include "llvm/Analysis/TargetLibraryInfo.h"
@@ -31,6 +32,7 @@
 #include "llvm/IR/InstrTypes.h"
 #include "llvm/IR/Instruction.h"
 #include "llvm/IR/Instructions.h"
+#include "llvm/IR/IntrinsicInst.h"
 #include "llvm/IR/PassManager.h"
 #include "llvm/IR/Type.h"
 #include "llvm/IR/Value.h"
@@ -53,12 +55,15 @@ STATISTIC(NumInstReplaced,
 // runSCCP() - Run the Sparse Conditional Constant Propagation algorithm,
 // and return true if the function was modified.
 static bool runSCCP(Function &F, const DataLayout &DL,
-                    const TargetLibraryInfo *TLI, DomTreeUpdater &DTU) {
+                    const TargetLibraryInfo *TLI, DominatorTree &DT,
+                    AssumptionCache &AC) {
   LLVM_DEBUG(dbgs() << "SCCP on function '" << F.getName() << "'\n");
   SCCPSolver Solver(
       DL, [TLI](Function &F) -> const TargetLibraryInfo & { return *TLI; },
       F.getContext());
 
+  Solver.addPredicateInfo(F, DT, AC);
+
   // While we don't do any actual inter-procedural analysis, still track
   // return values so we can infer attributes.
   if (canTrackReturnsInterprocedurally(&F))
@@ -101,6 +106,7 @@ static bool runSCCP(Function &F, const DataLayout &DL,
   }
 
   // Remove unreachable blocks and non-feasible edges.
+  DomTreeUpdater DTU(DT, DomTreeUpdater::UpdateStrategy::Lazy);
   for (BasicBlock *DeadBB : BlocksToErase)
     NumInstRemoved += changeToUnreachable(&*DeadBB->getFirstNonPHIIt(),
                                           /*PreserveLCSSA=*/false, &DTU);
@@ -113,6 +119,8 @@ static bool runSCCP(Function &F, const DataLayout &DL,
     if (!DeadBB->hasAddressTaken())
       DTU.deleteBB(DeadBB);
 
+  Solver.removeSSACopies(F);
+
   Solver.inferReturnAttributes();
 
   return MadeChanges;
@@ -121,9 +129,9 @@ static bool runSCCP(Function &F, const DataLayout &DL,
 PreservedAnalyses SCCPPass::run(Function &F, FunctionAnalysisManager &AM) {
   const DataLayout &DL = F.getDataLayout();
   auto &TLI = AM.getResult<TargetLibraryAnalysis>(F);
-  auto *DT = AM.getCachedResult<DominatorTreeAnalysis>(F);
-  DomTreeUpdater DTU(DT, DomTreeUpdater::UpdateStrategy::Lazy);
-  if (!runSCCP(F, DL, &TLI, DTU))
+  auto &DT = AM.getResult<DominatorTreeAnalysis>(F);
+  auto &AC = AM.getResult<AssumptionAnalysis>(F);
+  if (!runSCCP(F, DL, &TLI, DT, AC))
     return PreservedAnalyses::all();
 
   auto PA = PreservedAnalyses();
diff --git a/llvm/test/Transforms/PhaseOrdering/deletion-of-loops-that-became-side-effect-free.ll b/llvm/test/Transforms/PhaseOrdering/deletion-of-loops-that-became-side-effect-free.ll
index 641f216302146..df78f3d8fd54a 100644
--- a/llvm/test/Transforms/PhaseOrdering/deletion-of-loops-that-became-side-effect-free.ll
+++ b/llvm/test/Transforms/PhaseOrdering/deletion-of-loops-that-became-side-effect-free.ll
@@ -96,35 +96,10 @@ while.end:
 }
 
 define dso_local zeroext i1 @is_not_empty_variant3(ptr %p) {
-; O3-LABEL: @is_not_empty_variant3(
-; O3-NEXT:  entry:
-; O3-NEXT:    [[TOBOOL_NOT4_I:%.*]] = icmp ne ptr [[P:%.*]], null
-; O3-NEXT:    ret i1 [[TOBOOL_NOT4_I]]
-;
-; O2-LABEL: @is_not_empty_variant3(
-; O2-NEXT:  entry:
-; O2-NEXT:    [[TOBOOL_NOT4_I:%.*]] = icmp ne ptr [[P:%.*]], null
-; O2-NEXT:    ret i1 [[TOBOOL_NOT4_I]]
-;
-; O1-LABEL: @is_not_empty_variant3(
-; O1-NEXT:  entry:
-; O1-NEXT:    [[TOBOOL_NOT4_I:%.*]] = icmp eq ptr [[P:%.*]], null
-; O1-NEXT:    br i1 [[TOBOOL_NOT4_I]], label [[COUNT_NODES_VARIANT3_EXIT:%.*]], label [[WHILE_BODY_I:%.*]]
-; O1:       while.body.i:
-; O1-NEXT:    [[SIZE_06_I:%.*]] = phi i64 [ [[INC_I:%.*]], [[WHILE_BODY_I]] ], [ 0, [[ENTRY:%.*]] ]
-; O1-NEXT:    [[P_ADDR_05_I:%.*]] = phi ptr [ [[TMP0:%.*]], [[WHILE_BODY_I]] ], [ [[P]], [[ENTRY]] ]
-; O1-NEXT:    [[CMP_I:%.*]] = icmp ne i64 [[SIZE_06_I]], -1
-; O1-NEXT:    call void @llvm.assume(i1 [[CMP_I]])
-; O1-NEXT:    [[TMP0]] = load ptr, ptr [[P_ADDR_05_I]], align 8
-; O1-NEXT:    [[INC_I]] = add i64 [[SIZE_06_I]], 1
-; O1-NEXT:    [[TOBOOL_NOT_I:%.*]] = icmp eq ptr [[TMP0]], null
-; O1-NEXT:    br i1 [[TOBOOL_NOT_I]], label [[COUNT_NODES_VARIANT3_EXIT_LOOPEXIT:%.*]], label [[WHILE_BODY_I]], !llvm.loop [[LOOP0:![0-9]+]]
-; O1:       count_nodes_variant3.exit.loopexit:
-; O1-NEXT:    [[PHI_CMP:%.*]] = icmp ne i64 [[INC_I]], 0
-; O1-NEXT:    br label [[COUNT_NODES_VARIANT3_EXIT]]
-; O1:       count_nodes_variant3.exit:
-; O1-NEXT:    [[SIZE_0_LCSSA_I:%.*]] = phi i1 [ false, [[ENTRY]] ], [ [[PHI_CMP]], [[COUNT_NODES_VARIANT3_EXIT_LOOPEXIT]] ]
-; O1-NEXT:    ret i1 [[SIZE_0_LCSSA_I]]
+; ALL-LABEL: @is_not_empty_variant3(
+; ALL-NEXT:  entry:
+; ALL-NEXT:    [[TOBOOL_NOT4_I:%.*]] = icmp ne ptr [[P:%.*]], null
+; ALL-NEXT:    ret i1 [[TOBOOL_NOT4_I]]
 ;
 entry:
   %p.addr = alloca ptr, align 8
@@ -182,3 +157,7 @@ declare void @llvm.assume(i1 noundef)
 !1 = !{!"llvm.loop.mustprogress"}
 !2 = distinct !{!2, !1}
 !3 = distinct !{!3, !1}
+;; NOTE: These prefixes are unused and the list is autogenerated. Do not add tests below this line:
+; O1: {{.*}}
+; O2: {{.*}}
+; O3: {{.*}}
diff --git a/llvm/test/Transforms/SCCP/pr27712.ll b/llvm/test/Transforms/SCCP/pr27712.ll
index 5529beba45341..04779dc308701 100644
--- a/llvm/test/Transforms/SCCP/pr27712.ll
+++ b/llvm/test/Transforms/SCCP/pr27712.ll
@@ -2,7 +2,7 @@
 ; RUN: opt -passes=sccp -S < %s | FileCheck %s
 
 define i32 @main() {
-; CHECK-LABEL: define i32 @main() {
+; CHECK-LABEL: define range(i32 33554432, 0) i32 @main() {
 ; CHECK-NEXT:  [[ENTRY:.*]]:
 ; CHECK-NEXT:    br label %[[LBL_1154:.*]]
 ; CHECK:       [[LBL_1154]]:
diff --git a/llvm/test/Transforms/SCCP/sccptest.ll b/llvm/test/Transforms/SCCP/sccptest.ll
index 299645435bf86..7a37b7236b84d 100644
--- a/llvm/test/Transforms/SCCP/sccptest.ll
+++ b/llvm/test/Transforms/SCCP/sccptest.ll
@@ -43,7 +43,7 @@ define i32 @test2(i32 %i0, i32 %j0) {
 ; CHECK:       BB4:
 ; CHECK-NEXT:    ret i32 1
 ; CHECK:       BB5:
-; CHECK-NEXT:    [[K3]] = add i32 [[K2]], 1
+; CHECK-NEXT:    [[K3]] = add nsw i32 [[K2]], 1
 ; CHECK-NEXT:    br label [[BB7]]
 ; CHECK:       BB7:
 ; CHECK-NEXT:    br label [[BB2]]
diff --git a/llvm/test/Transforms/SCCP/undef-resolve.ll b/llvm/test/Transforms/SCCP/undef-resolve.ll
index 8bb2baa82dce3..7984a52713787 100644
--- a/llvm/test/Transforms/SCCP/undef-resolve.ll
+++ b/llvm/test/Transforms/SCCP/undef-resolve.ll
@@ -33,7 +33,7 @@ define i32 @test2() nounwind readnone ssp {
 ; CHECK:       control.outer.outer.split.us:
 ; CHECK-NEXT:    br label [[CONTROL_OUTER_US:%.*]]
 ; CHECK:       control.outer.us:
-; CHECK-NEXT:    [[A_0_PH_US:%.*]] = phi i32 [ [[SWITCHCOND_0_US:%.*]], [[BB3_US:%.*]] ], [ 4, [[CONTROL_OUTER_OUTER_SPLIT_US]] ]
+; CHECK-NEXT:    [[A_0_PH_US:%.*]] = phi i32 [ 3, [[BB3_US:%.*]] ], [ 4, [[CONTROL_OUTER_OUTER_SPLIT_US]] ]
 ; CHECK-NEXT:    [[SWITCHCOND_0_PH_US:%.*]] = phi i32 [ [[A_0_PH_US]], [[BB3_US]] ], [ [[SWITCHCOND_0_PH_PH]], [[CONTROL_OUTER_OUTER_SPLIT_US]] ]
 ; CHECK-NEXT:    br label [[CONTROL_US:%.*]]
 ; CHECK:       bb3.us:
@@ -41,7 +41,7 @@ define i32 @test2() nounwind readnone ssp {
 ; CHECK:       bb0.us:
 ; CHECK-NEXT:    br label [[CONTROL_US]]
 ; CHECK:       control.us:
-; CHECK-NEXT:    [[SWITCHCOND_0_US]] = phi i32 [ [[A_0_PH_US]], [[BB0_US:%.*]] ], [ [[SWITCHCOND_0_PH_US]], [[CONTROL_OUTER_US]] ]
+; CHECK-NEXT:    [[SWITCHCOND_0_US:%.*]] = phi i32 [ [[A_0_PH_US]], [[BB0_US:%.*]] ], [ [[SWITCHCOND_0_PH_US]], [[CONTROL_OUTER_US]] ]
 ; CHECK-NEXT:    switch i32 [[SWITCHCOND_0_US]], label [[CONTROL_OUTER_LOOPEXIT_US_LCSSA_US:%.*]] [
 ; CHECK-NEXT:      i32 0, label [[BB0_US]]
 ; CHECK-NEXT:      i32 1, label [[BB1_US_LCSSA_US:%.*]]
@@ -55,7 +55,7 @@ define i32 @test2() nounwind readnone ssp {
 ; CHECK:       bb4.us-lcssa.us:
 ; CHECK-NEXT:    br label [[BB4:%.*]]
 ; CHECK:       control.outer:
-; CHECK-NEXT:    [[A_0_PH:%.*]] = phi i32 [ [[NEXTID17:%.*]], [[BB3:%.*]] ], [ 4, [[CONTROL_OUTER_OUTER_CONTROL_OUTER_OUTER_SPLIT_CRIT_EDGE]] ]
+; CHECK-NEXT:    [[A_0_PH:%.*]] = phi i32 [ 1, [[BB3:%.*]] ], [ 4, [[CONTROL_OUTER_OUTER_CONTROL_OUTER_OUTER_SPLIT_CRIT_EDGE]] ]
 ; CHECK-NEXT:    [[SWITCHCOND_0_PH:%.*]] = phi i32 [ 0, [[BB3]] ], [ [[SWITCHCOND_0_PH_PH]], [[CONTROL_OUTER_OUTER_CONTROL_OUTER_OUTER_SPLIT_CRIT_EDGE]] ]
 ; CHECK-NEXT:    br label [[CONTROL:%.*]]
 ; CHECK:       control:
@@ -74,7 +74,6 @@ define i32 @test2() nounwind readnone ssp {
 ; CHECK-NEXT:    [[I_0_PH_PH_BE]] = phi i32 [ 1, [[BB4]] ], [ 0, [[CONTROL_OUTER_LOOPEXIT]] ]
 ; CHECK-NEXT:    br label [[CONTROL_OUTER_OUTER]]
 ; CHECK:       bb3:
-; CHECK-NEXT:    [[NEXTID17]] = add i32 [[SWITCHCOND_0]], -2
 ; CHECK-NEXT:    br label [[CONTROL_OUTER]]
 ; CHECK:       bb0:
 ; CHECK-NEXT:    br label [[CONTROL]]
diff --git a/llvm/test/Transforms/SCCP/widening.ll b/llvm/test/Transforms/SCCP/widening.ll
index 2bc583c94b7a7..408038cab5e12 100644
--- a/llvm/test/Transforms/SCCP/widening.ll
+++ b/llvm/test/Transforms/SCCP/widening.ll
@@ -238,34 +238,19 @@ exit.1:
 ; For the loop_with_header_* tests, %iv and %a change on each iteration, but we
 ; can use the range imposed by the condition %c.1 when widening.
 define void @loop_with_header_1(i32 %x) {
-; SCCP-LABEL: @loop_with_header_1(
-; SCCP-NEXT:  entry:
-; SCCP-NEXT:    br label [[LOOP_HEADER:%.*]]
-; SCCP:       loop.header:
-; SCCP-NEXT:    [[IV:%.*]] = phi i32 [ 0, [[ENTRY:%.*]] ], [ [[IV_NEXT:%.*]], [[LOOP_BODY:%.*]] ]
-; SCCP-NEXT:    [[C_1:%.*]] = icmp slt i32 [[IV]], 2
-; SCCP-NEXT:    br i1 [[C_1]], label [[LOOP_BODY]], label [[EXIT:%.*]]
-; SCCP:       loop.body:
-; SCCP-NEXT:    [[T_1:%.*]] = icmp slt i32 [[IV]], 2
-; SCCP-NEXT:    call void @use(i1 [[T_1]])
-; SCCP-NEXT:    [[IV_NEXT]] = add nsw i32 [[IV]], 1
-; SCCP-NEXT:    br label [[LOOP_HEADER]]
-; SCCP:       exit:
-; SCCP-NEXT:    ret void
-;
-; IPSCCP-LABEL: @loop_with_header_1(
-; IPSCCP-NEXT:  entry:
-; IPSCCP-NEXT:    br label [[LOOP_HEADER:%.*]]
-; IPSCCP:       loop.header:
-; IPSCCP-NEXT:    [[IV:%.*]] = phi i32 [ 0, [[ENTRY:%.*]] ], [ [[IV_NEXT:%.*]], [[LOOP_BODY:%.*]] ]
-; IPSCCP-NEXT:    [[C_1:%.*]] = icmp slt i32 [[IV]], 2
-; IPSCCP-NEXT:    br i1 [[C_1]], label [[LOOP_BODY]], label [[EXIT:%.*]]
-; IPSCCP:       loop.body:
-; IPSCCP-NEXT:    call void @use(i1 true)
-; IPSCCP-NEXT:    [[IV_NEXT]] = add nuw nsw i32 [[IV]], 1
-; IPSCCP-NEXT:    br label [[LOOP_HEADER]]
-; IPSCCP:       exit:
-; IPSCCP-NEXT:    ret void
+; CHECK-LABEL: @loop_with_header_1(
+; CHECK-NEXT:  entry:
+; CHECK-NEXT:    br label [[LOOP_HEADER:%.*]]
+; CHECK:       loop.header:
+; CHECK-NEXT:    [[IV:%.*]] = phi i32 [ 0, [[ENTRY:%.*]] ], [ [[IV_NEXT:%.*]], [[LOOP_BODY:%.*]] ]
+; CHECK-NEXT:    [[C_1:%.*]] = icmp slt i32 [[IV]], 2
+; CHECK-NEXT:    br i1 [[C_1]], label [[LOOP_BODY]], label [[EXIT:%.*]]
+; CHECK:       loop.body:
+; CHECK-NEXT:    call void @use(i1 true)
+; CHECK-NEXT:    [[IV_NEXT]] = add nuw nsw i32 [[IV]], 1
+; CHECK-NEXT:    br label [[LOOP_HEADER]]
+; CHECK:       exit:
+; CHECK-NEXT:    ret void
 ;
 entry:
   br label %loop.header
@@ -286,34 +271,19 @@ exit:
 }
 
 define void @loop_with_header_2(i32 %x) {
-; SCCP-LABEL: @loop_with_header_2(
-; SCCP-NEXT:  entry:
-; SCCP-NEXT:    br label [[LOOP_HEADER:%.*]]
-; SCCP:       loop.header:
-; SCCP-NEXT:    [[IV:%.*]] = phi i32 [ 0, [[ENTRY:%.*]] ], [ [[IV_NEXT:%.*]], [[LOOP_BODY:%.*]] ]
-; SCCP-NEXT:    [[C_1:%.*]] = icmp slt i32 [[IV]], 200
-; SCCP-NEXT:    br i1 [[C_1]], label [[LOOP_BODY]], label [[EXIT:%.*]]
-; SCCP:       loop.body:
-; SCCP-NEXT:    [[T_1:%.*]] = icmp slt i32 [[IV]], 200
-; SCCP-NEXT:    call void @use(i1 [[T_1]])
-; SCCP-NEXT:    [[IV_NEXT]] = add nsw i32 [[IV]], 1
-; SCCP-NEXT:    br label [[LOOP_HEADER]]
-; SCCP:       exit:
-; SCCP-NEXT:    ret void
-;
-; IPSCCP-LABEL: @loop_with_header_2(
-; IPSCCP-NEXT:  entry:
-; IPSCCP-NEXT:    br label [[LOOP_HEADER:%.*]]
-; IPSCCP:       loop.header:
-; IPSCCP-NEXT:    [[IV:%.*]] = phi i32 [ 0, [[ENTRY:%.*]] ], [ [[IV_NEXT:%.*]], [[LOOP_BODY:%.*]] ]
-; IPSCCP-NEXT:    [[C_1:%.*]] = icmp slt i32 [[IV]], 200
-; IPSCCP-NEXT:    br i1 [[C_1]], label [[LOOP_BODY]], label [[EXIT:%.*]]
-; IPSCCP:       loop.body:
-; IPSCCP-NEXT:    call void @use(i1 true)
-; IPSCCP-NEXT:    [[IV_NEXT]] = add nsw i32 [[IV]], 1
-; IPSCCP-NEXT:    br label [[LOOP_HEADER]]
-; IPSCCP:       exit:
-; IPSCCP-NEXT:    ret void
+; CHECK-LABEL: @loop_with_header_2(
+; CHECK-NEXT:  entry:
+; CHECK-NEXT:    br label [[LOOP_HEADER:%.*]]
+; CHECK:       loop.header:
+; CHECK-NEXT:    [[IV:%.*]] = phi i32 [ 0, [[ENTRY:%.*]] ], [ [[IV_NEXT:%.*]], [[LOOP_BODY:%.*]] ]
+; CHECK-NEXT:    [[C_1:%.*]] = icmp slt i32 [[IV]], 200
+; CHECK-NEXT:    br i1 [[C_1]], label [[LOOP_BODY]], label [[EXIT:%.*]]
+; CHECK:       loop.body:
+; CHECK-NEXT:    call void @use(i1 true)
+; CHECK-NEXT:    [[IV_NEXT]] = add nsw i32 [[IV]], 1
+; CHECK-NEXT:    br label [[LOOP_HEADER]]
+; CHECK:       exit:
+; CHECK-NEXT:    ret void
 ;
 entry:
   br label %loop.header
@@ -448,167 +418,85 @@ bb:
 }
 
 define ptr @wobble(ptr %arg, i32 %arg1) align 2 {
-; SCCP-LABEL: @wobble(
-; SCCP-NEXT:  bb:
-; SCCP-NEXT:    [[TMP:%.*]] = lshr i32 [[ARG1:%.*]], 16
-; SCCP-NEXT:    [[TMP2:%.*]] = xor i32 [[TMP]], [[ARG1]]
-; SCCP-NEXT:    [[TMP3:%.*]] = and i32 [[TMP2]], 65535
-; SCCP-NEXT:    [[TMP4:%.*]] = mul i32 [[ARG1]], 8
-; SCCP-NEXT:    [[TMP5:%.*]] = getelementptr inbounds nuw [[STRUCT_BLAM_2:%.*]], ptr [[ARG:%.*]], i32 0, i32 1
-; SCCP-NEXT:    [[TMP6:%.*]] = load i32, ptr [[TMP5]], align 8
-; SCCP-NEXT:    [[TMP7:%.*]] = and i32 [[TMP4]], [[TMP6]]
-; SCCP-NEXT:    br label [[BB8:%.*]]
-; SCCP:       bb8:
-; SCCP-NEXT:    [[TMP9:%.*]] = phi ptr [ undef, [[BB:%.*]] ], [ [[TMP17:%.*]], [[BB29:%.*]] ]
-; SCCP-NEXT:    [[TMP10:%.*]] = phi ptr [ undef, [[BB]] ], [ [[TMP17]], [[BB29]] ]
-; SCCP-NEXT:    [[TMP11:%.*]] = phi i32 [ 0, [[BB]] ], [ [[TMP30:%.*]], [[BB29]] ]
-; SCCP-NEXT:    [[C_1:%.*]] = icmp slt i32 [[TMP11]], 8
-; SCCP-NEXT:    br i1 [[C_1]], label [[BB13:%.*]], label [[BB31:%.*]]
-; SCCP:       bb13:
-; SCCP-NEXT:    [[TMP15:%.*]] = add i32 [[TMP7]], [[TMP11]]
-; SCCP-NEXT:    [[TMP16:%.*]] = mul i32 [[TMP15]], 4
-; SCCP-NEXT:    [[TMP17]] = call dereferenceable(1) ptr @spam(ptr [[ARG]], i32 [[TMP16]])
-; SCCP-NEXT:    [[TMP19:%.*]] = getelementptr inbounds nuw i8, ptr [[TMP17]], i64 2
-; SCCP-NEXT:    [[TMP20:%.*]] = load i8, ptr [[TMP19]], align 1
-; SCCP-NEXT:    [[TMP21:%.*]] = zext i8 [[TMP20]] to i32
-; SCCP-NEXT:    [[TMP22:%.*]] = icmp eq i32 [[TMP21]], 0
-; SCCP-NEXT:    br i1 [[TMP22]], label [[BB23:%.*]], label [[BB25:%.*]]
-; SCCP:       bb23:
-; SCCP-NEXT:    [[TMP24:%.*]] = trunc nuw i32 [[TMP3]] to i16
-; SCCP-NEXT:    store i16 [[TMP24]], ptr [[TMP17]], align 2
-; SCCP-NEXT:    br label [[BB31]]
-; SCCP:       bb25:
-; SCCP-NEXT:    [[TMP26:%.*]] = load i16, ptr [[TMP17]], align 2
-; SCCP-NEXT:    [[TMP27:%.*]] = zext i16 [[TMP26]] to i32
-; SCCP-NEXT:    [[TMP28:%.*]] = icmp eq i32 [[TMP27]], [[TMP3]]
-; SCCP-NEXT:    br i1 [[TMP28]], label [[BB31]], label [[BB29]]
-; SCCP:       bb29:
-; SCCP-NEXT:    [[TMP30]] = add nsw i32 [[TMP11]], 1
-; SCCP-NEXT:    br label [[BB8]]
-; SCCP:       bb31:
-; SCCP-NEXT:    [[TMP32:%.*]] = phi ptr [ [[TMP17]], [[BB23]] ], [ [[TMP17]], [[BB25]] ], [ [[TMP9]], [[BB8]] ]
-; SCCP-NEXT:    [[TMP33:%.*]] = phi ptr [ [[TMP17]], [[BB23]] ], [ [[TMP17]], [[BB25]] ], [ [[TMP10]], [[BB8]] ]
-; SCCP-NEXT:    [[TMP34:%.*]] = icmp eq i32 [[TMP11]], 0
-; SCCP-NEXT:    br i1 [[TMP34]], label [[BB35:%.*]], label [[BB37:%.*]]
-; SCCP:       bb35:
-; SCCP-NEXT:    [[TMP36:%.*]] = getelementptr inbounds nuw i8, ptr [[TMP32]], i64 1
-; SCCP-NEXT:    br label [[BB66:%.*]]
-; SCCP:       bb37:
-; SCCP-NEXT:    [[C_2:%.*]] = icmp eq i32 [[TMP11]], 8
-; SCCP-NEXT:    br i1 [[C_2]], label [[BB39:%.*]], label [[BB58:%.*]]
-; SCCP:       bb39:
-; SCCP-NEXT:    [[TMP40:%.*]] = add nsw i32 [[TMP11]], -1
-; SCCP-NEXT:    [[TMP41:%.*]] = trunc nuw i32 [[TMP3]] to i16
-; SCCP-NEXT:    store i16 [[TMP41]], ptr @global.11, align 1
-; SCCP-NEXT:    [[TMP43:%.*]] = add i32 [[TMP7]], [[TMP40]]
-; SCCP-NEXT:    [[TMP44:%.*]] = mul i32 [[TMP43]], 4
-; SCCP-NEXT:    [[TMP45:%.*]] = add i32 [[TMP44]], 2
-; SCCP-NEXT:    [[TMP46:%.*]] = call dereferenceable(1) ptr @spam(ptr [[ARG]], i32 [[TMP45]])
-; SCCP-NEXT:    [[TMP47:%.*]] = load i8, ptr [[TMP46]], align 1
-; SCCP-NEXT:    [[TMP48:%.*]] = zext i8 [[TMP47]] to i32
-; SCCP-NEXT:    [[TMP49:%.*]] = sub i32 [[TMP43]], 1
-; SCCP-NEXT:    [[TMP50:%.*]] = mul i32 [[TMP49]], 4
-; SCCP-NEXT:    [[TMP51:%.*]] = add i32 [[TMP50]], 2
-; SCCP-NEXT:    [[TMP52:%.*]] = call dereferenceable(1) ptr @spam(ptr [[ARG]], i32 [[TMP51]])
-; SCCP-NEXT:    [[TMP53:%.*]] = load i8, ptr [[TMP52]], align 1
-; SCCP-NEXT:    [[TMP54:%.*]] = zext i8 [[TMP53]] to i32
-; SCCP-NEXT:    [[TMP55:%.*]] = icmp sgt i32 [[TMP48]], [[TMP54]]
-; SCCP-NEXT:    br i1 [[TMP55]], label [[BB56:%.*]], label [[BB60:%.*]]
-; SCCP:       bb56:
-; SCCP-NEXT:    [[TMP57:%.*]] = add nsw i32 [[TMP40]], -1
-; SCCP-NEXT:    br label [[BB60]]
-; SCCP:       bb58:
-; SCCP-NEXT:    call void @llvm.memcpy.p0.p0.i64(ptr align 1 @global.11, ptr align 2 [[TMP33]], i64 4, i1 false)
-; SCCP-NEXT:    br label [[BB60]]
-; SCCP:       bb60:
-; SCCP-NEXT:    [[TMP61:%.*]] = phi i32 [ [[TMP57]], [[BB56]] ], [ [[TMP40]], [[BB39]] ], [ [[TMP11]], [[BB58]] ]
-; SCCP-NEXT:    [[TMP63:%.*]] = add i32 [[TMP7]], 1
-; SCCP-NEXT:    [[TMP64:%.*]] = mul i32 [[TMP63]], 4
-; SCCP-NEXT:    [[TMP65:%.*]] = call dereferenceable(1) ptr @spam(ptr [[ARG]], i32 [[TMP64]])
-; SCCP-NEXT:    br label [[BB66]]
-; SCCP:       bb66:
-; SCCP-NEXT:    [[TMP67:%.*]] = phi ptr [ [[TMP36]], [[BB35]] ], [ null, [[BB60]] ]
-; SCCP-NEXT:    ret ptr [[TMP67]]
-;
-; IPSCCP-LABEL: @wobble(
-; IPSCCP-NEXT:  bb:
-; IPSCCP-NEXT:    [[TMP:%.*]] = lshr i32 [[ARG1:%.*]], 16
-; IPSCCP-NEXT:    [[TMP2:%.*]] = xor i32 [[TMP]], [[ARG1]]
-; IPSCCP-NEXT:    [[TMP3:%.*]] = and i32 [[TMP2]], 65535
-; IPSCCP-NEXT:    [[TMP4:%.*]] = mul i32 [[ARG1]], 8
-; IPSCCP-NEXT:    [[TMP5:%.*]] = getelementptr inbounds nuw [[STRUCT_BLAM_2:%.*]], ptr [[ARG:%.*]], i32 0, i32 1
-; IPSCCP-NEXT:    [[TMP6:%.*]] = load i32, ptr [[TMP5]], align 8
-; IPSCCP-NEXT:    [[TMP7:%.*]] = and i32 [[TMP4]], [[TMP6]]
-; IPSCCP-NEXT:    br label [[BB8:%.*]]
-; IPSCCP:       bb8:
-; IPSCCP-NEXT:    [[TMP9:%.*]] = phi ptr [ undef, [[BB:%.*]] ], [ [[TMP17:%.*]], [[BB29:%.*]] ]
-; IPSCCP-NEXT:    [[TMP10:%.*]] = phi ptr [ undef, [[BB]] ], [ [[TMP17]], [[BB29]] ]
-; IPSCCP-NEXT:    [[TMP11:%.*]] = phi i32 [ 0, [[BB]] ], [ [[TMP30:%.*]], [[BB29]] ]
-; IPSCCP-NEXT:    [[C_1:%.*]] = icmp slt i32 [[TMP11]], 8
-; IPSCCP-NEXT:    br i1 [[C_1]], label [[BB13:%.*]], label [[BB31:%.*]]
-; IPSCCP:       bb13:
-; IPSCCP-NEXT:    [[TMP15:%.*]] = add i32 [[TMP7]], [[TMP11]]
-; IPSCCP-NEXT:    [[TMP16:%.*]] = mul i32 [[TMP15]], 4
-; IPSCCP-NEXT:    [[TMP17]] = call dereferenceable(1) ptr @spam(ptr [[ARG]], i32 [[TMP16]])
-; IPSCCP-NEXT:    [[TMP19:%.*]] = getelementptr inbounds nuw i8, ptr [[TMP17]], i64 2
-; IPSCCP-NEXT:    [[TMP20:%.*]] = load i8, ptr [[TMP19]], align 1
-; IPSCCP-NEXT:    [[TMP21:%.*]] = zext i8 [[TMP20]] to i32
-; IPSCCP-NEXT:    [[TMP22:%.*]] = icmp eq i32 [[TMP21]], 0
-; IPSCCP-NEXT:    br i1 [[TMP22]], label [[BB23:%.*]], label [[BB25:%.*]]
-; IPSCCP:       bb23:
-; IPSCCP-NEXT:    [[TMP24:%.*]] = trunc nuw i32 [[TMP3]] to i16
-; IPSCCP-NEXT:    store i16 [[TMP24]], ptr [[TMP17]], align 2
-; IPSCCP-NEXT:    br label [[BB31]]
-; IPSCCP:       bb25:
-; IPSCCP-NEXT:    [[TMP26:%.*]] = load i16, ptr [[TMP17]], align 2
-; IPSCCP-NEXT:    [[TMP27:%.*]] = zext i16 [[TMP26]] to i32
-; IPSCCP-NEXT:    [[TMP28:%.*]] = icmp eq i32 [[TMP27]], [[TMP3]]
-; IPSCCP-NEXT:    br i1 [[TMP28]], label [[BB31]], label [[BB29]]
-; IPSCCP:       bb29:
-; IPSCCP-NEXT:    [[TMP30]] = add nsw i32 [[TMP11]], 1
-; IPSCCP-NEXT:    br label [[BB8]]
-; IPSCCP:       bb31:
-; IPSCCP-NEXT:    [[TMP32:%.*]] = phi ptr [ [[TMP17]], [[BB23]] ], [ [[TMP17]], [[BB25]] ], [ [[TMP9]], [[BB8]] ]
-; IPSCCP-NEXT:    [[TMP33:%.*]] = phi ptr [ [[TMP17]], [[BB23]] ], [ [[TMP17]], [[BB25]] ], [ [[TMP10]], [[BB8]] ]
-; IPSCCP-NEXT:    [[TMP34:%.*]] = icmp eq i32 [[TMP11]], 0
-; IPSCC...
[truncated]

``````````

</details>


https://github.com/llvm/llvm-project/pull/153003


More information about the llvm-commits mailing list