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(F); - auto *DT = AM.getCachedResult(F); - DomTreeUpdater DTU(DT, DomTreeUpdater::UpdateStrategy::Lazy); - if (!runSCCP(F, DL, &TLI, DTU)) + auto &DT = AM.getResult(F); + auto &AC = AM.getResult(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 -; IPSCCP-NEXT: br i1 [[TMP34]], label [[BB35:%.*]], label [[BB37:%.*]] -; IPSCCP: bb35: -; IPSCCP-NEXT: [[TMP36:%.*]] = getelementptr inbounds nuw i8, ptr [[TMP32]], i64 1 -; IPSCCP-NEXT: br label [[BB66:%.*]] -; IPSCCP: bb37: -; IPSCCP-NEXT: [[C_2:%.*]] = icmp eq i32 [[TMP11]], 8 -; IPSCCP-NEXT: br i1 [[C_2]], label [[BB39:%.*]], label [[BB58:%.*]] -; IPSCCP: bb39: -; IPSCCP-NEXT: [[TMP41:%.*]] = trunc nuw i32 [[TMP3]] to i16 -; IPSCCP-NEXT: store i16 [[TMP41]], ptr @global.11, align 1 -; IPSCCP-NEXT: [[TMP43:%.*]] = add i32 [[TMP7]], 7 -; IPSCCP-NEXT: [[TMP44:%.*]] = mul i32 [[TMP43]], 4 -; IPSCCP-NEXT: [[TMP45:%.*]] = add i32 [[TMP44]], 2 -; IPSCCP-NEXT: [[TMP46:%.*]] = call dereferenceable(1) ptr @spam(ptr [[ARG]], i32 [[TMP45]]) -; IPSCCP-NEXT: [[TMP47:%.*]] = load i8, ptr [[TMP46]], align 1 -; IPSCCP-NEXT: [[TMP48:%.*]] = zext i8 [[TMP47]] to i32 -; IPSCCP-NEXT: [[TMP49:%.*]] = sub i32 [[TMP43]], 1 -; IPSCCP-NEXT: [[TMP50:%.*]] = mul i32 [[TMP49]], 4 -; IPSCCP-NEXT: [[TMP51:%.*]] = add i32 [[TMP50]], 2 -; IPSCCP-NEXT: [[TMP52:%.*]] = call dereferenceable(1) ptr @spam(ptr [[ARG]], i32 [[TMP51]]) -; IPSCCP-NEXT: [[TMP53:%.*]] = load i8, ptr [[TMP52]], align 1 -; IPSCCP-NEXT: [[TMP54:%.*]] = zext i8 [[TMP53]] to i32 -; IPSCCP-NEXT: [[TMP55:%.*]] = icmp sgt i32 [[TMP48]], [[TMP54]] -; IPSCCP-NEXT: br i1 [[TMP55]], label [[BB56:%.*]], label [[BB60:%.*]] -; IPSCCP: bb56: -; IPSCCP-NEXT: br label [[BB60]] -; IPSCCP: bb58: -; IPSCCP-NEXT: call void @llvm.memcpy.p0.p0.i64(ptr align 1 @global.11, ptr align 2 [[TMP33]], i64 4, i1 false) -; IPSCCP-NEXT: br label [[BB60]] -; IPSCCP: bb60: -; IPSCCP-NEXT: [[TMP61:%.*]] = phi i32 [ 6, [[BB56]] ], [ 7, [[BB39]] ], [ [[TMP11]], [[BB58]] ] -; IPSCCP-NEXT: [[TMP63:%.*]] = add i32 [[TMP7]], 1 -; IPSCCP-NEXT: [[TMP64:%.*]] = mul i32 [[TMP63]], 4 -; IPSCCP-NEXT: [[TMP65:%.*]] = call dereferenceable(1) ptr @spam(ptr [[ARG]], i32 [[TMP64]]) -; IPSCCP-NEXT: br label [[BB66]] -; IPSCCP: bb66: -; IPSCCP-NEXT: [[TMP67:%.*]] = phi ptr [ [[TMP36]], [[BB35]] ], [ null, [[BB60]] ] -; IPSCCP-NEXT: ret ptr [[TMP67]] +; CHECK-LABEL: @wobble( +; CHECK-NEXT: bb: +; CHECK-NEXT: [[TMP:%.*]] = lshr i32 [[ARG1:%.*]], 16 +; CHECK-NEXT: [[TMP2:%.*]] = xor i32 [[TMP]], [[ARG1]] +; CHECK-NEXT: [[TMP3:%.*]] = and i32 [[TMP2]], 65535 +; CHECK-NEXT: [[TMP4:%.*]] = mul i32 [[ARG1]], 8 +; CHECK-NEXT: [[TMP5:%.*]] = getelementptr inbounds nuw [[STRUCT_BLAM_2:%.*]], ptr [[ARG:%.*]], i32 0, i32 1 +; CHECK-NEXT: [[TMP6:%.*]] = load i32, ptr [[TMP5]], align 8 +; CHECK-NEXT: [[TMP7:%.*]] = and i32 [[TMP4]], [[TMP6]] +; CHECK-NEXT: br label [[BB8:%.*]] +; CHECK: bb8: +; CHECK-NEXT: [[TMP9:%.*]] = phi ptr [ undef, [[BB:%.*]] ], [ [[TMP17:%.*]], [[BB29:%.*]] ] +; CHECK-NEXT: [[TMP10:%.*]] = phi ptr [ undef, [[BB]] ], [ [[TMP17]], [[BB29]] ] +; CHECK-NEXT: [[TMP11:%.*]] = phi i32 [ 0, [[BB]] ], [ [[TMP30:%.*]], [[BB29]] ] +; CHECK-NEXT: [[C_1:%.*]] = icmp slt i32 [[TMP11]], 8 +; CHECK-NEXT: br i1 [[C_1]], label [[BB13:%.*]], label [[BB31:%.*]] +; CHECK: bb13: +; CHECK-NEXT: [[TMP15:%.*]] = add i32 [[TMP7]], [[TMP11]] +; CHECK-NEXT: [[TMP16:%.*]] = mul i32 [[TMP15]], 4 +; CHECK-NEXT: [[TMP17]] = call dereferenceable(1) ptr @spam(ptr [[ARG]], i32 [[TMP16]]) +; CHECK-NEXT: [[TMP19:%.*]] = getelementptr inbounds nuw i8, ptr [[TMP17]], i64 2 +; CHECK-NEXT: [[TMP20:%.*]] = load i8, ptr [[TMP19]], align 1 +; CHECK-NEXT: [[TMP21:%.*]] = zext i8 [[TMP20]] to i32 +; CHECK-NEXT: [[TMP22:%.*]] = icmp eq i32 [[TMP21]], 0 +; CHECK-NEXT: br i1 [[TMP22]], label [[BB23:%.*]], label [[BB25:%.*]] +; CHECK: bb23: +; CHECK-NEXT: [[TMP24:%.*]] = trunc nuw i32 [[TMP3]] to i16 +; CHECK-NEXT: store i16 [[TMP24]], ptr [[TMP17]], align 2 +; CHECK-NEXT: br label [[BB31]] +; CHECK: bb25: +; CHECK-NEXT: [[TMP26:%.*]] = load i16, ptr [[TMP17]], align 2 +; CHECK-NEXT: [[TMP27:%.*]] = zext i16 [[TMP26]] to i32 +; CHECK-NEXT: [[TMP28:%.*]] = icmp eq i32 [[TMP27]], [[TMP3]] +; CHECK-NEXT: br i1 [[TMP28]], label [[BB31]], label [[BB29]] +; CHECK: bb29: +; CHECK-NEXT: [[TMP30]] = add nsw i32 [[TMP11]], 1 +; CHECK-NEXT: br label [[BB8]] +; CHECK: bb31: +; CHECK-NEXT: [[TMP32:%.*]] = phi ptr [ [[TMP17]], [[BB23]] ], [ [[TMP17]], [[BB25]] ], [ [[TMP9]], [[BB8]] ] +; CHECK-NEXT: [[TMP33:%.*]] = phi ptr [ [[TMP17]], [[BB23]] ], [ [[TMP17]], [[BB25]] ], [ [[TMP10]], [[BB8]] ] +; CHECK-NEXT: [[TMP34:%.*]] = icmp eq i32 [[TMP11]], 0 +; CHECK-NEXT: br i1 [[TMP34]], label [[BB35:%.*]], label [[BB37:%.*]] +; CHECK: bb35: +; CHECK-NEXT: [[TMP36:%.*]] = getelementptr inbounds nuw i8, ptr [[TMP32]], i64 1 +; CHECK-NEXT: br label [[BB66:%.*]] +; CHECK: bb37: +; CHECK-NEXT: [[C_2:%.*]] = icmp eq i32 [[TMP11]], 8 +; CHECK-NEXT: br i1 [[C_2]], label [[BB39:%.*]], label [[BB58:%.*]] +; CHECK: bb39: +; CHECK-NEXT: [[TMP41:%.*]] = trunc nuw i32 [[TMP3]] to i16 +; CHECK-NEXT: store i16 [[TMP41]], ptr @global.11, align 1 +; CHECK-NEXT: [[TMP43:%.*]] = add i32 [[TMP7]], 7 +; CHECK-NEXT: [[TMP44:%.*]] = mul i32 [[TMP43]], 4 +; CHECK-NEXT: [[TMP45:%.*]] = add i32 [[TMP44]], 2 +; CHECK-NEXT: [[TMP46:%.*]] = call dereferenceable(1) ptr @spam(ptr [[ARG]], i32 [[TMP45]]) +; CHECK-NEXT: [[TMP47:%.*]] = load i8, ptr [[TMP46]], align 1 +; CHECK-NEXT: [[TMP48:%.*]] = zext i8 [[TMP47]] to i32 +; CHECK-NEXT: [[TMP49:%.*]] = sub i32 [[TMP43]], 1 +; CHECK-NEXT: [[TMP50:%.*]] = mul i32 [[TMP49]], 4 +; CHECK-NEXT: [[TMP51:%.*]] = add i32 [[TMP50]], 2 +; CHECK-NEXT: [[TMP52:%.*]] = call dereferenceable(1) ptr @spam(ptr [[ARG]], i32 [[TMP51]]) +; CHECK-NEXT: [[TMP53:%.*]] = load i8, ptr [[TMP52]], align 1 +; CHECK-NEXT: [[TMP54:%.*]] = zext i8 [[TMP53]] to i32 +; CHECK-NEXT: [[TMP55:%.*]] = icmp sgt i32 [[TMP48]], [[TMP54]] +; CHECK-NEXT: br i1 [[TMP55]], label [[BB56:%.*]], label [[BB60:%.*]] +; CHECK: bb56: +; CHECK-NEXT: br label [[BB60]] +; CHECK: bb58: +; CHECK-NEXT: call void @llvm.memcpy.p0.p0.i64(ptr align 1 @global.11, ptr align 2 [[TMP33]], i64 4, i1 false) +; CHECK-NEXT: br label [[BB60]] +; CHECK: bb60: +; CHECK-NEXT: [[TMP61:%.*]] = phi i32 [ 6, [[BB56]] ], [ 7, [[BB39]] ], [ [[TMP11]], [[BB58]] ] +; CHECK-NEXT: [[TMP63:%.*]] = add i32 [[TMP7]], 1 +; CHECK-NEXT: [[TMP64:%.*]] = mul i32 [[TMP63]], 4 +; CHECK-NEXT: [[TMP65:%.*]] = call dereferenceable(1) ptr @spam(ptr [[ARG]], i32 [[TMP64]]) +; CHECK-NEXT: br label [[BB66]] +; CHECK: bb66: +; CHECK-NEXT: [[TMP67:%.*]] = phi ptr [ [[TMP36]], [[BB35]] ], [ null, [[BB60]] ] +; CHECK-NEXT: ret ptr [[TMP67]] ; bb: %tmp = lshr i32 %arg1, 16 @@ -766,3 +654,6 @@ bb6: end: ret i32 %p } +;; NOTE: These prefixes are unused and the list is autogenerated. Do not add tests below this line: +; IPSCCP: {{.*}} +; SCCP: {{.*}}