diff --git a/llvm/lib/Transforms/Utils/SimplifyCFG.cpp b/llvm/lib/Transforms/Utils/SimplifyCFG.cpp --- a/llvm/lib/Transforms/Utils/SimplifyCFG.cpp +++ b/llvm/lib/Transforms/Utils/SimplifyCFG.cpp @@ -94,6 +94,12 @@ cl::desc( "Control the amount of phi node folding to perform (default = 2)")); +static cl::opt TwoEntryPHINodeFoldingThreshold( + "two-entry-phi-node-folding-threshold", cl::Hidden, cl::init(4), + cl::desc("Control the maximal total instruction cost that we are willing " + "to speculatively execute to fold a 2-entry PHI node into a " + "select (default = 4)")); + static cl::opt DupRet( "simplifycfg-dup-ret", cl::Hidden, cl::init(false), cl::desc("Duplicate return instructions into unconditional branches")); @@ -332,7 +338,7 @@ /// CostRemaining, false is returned and CostRemaining is undefined. static bool DominatesMergePoint(Value *V, BasicBlock *BB, SmallPtrSetImpl &AggressiveInsts, - unsigned &CostRemaining, + int &BudgetRemaining, const TargetTransformInfo &TTI, unsigned Depth = 0) { // It is possible to hit a zero-cost cycle (phi/gep instructions for example), @@ -375,7 +381,7 @@ if (!isSafeToSpeculativelyExecute(I)) return false; - unsigned Cost = ComputeSpeculationCost(I, TTI); + BudgetRemaining -= ComputeSpeculationCost(I, TTI); // Allow exactly one instruction to be speculated regardless of its cost // (as long as it is safe to do so). @@ -383,17 +389,14 @@ // or other expensive operation. The speculation of an expensive instruction // is expected to be undone in CodeGenPrepare if the speculation has not // enabled further IR optimizations. - if (Cost > CostRemaining && + if (BudgetRemaining < 0 && (!SpeculateOneExpensiveInst || !AggressiveInsts.empty() || Depth > 0)) return false; - // Avoid unsigned wrap. - CostRemaining = (Cost > CostRemaining) ? 0 : CostRemaining - Cost; - // Okay, we can only really hoist these out if their operands do // not take us over the cost threshold. for (User::op_iterator i = I->op_begin(), e = I->op_end(); i != e; ++i) - if (!DominatesMergePoint(*i, BB, AggressiveInsts, CostRemaining, TTI, + if (!DominatesMergePoint(*i, BB, AggressiveInsts, BudgetRemaining, TTI, Depth + 1)) return false; // Okay, it's safe to do this! Remember this instruction. @@ -2322,10 +2325,8 @@ // instructions. While we are at it, keep track of the instructions // that need to be moved to the dominating block. SmallPtrSet AggressiveInsts; - unsigned MaxCostVal0 = PHINodeFoldingThreshold, - MaxCostVal1 = PHINodeFoldingThreshold; - MaxCostVal0 *= TargetTransformInfo::TCC_Basic; - MaxCostVal1 *= TargetTransformInfo::TCC_Basic; + int BudgetRemaining = + TwoEntryPHINodeFoldingThreshold * TargetTransformInfo::TCC_Basic; for (BasicBlock::iterator II = BB->begin(); isa(II);) { PHINode *PN = cast(II++); @@ -2336,9 +2337,9 @@ } if (!DominatesMergePoint(PN->getIncomingValue(0), BB, AggressiveInsts, - MaxCostVal0, TTI) || + BudgetRemaining, TTI) || !DominatesMergePoint(PN->getIncomingValue(1), BB, AggressiveInsts, - MaxCostVal1, TTI)) + BudgetRemaining, TTI)) return false; } diff --git a/llvm/test/Transforms/SimplifyCFG/PhiEliminate3.ll b/llvm/test/Transforms/SimplifyCFG/PhiEliminate3.ll --- a/llvm/test/Transforms/SimplifyCFG/PhiEliminate3.ll +++ b/llvm/test/Transforms/SimplifyCFG/PhiEliminate3.ll @@ -7,55 +7,21 @@ ; with various folding thresholds define i32 @test(i1 %a, i1 %b, i32 %i, i32 %j, i32 %k) { -; CHECK-ONE-LABEL: @test( -; CHECK-ONE-NEXT: entry: -; CHECK-ONE-NEXT: br i1 [[A:%.*]], label [[M:%.*]], label [[O:%.*]] -; CHECK-ONE: O: -; CHECK-ONE-NEXT: br i1 [[B:%.*]], label [[P:%.*]], label [[Q:%.*]] -; CHECK-ONE: P: -; CHECK-ONE-NEXT: [[IAJ:%.*]] = add i32 [[I:%.*]], [[J:%.*]] -; CHECK-ONE-NEXT: [[IAJAK:%.*]] = add i32 [[IAJ]], [[K:%.*]] -; CHECK-ONE-NEXT: br label [[N:%.*]] -; CHECK-ONE: Q: -; CHECK-ONE-NEXT: [[IXJ:%.*]] = xor i32 [[I]], [[J]] -; CHECK-ONE-NEXT: [[IXJXK:%.*]] = xor i32 [[IXJ]], [[K]] -; CHECK-ONE-NEXT: br label [[N]] -; CHECK-ONE: N: -; CHECK-ONE-NEXT: [[WP:%.*]] = phi i32 [ [[IAJAK]], [[P]] ], [ [[IXJXK]], [[Q]] ] -; CHECK-ONE-NEXT: [[WP2:%.*]] = add i32 [[WP]], [[WP]] -; CHECK-ONE-NEXT: br label [[M]] -; CHECK-ONE: M: -; CHECK-ONE-NEXT: [[W:%.*]] = phi i32 [ [[WP2]], [[N]] ], [ 2, [[ENTRY:%.*]] ] -; CHECK-ONE-NEXT: [[R:%.*]] = add i32 [[W]], 1 -; CHECK-ONE-NEXT: ret i32 [[R]] -; -; CHECK-TWO-LABEL: @test( -; CHECK-TWO-NEXT: entry: -; CHECK-TWO-NEXT: br i1 [[A:%.*]], label [[M:%.*]], label [[O:%.*]] -; CHECK-TWO: O: -; CHECK-TWO-NEXT: [[IAJ:%.*]] = add i32 [[I:%.*]], [[J:%.*]] -; CHECK-TWO-NEXT: [[IAJAK:%.*]] = add i32 [[IAJ]], [[K:%.*]] -; CHECK-TWO-NEXT: [[IXJ:%.*]] = xor i32 [[I]], [[J]] -; CHECK-TWO-NEXT: [[IXJXK:%.*]] = xor i32 [[IXJ]], [[K]] -; CHECK-TWO-NEXT: [[WP:%.*]] = select i1 [[B:%.*]], i32 [[IAJAK]], i32 [[IXJXK]] -; CHECK-TWO-NEXT: [[WP2:%.*]] = add i32 [[WP]], [[WP]] -; CHECK-TWO-NEXT: br label [[M]] -; CHECK-TWO: M: -; CHECK-TWO-NEXT: [[W:%.*]] = phi i32 [ [[WP2]], [[O]] ], [ 2, [[ENTRY:%.*]] ] -; CHECK-TWO-NEXT: [[R:%.*]] = add i32 [[W]], 1 -; CHECK-TWO-NEXT: ret i32 [[R]] -; -; CHECK-SEVEN-LABEL: @test( -; CHECK-SEVEN-NEXT: entry: -; CHECK-SEVEN-NEXT: [[IAJ:%.*]] = add i32 [[I:%.*]], [[J:%.*]] -; CHECK-SEVEN-NEXT: [[IAJAK:%.*]] = add i32 [[IAJ]], [[K:%.*]] -; CHECK-SEVEN-NEXT: [[IXJ:%.*]] = xor i32 [[I]], [[J]] -; CHECK-SEVEN-NEXT: [[IXJXK:%.*]] = xor i32 [[IXJ]], [[K]] -; CHECK-SEVEN-NEXT: [[WP:%.*]] = select i1 [[B:%.*]], i32 [[IAJAK]], i32 [[IXJXK]] -; CHECK-SEVEN-NEXT: [[WP2:%.*]] = add i32 [[WP]], [[WP]] -; CHECK-SEVEN-NEXT: [[W:%.*]] = select i1 [[A:%.*]], i32 2, i32 [[WP2]] -; CHECK-SEVEN-NEXT: [[R:%.*]] = add i32 [[W]], 1 -; CHECK-SEVEN-NEXT: ret i32 [[R]] +; ALL-LABEL: @test( +; ALL-NEXT: entry: +; ALL-NEXT: br i1 [[A:%.*]], label [[M:%.*]], label [[O:%.*]] +; ALL: O: +; ALL-NEXT: [[IAJ:%.*]] = add i32 [[I:%.*]], [[J:%.*]] +; ALL-NEXT: [[IAJAK:%.*]] = add i32 [[IAJ]], [[K:%.*]] +; ALL-NEXT: [[IXJ:%.*]] = xor i32 [[I]], [[J]] +; ALL-NEXT: [[IXJXK:%.*]] = xor i32 [[IXJ]], [[K]] +; ALL-NEXT: [[WP:%.*]] = select i1 [[B:%.*]], i32 [[IAJAK]], i32 [[IXJXK]] +; ALL-NEXT: [[WP2:%.*]] = add i32 [[WP]], [[WP]] +; ALL-NEXT: br label [[M]] +; ALL: M: +; ALL-NEXT: [[W:%.*]] = phi i32 [ [[WP2]], [[O]] ], [ 2, [[ENTRY:%.*]] ] +; ALL-NEXT: [[R:%.*]] = add i32 [[W]], 1 +; ALL-NEXT: ret i32 [[R]] ; entry: br i1 %a, label %M, label %O diff --git a/llvm/test/Transforms/SimplifyCFG/SpeculativeExec.ll b/llvm/test/Transforms/SimplifyCFG/SpeculativeExec.ll --- a/llvm/test/Transforms/SimplifyCFG/SpeculativeExec.ll +++ b/llvm/test/Transforms/SimplifyCFG/SpeculativeExec.ll @@ -8,14 +8,10 @@ ; CHECK-LABEL: @test1( ; CHECK-NEXT: entry: ; CHECK-NEXT: [[TMP1:%.*]] = icmp eq i32 [[B:%.*]], 0 -; CHECK-NEXT: br i1 [[TMP1]], label [[BB1:%.*]], label [[BB3:%.*]] -; CHECK: bb1: ; CHECK-NEXT: [[TMP2:%.*]] = icmp sgt i32 [[C:%.*]], 1 ; CHECK-NEXT: [[TMP3:%.*]] = add i32 [[A:%.*]], 1 ; CHECK-NEXT: [[SPEC_SELECT:%.*]] = select i1 [[TMP2]], i32 [[TMP3]], i32 [[A]] -; CHECK-NEXT: br label [[BB3]] -; CHECK: bb3: -; CHECK-NEXT: [[TMP4:%.*]] = phi i32 [ [[B]], [[ENTRY:%.*]] ], [ [[SPEC_SELECT]], [[BB1]] ] +; CHECK-NEXT: [[TMP4:%.*]] = select i1 [[TMP1]], i32 [[SPEC_SELECT]], i32 [[B]] ; CHECK-NEXT: [[TMP5:%.*]] = sub i32 [[TMP4]], 1 ; CHECK-NEXT: ret i32 [[TMP5]] ; diff --git a/llvm/test/Transforms/SimplifyCFG/X86/speculate-cttz-ctlz.ll b/llvm/test/Transforms/SimplifyCFG/X86/speculate-cttz-ctlz.ll --- a/llvm/test/Transforms/SimplifyCFG/X86/speculate-cttz-ctlz.ll +++ b/llvm/test/Transforms/SimplifyCFG/X86/speculate-cttz-ctlz.ll @@ -223,37 +223,13 @@ ; for the target. define i64 @test1e(i32 %x) { -; BMI-LABEL: @test1e( -; BMI-NEXT: entry: -; BMI-NEXT: [[TOBOOL:%.*]] = icmp eq i32 [[X:%.*]], 0 -; BMI-NEXT: [[TMP0:%.*]] = tail call i32 @llvm.cttz.i32(i32 [[X]], i1 true) -; BMI-NEXT: [[PHITMP2:%.*]] = zext i32 [[TMP0]] to i64 -; BMI-NEXT: [[COND:%.*]] = select i1 [[TOBOOL]], i64 32, i64 [[PHITMP2]] -; BMI-NEXT: ret i64 [[COND]] -; -; LZCNT-LABEL: @test1e( -; LZCNT-NEXT: entry: -; LZCNT-NEXT: [[TOBOOL:%.*]] = icmp eq i32 [[X:%.*]], 0 -; LZCNT-NEXT: br i1 [[TOBOOL]], label [[COND_END:%.*]], label [[COND_TRUE:%.*]] -; LZCNT: cond.true: -; LZCNT-NEXT: [[TMP0:%.*]] = tail call i32 @llvm.cttz.i32(i32 [[X]], i1 true) -; LZCNT-NEXT: [[PHITMP2:%.*]] = zext i32 [[TMP0]] to i64 -; LZCNT-NEXT: br label [[COND_END]] -; LZCNT: cond.end: -; LZCNT-NEXT: [[COND:%.*]] = phi i64 [ [[PHITMP2]], [[COND_TRUE]] ], [ 32, [[ENTRY:%.*]] ] -; LZCNT-NEXT: ret i64 [[COND]] -; -; GENERIC-LABEL: @test1e( -; GENERIC-NEXT: entry: -; GENERIC-NEXT: [[TOBOOL:%.*]] = icmp eq i32 [[X:%.*]], 0 -; GENERIC-NEXT: br i1 [[TOBOOL]], label [[COND_END:%.*]], label [[COND_TRUE:%.*]] -; GENERIC: cond.true: -; GENERIC-NEXT: [[TMP0:%.*]] = tail call i32 @llvm.cttz.i32(i32 [[X]], i1 true) -; GENERIC-NEXT: [[PHITMP2:%.*]] = zext i32 [[TMP0]] to i64 -; GENERIC-NEXT: br label [[COND_END]] -; GENERIC: cond.end: -; GENERIC-NEXT: [[COND:%.*]] = phi i64 [ [[PHITMP2]], [[COND_TRUE]] ], [ 32, [[ENTRY:%.*]] ] -; GENERIC-NEXT: ret i64 [[COND]] +; ALL-LABEL: @test1e( +; ALL-NEXT: entry: +; ALL-NEXT: [[TOBOOL:%.*]] = icmp eq i32 [[X:%.*]], 0 +; ALL-NEXT: [[TMP0:%.*]] = tail call i32 @llvm.cttz.i32(i32 [[X]], i1 true) +; ALL-NEXT: [[PHITMP2:%.*]] = zext i32 [[TMP0]] to i64 +; ALL-NEXT: [[COND:%.*]] = select i1 [[TOBOOL]], i64 32, i64 [[PHITMP2]] +; ALL-NEXT: ret i64 [[COND]] ; entry: %tobool = icmp eq i32 %x, 0 @@ -270,37 +246,13 @@ } define i32 @test2e(i64 %x) { -; BMI-LABEL: @test2e( -; BMI-NEXT: entry: -; BMI-NEXT: [[TOBOOL:%.*]] = icmp eq i64 [[X:%.*]], 0 -; BMI-NEXT: [[TMP0:%.*]] = tail call i64 @llvm.cttz.i64(i64 [[X]], i1 true) -; BMI-NEXT: [[CAST:%.*]] = trunc i64 [[TMP0]] to i32 -; BMI-NEXT: [[COND:%.*]] = select i1 [[TOBOOL]], i32 64, i32 [[CAST]] -; BMI-NEXT: ret i32 [[COND]] -; -; LZCNT-LABEL: @test2e( -; LZCNT-NEXT: entry: -; LZCNT-NEXT: [[TOBOOL:%.*]] = icmp eq i64 [[X:%.*]], 0 -; LZCNT-NEXT: br i1 [[TOBOOL]], label [[COND_END:%.*]], label [[COND_TRUE:%.*]] -; LZCNT: cond.true: -; LZCNT-NEXT: [[TMP0:%.*]] = tail call i64 @llvm.cttz.i64(i64 [[X]], i1 true) -; LZCNT-NEXT: [[CAST:%.*]] = trunc i64 [[TMP0]] to i32 -; LZCNT-NEXT: br label [[COND_END]] -; LZCNT: cond.end: -; LZCNT-NEXT: [[COND:%.*]] = phi i32 [ [[CAST]], [[COND_TRUE]] ], [ 64, [[ENTRY:%.*]] ] -; LZCNT-NEXT: ret i32 [[COND]] -; -; GENERIC-LABEL: @test2e( -; GENERIC-NEXT: entry: -; GENERIC-NEXT: [[TOBOOL:%.*]] = icmp eq i64 [[X:%.*]], 0 -; GENERIC-NEXT: br i1 [[TOBOOL]], label [[COND_END:%.*]], label [[COND_TRUE:%.*]] -; GENERIC: cond.true: -; GENERIC-NEXT: [[TMP0:%.*]] = tail call i64 @llvm.cttz.i64(i64 [[X]], i1 true) -; GENERIC-NEXT: [[CAST:%.*]] = trunc i64 [[TMP0]] to i32 -; GENERIC-NEXT: br label [[COND_END]] -; GENERIC: cond.end: -; GENERIC-NEXT: [[COND:%.*]] = phi i32 [ [[CAST]], [[COND_TRUE]] ], [ 64, [[ENTRY:%.*]] ] -; GENERIC-NEXT: ret i32 [[COND]] +; ALL-LABEL: @test2e( +; ALL-NEXT: entry: +; ALL-NEXT: [[TOBOOL:%.*]] = icmp eq i64 [[X:%.*]], 0 +; ALL-NEXT: [[TMP0:%.*]] = tail call i64 @llvm.cttz.i64(i64 [[X]], i1 true) +; ALL-NEXT: [[CAST:%.*]] = trunc i64 [[TMP0]] to i32 +; ALL-NEXT: [[COND:%.*]] = select i1 [[TOBOOL]], i32 64, i32 [[CAST]] +; ALL-NEXT: ret i32 [[COND]] ; entry: %tobool = icmp eq i64 %x, 0 @@ -317,37 +269,13 @@ } define i64 @test3e(i32 %x) { -; BMI-LABEL: @test3e( -; BMI-NEXT: entry: -; BMI-NEXT: [[TOBOOL:%.*]] = icmp eq i32 [[X:%.*]], 0 -; BMI-NEXT: br i1 [[TOBOOL]], label [[COND_END:%.*]], label [[COND_TRUE:%.*]] -; BMI: cond.true: -; BMI-NEXT: [[TMP0:%.*]] = tail call i32 @llvm.ctlz.i32(i32 [[X]], i1 true) -; BMI-NEXT: [[PHITMP2:%.*]] = zext i32 [[TMP0]] to i64 -; BMI-NEXT: br label [[COND_END]] -; BMI: cond.end: -; BMI-NEXT: [[COND:%.*]] = phi i64 [ [[PHITMP2]], [[COND_TRUE]] ], [ 32, [[ENTRY:%.*]] ] -; BMI-NEXT: ret i64 [[COND]] -; -; LZCNT-LABEL: @test3e( -; LZCNT-NEXT: entry: -; LZCNT-NEXT: [[TOBOOL:%.*]] = icmp eq i32 [[X:%.*]], 0 -; LZCNT-NEXT: [[TMP0:%.*]] = tail call i32 @llvm.ctlz.i32(i32 [[X]], i1 true) -; LZCNT-NEXT: [[PHITMP2:%.*]] = zext i32 [[TMP0]] to i64 -; LZCNT-NEXT: [[COND:%.*]] = select i1 [[TOBOOL]], i64 32, i64 [[PHITMP2]] -; LZCNT-NEXT: ret i64 [[COND]] -; -; GENERIC-LABEL: @test3e( -; GENERIC-NEXT: entry: -; GENERIC-NEXT: [[TOBOOL:%.*]] = icmp eq i32 [[X:%.*]], 0 -; GENERIC-NEXT: br i1 [[TOBOOL]], label [[COND_END:%.*]], label [[COND_TRUE:%.*]] -; GENERIC: cond.true: -; GENERIC-NEXT: [[TMP0:%.*]] = tail call i32 @llvm.ctlz.i32(i32 [[X]], i1 true) -; GENERIC-NEXT: [[PHITMP2:%.*]] = zext i32 [[TMP0]] to i64 -; GENERIC-NEXT: br label [[COND_END]] -; GENERIC: cond.end: -; GENERIC-NEXT: [[COND:%.*]] = phi i64 [ [[PHITMP2]], [[COND_TRUE]] ], [ 32, [[ENTRY:%.*]] ] -; GENERIC-NEXT: ret i64 [[COND]] +; ALL-LABEL: @test3e( +; ALL-NEXT: entry: +; ALL-NEXT: [[TOBOOL:%.*]] = icmp eq i32 [[X:%.*]], 0 +; ALL-NEXT: [[TMP0:%.*]] = tail call i32 @llvm.ctlz.i32(i32 [[X]], i1 true) +; ALL-NEXT: [[PHITMP2:%.*]] = zext i32 [[TMP0]] to i64 +; ALL-NEXT: [[COND:%.*]] = select i1 [[TOBOOL]], i64 32, i64 [[PHITMP2]] +; ALL-NEXT: ret i64 [[COND]] ; entry: %tobool = icmp eq i32 %x, 0 @@ -364,37 +292,13 @@ } define i32 @test4e(i64 %x) { -; BMI-LABEL: @test4e( -; BMI-NEXT: entry: -; BMI-NEXT: [[TOBOOL:%.*]] = icmp eq i64 [[X:%.*]], 0 -; BMI-NEXT: br i1 [[TOBOOL]], label [[COND_END:%.*]], label [[COND_TRUE:%.*]] -; BMI: cond.true: -; BMI-NEXT: [[TMP0:%.*]] = tail call i64 @llvm.ctlz.i64(i64 [[X]], i1 true) -; BMI-NEXT: [[CAST:%.*]] = trunc i64 [[TMP0]] to i32 -; BMI-NEXT: br label [[COND_END]] -; BMI: cond.end: -; BMI-NEXT: [[COND:%.*]] = phi i32 [ [[CAST]], [[COND_TRUE]] ], [ 64, [[ENTRY:%.*]] ] -; BMI-NEXT: ret i32 [[COND]] -; -; LZCNT-LABEL: @test4e( -; LZCNT-NEXT: entry: -; LZCNT-NEXT: [[TOBOOL:%.*]] = icmp eq i64 [[X:%.*]], 0 -; LZCNT-NEXT: [[TMP0:%.*]] = tail call i64 @llvm.ctlz.i64(i64 [[X]], i1 true) -; LZCNT-NEXT: [[CAST:%.*]] = trunc i64 [[TMP0]] to i32 -; LZCNT-NEXT: [[COND:%.*]] = select i1 [[TOBOOL]], i32 64, i32 [[CAST]] -; LZCNT-NEXT: ret i32 [[COND]] -; -; GENERIC-LABEL: @test4e( -; GENERIC-NEXT: entry: -; GENERIC-NEXT: [[TOBOOL:%.*]] = icmp eq i64 [[X:%.*]], 0 -; GENERIC-NEXT: br i1 [[TOBOOL]], label [[COND_END:%.*]], label [[COND_TRUE:%.*]] -; GENERIC: cond.true: -; GENERIC-NEXT: [[TMP0:%.*]] = tail call i64 @llvm.ctlz.i64(i64 [[X]], i1 true) -; GENERIC-NEXT: [[CAST:%.*]] = trunc i64 [[TMP0]] to i32 -; GENERIC-NEXT: br label [[COND_END]] -; GENERIC: cond.end: -; GENERIC-NEXT: [[COND:%.*]] = phi i32 [ [[CAST]], [[COND_TRUE]] ], [ 64, [[ENTRY:%.*]] ] -; GENERIC-NEXT: ret i32 [[COND]] +; ALL-LABEL: @test4e( +; ALL-NEXT: entry: +; ALL-NEXT: [[TOBOOL:%.*]] = icmp eq i64 [[X:%.*]], 0 +; ALL-NEXT: [[TMP0:%.*]] = tail call i64 @llvm.ctlz.i64(i64 [[X]], i1 true) +; ALL-NEXT: [[CAST:%.*]] = trunc i64 [[TMP0]] to i32 +; ALL-NEXT: [[COND:%.*]] = select i1 [[TOBOOL]], i32 64, i32 [[CAST]] +; ALL-NEXT: ret i32 [[COND]] ; entry: %tobool = icmp eq i64 %x, 0 @@ -411,37 +315,13 @@ } define i16 @test5e(i64 %x) { -; BMI-LABEL: @test5e( -; BMI-NEXT: entry: -; BMI-NEXT: [[TOBOOL:%.*]] = icmp eq i64 [[X:%.*]], 0 -; BMI-NEXT: br i1 [[TOBOOL]], label [[COND_END:%.*]], label [[COND_TRUE:%.*]] -; BMI: cond.true: -; BMI-NEXT: [[TMP0:%.*]] = tail call i64 @llvm.ctlz.i64(i64 [[X]], i1 true) -; BMI-NEXT: [[CAST:%.*]] = trunc i64 [[TMP0]] to i16 -; BMI-NEXT: br label [[COND_END]] -; BMI: cond.end: -; BMI-NEXT: [[COND:%.*]] = phi i16 [ [[CAST]], [[COND_TRUE]] ], [ 64, [[ENTRY:%.*]] ] -; BMI-NEXT: ret i16 [[COND]] -; -; LZCNT-LABEL: @test5e( -; LZCNT-NEXT: entry: -; LZCNT-NEXT: [[TOBOOL:%.*]] = icmp eq i64 [[X:%.*]], 0 -; LZCNT-NEXT: [[TMP0:%.*]] = tail call i64 @llvm.ctlz.i64(i64 [[X]], i1 true) -; LZCNT-NEXT: [[CAST:%.*]] = trunc i64 [[TMP0]] to i16 -; LZCNT-NEXT: [[COND:%.*]] = select i1 [[TOBOOL]], i16 64, i16 [[CAST]] -; LZCNT-NEXT: ret i16 [[COND]] -; -; GENERIC-LABEL: @test5e( -; GENERIC-NEXT: entry: -; GENERIC-NEXT: [[TOBOOL:%.*]] = icmp eq i64 [[X:%.*]], 0 -; GENERIC-NEXT: br i1 [[TOBOOL]], label [[COND_END:%.*]], label [[COND_TRUE:%.*]] -; GENERIC: cond.true: -; GENERIC-NEXT: [[TMP0:%.*]] = tail call i64 @llvm.ctlz.i64(i64 [[X]], i1 true) -; GENERIC-NEXT: [[CAST:%.*]] = trunc i64 [[TMP0]] to i16 -; GENERIC-NEXT: br label [[COND_END]] -; GENERIC: cond.end: -; GENERIC-NEXT: [[COND:%.*]] = phi i16 [ [[CAST]], [[COND_TRUE]] ], [ 64, [[ENTRY:%.*]] ] -; GENERIC-NEXT: ret i16 [[COND]] +; ALL-LABEL: @test5e( +; ALL-NEXT: entry: +; ALL-NEXT: [[TOBOOL:%.*]] = icmp eq i64 [[X:%.*]], 0 +; ALL-NEXT: [[TMP0:%.*]] = tail call i64 @llvm.ctlz.i64(i64 [[X]], i1 true) +; ALL-NEXT: [[CAST:%.*]] = trunc i64 [[TMP0]] to i16 +; ALL-NEXT: [[COND:%.*]] = select i1 [[TOBOOL]], i16 64, i16 [[CAST]] +; ALL-NEXT: ret i16 [[COND]] ; entry: %tobool = icmp eq i64 %x, 0 @@ -458,37 +338,13 @@ } define i16 @test6e(i32 %x) { -; BMI-LABEL: @test6e( -; BMI-NEXT: entry: -; BMI-NEXT: [[TOBOOL:%.*]] = icmp eq i32 [[X:%.*]], 0 -; BMI-NEXT: br i1 [[TOBOOL]], label [[COND_END:%.*]], label [[COND_TRUE:%.*]] -; BMI: cond.true: -; BMI-NEXT: [[TMP0:%.*]] = tail call i32 @llvm.ctlz.i32(i32 [[X]], i1 true) -; BMI-NEXT: [[CAST:%.*]] = trunc i32 [[TMP0]] to i16 -; BMI-NEXT: br label [[COND_END]] -; BMI: cond.end: -; BMI-NEXT: [[COND:%.*]] = phi i16 [ [[CAST]], [[COND_TRUE]] ], [ 32, [[ENTRY:%.*]] ] -; BMI-NEXT: ret i16 [[COND]] -; -; LZCNT-LABEL: @test6e( -; LZCNT-NEXT: entry: -; LZCNT-NEXT: [[TOBOOL:%.*]] = icmp eq i32 [[X:%.*]], 0 -; LZCNT-NEXT: [[TMP0:%.*]] = tail call i32 @llvm.ctlz.i32(i32 [[X]], i1 true) -; LZCNT-NEXT: [[CAST:%.*]] = trunc i32 [[TMP0]] to i16 -; LZCNT-NEXT: [[COND:%.*]] = select i1 [[TOBOOL]], i16 32, i16 [[CAST]] -; LZCNT-NEXT: ret i16 [[COND]] -; -; GENERIC-LABEL: @test6e( -; GENERIC-NEXT: entry: -; GENERIC-NEXT: [[TOBOOL:%.*]] = icmp eq i32 [[X:%.*]], 0 -; GENERIC-NEXT: br i1 [[TOBOOL]], label [[COND_END:%.*]], label [[COND_TRUE:%.*]] -; GENERIC: cond.true: -; GENERIC-NEXT: [[TMP0:%.*]] = tail call i32 @llvm.ctlz.i32(i32 [[X]], i1 true) -; GENERIC-NEXT: [[CAST:%.*]] = trunc i32 [[TMP0]] to i16 -; GENERIC-NEXT: br label [[COND_END]] -; GENERIC: cond.end: -; GENERIC-NEXT: [[COND:%.*]] = phi i16 [ [[CAST]], [[COND_TRUE]] ], [ 32, [[ENTRY:%.*]] ] -; GENERIC-NEXT: ret i16 [[COND]] +; ALL-LABEL: @test6e( +; ALL-NEXT: entry: +; ALL-NEXT: [[TOBOOL:%.*]] = icmp eq i32 [[X:%.*]], 0 +; ALL-NEXT: [[TMP0:%.*]] = tail call i32 @llvm.ctlz.i32(i32 [[X]], i1 true) +; ALL-NEXT: [[CAST:%.*]] = trunc i32 [[TMP0]] to i16 +; ALL-NEXT: [[COND:%.*]] = select i1 [[TOBOOL]], i16 32, i16 [[CAST]] +; ALL-NEXT: ret i16 [[COND]] ; entry: %tobool = icmp eq i32 %x, 0 @@ -505,37 +361,13 @@ } define i16 @test7e(i64 %x) { -; BMI-LABEL: @test7e( -; BMI-NEXT: entry: -; BMI-NEXT: [[TOBOOL:%.*]] = icmp eq i64 [[X:%.*]], 0 -; BMI-NEXT: [[TMP0:%.*]] = tail call i64 @llvm.cttz.i64(i64 [[X]], i1 true) -; BMI-NEXT: [[CAST:%.*]] = trunc i64 [[TMP0]] to i16 -; BMI-NEXT: [[COND:%.*]] = select i1 [[TOBOOL]], i16 64, i16 [[CAST]] -; BMI-NEXT: ret i16 [[COND]] -; -; LZCNT-LABEL: @test7e( -; LZCNT-NEXT: entry: -; LZCNT-NEXT: [[TOBOOL:%.*]] = icmp eq i64 [[X:%.*]], 0 -; LZCNT-NEXT: br i1 [[TOBOOL]], label [[COND_END:%.*]], label [[COND_TRUE:%.*]] -; LZCNT: cond.true: -; LZCNT-NEXT: [[TMP0:%.*]] = tail call i64 @llvm.cttz.i64(i64 [[X]], i1 true) -; LZCNT-NEXT: [[CAST:%.*]] = trunc i64 [[TMP0]] to i16 -; LZCNT-NEXT: br label [[COND_END]] -; LZCNT: cond.end: -; LZCNT-NEXT: [[COND:%.*]] = phi i16 [ [[CAST]], [[COND_TRUE]] ], [ 64, [[ENTRY:%.*]] ] -; LZCNT-NEXT: ret i16 [[COND]] -; -; GENERIC-LABEL: @test7e( -; GENERIC-NEXT: entry: -; GENERIC-NEXT: [[TOBOOL:%.*]] = icmp eq i64 [[X:%.*]], 0 -; GENERIC-NEXT: br i1 [[TOBOOL]], label [[COND_END:%.*]], label [[COND_TRUE:%.*]] -; GENERIC: cond.true: -; GENERIC-NEXT: [[TMP0:%.*]] = tail call i64 @llvm.cttz.i64(i64 [[X]], i1 true) -; GENERIC-NEXT: [[CAST:%.*]] = trunc i64 [[TMP0]] to i16 -; GENERIC-NEXT: br label [[COND_END]] -; GENERIC: cond.end: -; GENERIC-NEXT: [[COND:%.*]] = phi i16 [ [[CAST]], [[COND_TRUE]] ], [ 64, [[ENTRY:%.*]] ] -; GENERIC-NEXT: ret i16 [[COND]] +; ALL-LABEL: @test7e( +; ALL-NEXT: entry: +; ALL-NEXT: [[TOBOOL:%.*]] = icmp eq i64 [[X:%.*]], 0 +; ALL-NEXT: [[TMP0:%.*]] = tail call i64 @llvm.cttz.i64(i64 [[X]], i1 true) +; ALL-NEXT: [[CAST:%.*]] = trunc i64 [[TMP0]] to i16 +; ALL-NEXT: [[COND:%.*]] = select i1 [[TOBOOL]], i16 64, i16 [[CAST]] +; ALL-NEXT: ret i16 [[COND]] ; entry: %tobool = icmp eq i64 %x, 0 @@ -552,37 +384,13 @@ } define i16 @test8e(i32 %x) { -; BMI-LABEL: @test8e( -; BMI-NEXT: entry: -; BMI-NEXT: [[TOBOOL:%.*]] = icmp eq i32 [[X:%.*]], 0 -; BMI-NEXT: [[TMP0:%.*]] = tail call i32 @llvm.cttz.i32(i32 [[X]], i1 true) -; BMI-NEXT: [[CAST:%.*]] = trunc i32 [[TMP0]] to i16 -; BMI-NEXT: [[COND:%.*]] = select i1 [[TOBOOL]], i16 32, i16 [[CAST]] -; BMI-NEXT: ret i16 [[COND]] -; -; LZCNT-LABEL: @test8e( -; LZCNT-NEXT: entry: -; LZCNT-NEXT: [[TOBOOL:%.*]] = icmp eq i32 [[X:%.*]], 0 -; LZCNT-NEXT: br i1 [[TOBOOL]], label [[COND_END:%.*]], label [[COND_TRUE:%.*]] -; LZCNT: cond.true: -; LZCNT-NEXT: [[TMP0:%.*]] = tail call i32 @llvm.cttz.i32(i32 [[X]], i1 true) -; LZCNT-NEXT: [[CAST:%.*]] = trunc i32 [[TMP0]] to i16 -; LZCNT-NEXT: br label [[COND_END]] -; LZCNT: cond.end: -; LZCNT-NEXT: [[COND:%.*]] = phi i16 [ [[CAST]], [[COND_TRUE]] ], [ 32, [[ENTRY:%.*]] ] -; LZCNT-NEXT: ret i16 [[COND]] -; -; GENERIC-LABEL: @test8e( -; GENERIC-NEXT: entry: -; GENERIC-NEXT: [[TOBOOL:%.*]] = icmp eq i32 [[X:%.*]], 0 -; GENERIC-NEXT: br i1 [[TOBOOL]], label [[COND_END:%.*]], label [[COND_TRUE:%.*]] -; GENERIC: cond.true: -; GENERIC-NEXT: [[TMP0:%.*]] = tail call i32 @llvm.cttz.i32(i32 [[X]], i1 true) -; GENERIC-NEXT: [[CAST:%.*]] = trunc i32 [[TMP0]] to i16 -; GENERIC-NEXT: br label [[COND_END]] -; GENERIC: cond.end: -; GENERIC-NEXT: [[COND:%.*]] = phi i16 [ [[CAST]], [[COND_TRUE]] ], [ 32, [[ENTRY:%.*]] ] -; GENERIC-NEXT: ret i16 [[COND]] +; ALL-LABEL: @test8e( +; ALL-NEXT: entry: +; ALL-NEXT: [[TOBOOL:%.*]] = icmp eq i32 [[X:%.*]], 0 +; ALL-NEXT: [[TMP0:%.*]] = tail call i32 @llvm.cttz.i32(i32 [[X]], i1 true) +; ALL-NEXT: [[CAST:%.*]] = trunc i32 [[TMP0]] to i16 +; ALL-NEXT: [[COND:%.*]] = select i1 [[TOBOOL]], i16 32, i16 [[CAST]] +; ALL-NEXT: ret i16 [[COND]] ; entry: %tobool = icmp eq i32 %x, 0 diff --git a/llvm/test/Transforms/SimplifyCFG/X86/switch_to_lookup_table.ll b/llvm/test/Transforms/SimplifyCFG/X86/switch_to_lookup_table.ll --- a/llvm/test/Transforms/SimplifyCFG/X86/switch_to_lookup_table.ll +++ b/llvm/test/Transforms/SimplifyCFG/X86/switch_to_lookup_table.ll @@ -1437,14 +1437,10 @@ ; CHECK-LABEL: @no_reuse_cmp2( ; CHECK-NEXT: entry: ; CHECK-NEXT: [[EC:%.*]] = icmp ne i32 [[Y:%.*]], 0 -; CHECK-NEXT: br i1 [[EC]], label [[SWITCH_ENTRY:%.*]], label [[SW_EPILOG:%.*]] -; CHECK: switch.entry: ; CHECK-NEXT: [[TMP0:%.*]] = icmp ult i32 [[X:%.*]], 4 ; CHECK-NEXT: [[SWITCH_OFFSET:%.*]] = add i32 [[X]], 10 ; CHECK-NEXT: [[SPEC_SELECT:%.*]] = select i1 [[TMP0]], i32 [[SWITCH_OFFSET]], i32 0 -; CHECK-NEXT: br label [[SW_EPILOG]] -; CHECK: sw.epilog: -; CHECK-NEXT: [[R_0:%.*]] = phi i32 [ 100, [[ENTRY:%.*]] ], [ [[SPEC_SELECT]], [[SWITCH_ENTRY]] ] +; CHECK-NEXT: [[R_0:%.*]] = select i1 [[EC]], i32 [[SPEC_SELECT]], i32 100 ; CHECK-NEXT: [[CMP:%.*]] = icmp eq i32 [[R_0]], 0 ; CHECK-NEXT: [[DOTR_0:%.*]] = select i1 [[CMP]], i32 100, i32 [[R_0]] ; CHECK-NEXT: ret i32 [[DOTR_0]] diff --git a/llvm/test/Transforms/SimplifyCFG/safe-abs.ll b/llvm/test/Transforms/SimplifyCFG/safe-abs.ll --- a/llvm/test/Transforms/SimplifyCFG/safe-abs.ll +++ b/llvm/test/Transforms/SimplifyCFG/safe-abs.ll @@ -8,14 +8,10 @@ ; CHECK-LABEL: @abs_with_clamp( ; CHECK-NEXT: begin: ; CHECK-NEXT: [[IS_POSITIVE:%.*]] = icmp sgt i32 [[ARG:%.*]], 0 -; CHECK-NEXT: br i1 [[IS_POSITIVE]], label [[END:%.*]], label [[NEGATIVE:%.*]] -; CHECK: negative: ; CHECK-NEXT: [[IS_INT_MIN:%.*]] = icmp eq i32 [[ARG]], -2147483648 ; CHECK-NEXT: [[NEGATED:%.*]] = sub nsw i32 0, [[ARG]] ; CHECK-NEXT: [[ABS:%.*]] = select i1 [[IS_INT_MIN]], i32 2147483647, i32 [[NEGATED]] -; CHECK-NEXT: br label [[END]] -; CHECK: end: -; CHECK-NEXT: [[TMP6:%.*]] = phi i32 [ [[ARG]], [[BEGIN:%.*]] ], [ [[ABS]], [[NEGATIVE]] ] +; CHECK-NEXT: [[TMP6:%.*]] = select i1 [[IS_POSITIVE]], i32 [[ARG]], i32 [[ABS]] ; CHECK-NEXT: ret i32 [[TMP6]] ; begin: diff --git a/llvm/test/Transforms/SimplifyCFG/safe-low-bit-extract.ll b/llvm/test/Transforms/SimplifyCFG/safe-low-bit-extract.ll --- a/llvm/test/Transforms/SimplifyCFG/safe-low-bit-extract.ll +++ b/llvm/test/Transforms/SimplifyCFG/safe-low-bit-extract.ll @@ -9,14 +9,10 @@ ; CHECK-LABEL: @extract_low_bits( ; CHECK-NEXT: begin: ; CHECK-NEXT: [[SHOULD_MASK:%.*]] = icmp ult i32 [[NBITS:%.*]], 32 -; CHECK-NEXT: br i1 [[SHOULD_MASK]], label [[PERFORM_MASKING:%.*]], label [[END:%.*]] -; CHECK: perform_masking: ; CHECK-NEXT: [[MASK_NOT:%.*]] = shl nsw i32 -1, [[NBITS]] ; CHECK-NEXT: [[MASK:%.*]] = xor i32 [[MASK_NOT]], -1 ; CHECK-NEXT: [[MASKED:%.*]] = and i32 [[MASK]], [[INPUT:%.*]] -; CHECK-NEXT: br label [[END]] -; CHECK: end: -; CHECK-NEXT: [[RES:%.*]] = phi i32 [ [[MASKED]], [[PERFORM_MASKING]] ], [ [[INPUT]], [[BEGIN:%.*]] ] +; CHECK-NEXT: [[RES:%.*]] = select i1 [[SHOULD_MASK]], i32 [[MASKED]], i32 [[INPUT]] ; CHECK-NEXT: ret i32 [[RES]] ; begin: diff --git a/llvm/test/Transforms/SimplifyCFG/signbit-like-value-extension.ll b/llvm/test/Transforms/SimplifyCFG/signbit-like-value-extension.ll --- a/llvm/test/Transforms/SimplifyCFG/signbit-like-value-extension.ll +++ b/llvm/test/Transforms/SimplifyCFG/signbit-like-value-extension.ll @@ -11,14 +11,10 @@ ; CHECK-NEXT: [[SKIPNBITS:%.*]] = sub i32 32, [[NBITS:%.*]] ; CHECK-NEXT: [[VALUE:%.*]] = lshr i32 [[STORAGE:%.*]], [[SKIPNBITS]] ; CHECK-NEXT: [[SHOULDEXTEND:%.*]] = icmp sgt i32 [[STORAGE]], -1 -; CHECK-NEXT: br i1 [[SHOULDEXTEND]], label [[EXTEND:%.*]], label [[END:%.*]] -; CHECK: extend: ; CHECK-NEXT: [[HIGHBITMASK:%.*]] = shl nsw i32 -1, [[NBITS]] ; CHECK-NEXT: [[HIGHBITMASKPLUSONE:%.*]] = add nsw i32 [[HIGHBITMASK]], 1 ; CHECK-NEXT: [[EXTENDED:%.*]] = add i32 [[HIGHBITMASKPLUSONE]], [[VALUE]] -; CHECK-NEXT: br label [[END]] -; CHECK: end: -; CHECK-NEXT: [[RES:%.*]] = phi i32 [ [[EXTENDED]], [[EXTEND]] ], [ [[VALUE]], [[BB:%.*]] ] +; CHECK-NEXT: [[RES:%.*]] = select i1 [[SHOULDEXTEND]], i32 [[EXTENDED]], i32 [[VALUE]] ; CHECK-NEXT: ret i32 [[RES]] ; bb: diff --git a/llvm/test/Transforms/SimplifyCFG/speculate-math.ll b/llvm/test/Transforms/SimplifyCFG/speculate-math.ll --- a/llvm/test/Transforms/SimplifyCFG/speculate-math.ll +++ b/llvm/test/Transforms/SimplifyCFG/speculate-math.ll @@ -12,23 +12,12 @@ declare float @llvm.maximum.f32(float, float) nounwind readonly define double @fdiv_test(double %a, double %b) { -; EXPENSIVE-LABEL: @fdiv_test( -; EXPENSIVE-NEXT: entry: -; EXPENSIVE-NEXT: [[CMP:%.*]] = fcmp ogt double [[A:%.*]], 0.000000e+00 -; EXPENSIVE-NEXT: [[DIV:%.*]] = fdiv double [[B:%.*]], [[A]] -; EXPENSIVE-NEXT: [[COND:%.*]] = select i1 [[CMP]], double [[DIV]], double 0.000000e+00 -; EXPENSIVE-NEXT: ret double [[COND]] -; -; CHEAP-LABEL: @fdiv_test( -; CHEAP-NEXT: entry: -; CHEAP-NEXT: [[CMP:%.*]] = fcmp ogt double [[A:%.*]], 0.000000e+00 -; CHEAP-NEXT: br i1 [[CMP]], label [[COND_TRUE:%.*]], label [[COND_END:%.*]] -; CHEAP: cond.true: -; CHEAP-NEXT: [[DIV:%.*]] = fdiv double [[B:%.*]], [[A]] -; CHEAP-NEXT: br label [[COND_END]] -; CHEAP: cond.end: -; CHEAP-NEXT: [[COND:%.*]] = phi double [ [[DIV]], [[COND_TRUE]] ], [ 0.000000e+00, [[ENTRY:%.*]] ] -; CHEAP-NEXT: ret double [[COND]] +; ALL-LABEL: @fdiv_test( +; ALL-NEXT: entry: +; ALL-NEXT: [[CMP:%.*]] = fcmp ogt double [[A:%.*]], 0.000000e+00 +; ALL-NEXT: [[DIV:%.*]] = fdiv double [[B:%.*]], [[A]] +; ALL-NEXT: [[COND:%.*]] = select i1 [[CMP]], double [[DIV]], double 0.000000e+00 +; ALL-NEXT: ret double [[COND]] ; entry: %cmp = fcmp ogt double %a, 0.0