The current `FoldTwoEntryPHINode()` is not quite designed correctly.
It starts from the merge point, and then tries to detect
the 'divergence' point.
Because of that, it is limited to the simple two-predecessor case,
where the PHI completely goes away. but that is rather pessimistic,
and it doesn't make much sense from the costmodel side of things.
For example if there is some other unrelated predecessor of
the merge point, we could split the merge point so that
the then/else blocks first branch to an empty block
and then to the merge point, and then we'd be able to speculate
the then/else code.
But if we'd instead simply start at the divergence point,
and look for the merge point, then we'll just natively support this case.
There's also the fact that `SpeculativelyExecuteBB()` already does
just that, but only if there is a single block to speculate,
and with a much more restrictive cost model.
But that also means we have code duplication.
Now, sadly, while this is as much NFCI as possible,
there is just no way to cleanly migrate to
the proper implementation. The results *are* going to be different
somewhat because of various phase ordering effects and SimplifyCFG
block iteration strategy.
return true;
}
+static bool SpeculativelyExecuteThenElseCode(BranchInst *BI,
+ const TargetTransformInfo &TTI,
+ DomTreeUpdater *DTU,
+ const DataLayout &DL) {
+ assert(BI->isConditional() && !isa<ConstantInt>(BI->getCondition()) &&
+ BI->getSuccessor(0) != BI->getSuccessor(1) &&
+ "Only for truly conditional branches.");
+ BasicBlock *BB = BI->getParent();
+
+ // Which ones of our successors end up with an unconditional branch?
+ SmallVector<BasicBlock *, 2> UncondSuccessors;
+ SmallVector<BasicBlock *, 2> OtherSuccessors;
+ for (BasicBlock *Succ : successors(BI)) {
+ auto *SuccBI = dyn_cast<BranchInst>(Succ->getTerminator());
+ if (SuccBI && SuccBI->isUnconditional())
+ UncondSuccessors.emplace_back(Succ);
+ else
+ OtherSuccessors.emplace_back(Succ);
+ }
+ assert(UncondSuccessors.size() + OtherSuccessors.size() == 2 &&
+ "Can not have more than two successors!");
+
+ // If none do, then we can't do anything.
+ if (UncondSuccessors.empty())
+ return false;
+
+ // We want to hoist code from the unconditional block[s] and eliminate them,
+ // but if they have their address taken, then we essentially can't do this.
+ for (BasicBlock *UncondSucc : UncondSuccessors)
+ if (UncondSucc->hasAddressTaken())
+ return false;
+
+ // All unconditional successors must have a single (and the same) predecessor.
+ // FIXME: lift this restriction.
+ for (BasicBlock *UncondSucc : UncondSuccessors)
+ if (!UncondSucc->getSinglePredecessor())
+ return false;
+
+ // Now, what is the merge point?
+ BasicBlock *MergeBB = nullptr;
+ // If there was only a single unconditional successor,
+ // then the other successor *must* be the merge point.
+ if (UncondSuccessors.size() == 1)
+ MergeBB = OtherSuccessors.front();
+
+ // All unconditional successors must have the same successor themselves.
+ for (BasicBlock *UncondSucc : UncondSuccessors) {
+ auto *SuccBI = cast<BranchInst>(UncondSucc->getTerminator());
+ assert(SuccBI->isUnconditional() && "Should be an unconditional branch.");
+ BasicBlock *SuccOfSucc = SuccBI->getSuccessor(0);
+ if (!MergeBB) // First unconditional successor, record it's successor.
+ MergeBB = SuccOfSucc;
+ else if (SuccOfSucc != MergeBB) // Do all succs have the same successor?
+ return false;
+ }
+
+ assert(MergeBB && "Should have found the merge point.");
+ assert(all_of(UncondSuccessors,
+ [MergeBB](BasicBlock *UncondSucc) {
+ return is_contained(predecessors(MergeBB), UncondSucc);
+ }) &&
+ "All unconditional successors must be predecessors of merge block.");
+ assert((UncondSuccessors.size() != 1 ||
+ is_contained(predecessors(MergeBB), BB)) &&
+ "If there is only a single unconditional successor, then the dispatch "
+ "block must also be merge block's predecessor.");
+
+ if (auto *PN = dyn_cast<PHINode>(MergeBB->begin()))
+ // FIXME: lift this restriction.
+ if (PN->getNumIncomingValues() == 2)
+ return FoldTwoEntryPHINode(PN, TTI, DTU, DL);
+
+ return false;
+}
+
static Value *createLogicalOp(IRBuilderBase &Builder,
Instruction::BinaryOps Opc, Value *LHS,
Value *RHS, const Twine &Name = "") {
return requestResimplify();
}
+ if (Options.FoldTwoEntryPHINode) {
+ if (SpeculativelyExecuteThenElseCode(BI, TTI, DTU, DL))
+ return true;
+ }
+
// If this is a branch on a phi node in the current block, thread control
// through this block if any PHI node entries are constants.
if (PHINode *PN = dyn_cast<PHINode>(BI->getCondition()))
IRBuilder<> Builder(BB);
- if (Options.FoldTwoEntryPHINode) {
- // If there is a trivial two-entry PHI node in this basic block, and we can
- // eliminate it, do so now.
- if (auto *PN = dyn_cast<PHINode>(BB->begin()))
- if (PN->getNumIncomingValues() == 2)
- if (FoldTwoEntryPHINode(PN, TTI, DTU, DL))
- return true;
- }
-
Instruction *Terminator = BB->getTerminator();
Builder.SetInsertPoint(Terminator);
switch (Terminator->getOpcode()) {
define i32 @f_i8_sign_extend_inreg(i8 %in, i32 %a, i32 %b) nounwind {
; CHECK-LABEL: f_i8_sign_extend_inreg:
; CHECK: // %bb.0: // %entry
-; CHECK-NEXT: sxtb w8, w0
-; CHECK-NEXT: cmp w8, #0
-; CHECK-NEXT: csel w8, w1, w2, ge
-; CHECK-NEXT: add w0, w8, w0, uxtb
+; CHECK-NEXT: and w8, w0, #0xff
+; CHECK-NEXT: sxtb w9, w0
+; CHECK-NEXT: add w10, w8, w1
+; CHECK-NEXT: add w8, w8, w2
+; CHECK-NEXT: cmp w9, #0
+; CHECK-NEXT: csel w0, w10, w8, ge
; CHECK-NEXT: ret
entry:
%cmp = icmp sgt i8 %in, -1
define i32 @f_i16_sign_extend_inreg(i16 %in, i32 %a, i32 %b) nounwind {
; CHECK-LABEL: f_i16_sign_extend_inreg:
; CHECK: // %bb.0: // %entry
-; CHECK-NEXT: sxth w8, w0
-; CHECK-NEXT: cmp w8, #0
-; CHECK-NEXT: csel w8, w1, w2, ge
-; CHECK-NEXT: add w0, w8, w0, uxth
+; CHECK-NEXT: and w8, w0, #0xffff
+; CHECK-NEXT: sxth w9, w0
+; CHECK-NEXT: add w10, w8, w1
+; CHECK-NEXT: add w8, w8, w2
+; CHECK-NEXT: cmp w9, #0
+; CHECK-NEXT: csel w0, w10, w8, ge
; CHECK-NEXT: ret
entry:
%cmp = icmp sgt i16 %in, -1
define i64 @f_i32_sign_extend_inreg(i32 %in, i64 %a, i64 %b) nounwind {
; CHECK-LABEL: f_i32_sign_extend_inreg:
; CHECK: // %bb.0: // %entry
+; CHECK-NEXT: mov w8, w0
; CHECK-NEXT: cmp w0, #0
-; CHECK-NEXT: csel x8, x1, x2, ge
-; CHECK-NEXT: add x0, x8, w0, uxtw
+; CHECK-NEXT: add x9, x8, x1
+; CHECK-NEXT: add x8, x8, x2
+; CHECK-NEXT: csel x0, x9, x8, ge
; CHECK-NEXT: ret
entry:
%cmp = icmp sgt i32 %in, -1
define i32 @g_i8_sign_extend_inreg(i8 %in, i32 %a, i32 %b) nounwind {
; CHECK-LABEL: g_i8_sign_extend_inreg:
; CHECK: // %bb.0: // %entry
-; CHECK-NEXT: sxtb w8, w0
-; CHECK-NEXT: cmp w8, #0
-; CHECK-NEXT: csel w8, w1, w2, lt
-; CHECK-NEXT: add w0, w8, w0, uxtb
+; CHECK-NEXT: and w8, w0, #0xff
+; CHECK-NEXT: sxtb w9, w0
+; CHECK-NEXT: add w10, w8, w1
+; CHECK-NEXT: add w8, w8, w2
+; CHECK-NEXT: cmp w9, #0
+; CHECK-NEXT: csel w0, w10, w8, lt
; CHECK-NEXT: ret
entry:
%cmp = icmp slt i8 %in, 0
define i32 @g_i16_sign_extend_inreg(i16 %in, i32 %a, i32 %b) nounwind {
; CHECK-LABEL: g_i16_sign_extend_inreg:
; CHECK: // %bb.0: // %entry
-; CHECK-NEXT: sxth w8, w0
-; CHECK-NEXT: cmp w8, #0
-; CHECK-NEXT: csel w8, w1, w2, lt
-; CHECK-NEXT: add w0, w8, w0, uxth
+; CHECK-NEXT: and w8, w0, #0xffff
+; CHECK-NEXT: sxth w9, w0
+; CHECK-NEXT: add w10, w8, w1
+; CHECK-NEXT: add w8, w8, w2
+; CHECK-NEXT: cmp w9, #0
+; CHECK-NEXT: csel w0, w10, w8, lt
; CHECK-NEXT: ret
entry:
%cmp = icmp slt i16 %in, 0
define i64 @g_i32_sign_extend_inreg(i32 %in, i64 %a, i64 %b) nounwind {
; CHECK-LABEL: g_i32_sign_extend_inreg:
; CHECK: // %bb.0: // %entry
+; CHECK-NEXT: mov w8, w0
; CHECK-NEXT: cmp w0, #0
-; CHECK-NEXT: csel x8, x1, x2, lt
-; CHECK-NEXT: add x0, x8, w0, uxtw
+; CHECK-NEXT: add x9, x8, x1
+; CHECK-NEXT: add x8, x8, x2
+; CHECK-NEXT: csel x0, x9, x8, lt
; CHECK-NEXT: ret
entry:
%cmp = icmp slt i32 %in, 0
; CHECK-LABEL: f_i32_sign_extend_i64:
; CHECK: // %bb.0: // %entry
; CHECK-NEXT: // kill: def $w0 killed $w0 def $x0
-; CHECK-NEXT: sxtw x8, w0
-; CHECK-NEXT: cmp x8, #0
-; CHECK-NEXT: csel x8, x1, x2, ge
-; CHECK-NEXT: add x0, x8, w0, uxtw
+; CHECK-NEXT: mov w8, w0
+; CHECK-NEXT: sxtw x9, w0
+; CHECK-NEXT: add x10, x8, x1
+; CHECK-NEXT: add x8, x8, x2
+; CHECK-NEXT: cmp x9, #0
+; CHECK-NEXT: csel x0, x10, x8, ge
; CHECK-NEXT: ret
entry:
%inext = sext i32 %in to i64
; CHECK-LABEL: g_i32_sign_extend_i64:
; CHECK: // %bb.0: // %entry
; CHECK-NEXT: // kill: def $w0 killed $w0 def $x0
-; CHECK-NEXT: sxtw x8, w0
-; CHECK-NEXT: cmp x8, #0
-; CHECK-NEXT: csel x8, x1, x2, lt
-; CHECK-NEXT: add x0, x8, w0, uxtw
+; CHECK-NEXT: mov w8, w0
+; CHECK-NEXT: sxtw x9, w0
+; CHECK-NEXT: add x10, x8, x1
+; CHECK-NEXT: add x8, x8, x2
+; CHECK-NEXT: cmp x9, #0
+; CHECK-NEXT: csel x0, x10, x8, lt
; CHECK-NEXT: ret
entry:
%inext = sext i32 %in to i64
; CHECK-NEXT: cbz x8, .LBB9_3
; CHECK-NEXT: // %bb.2:
; CHECK-NEXT: mov w0, #3
-; CHECK-NEXT: b .LBB9_4
+; CHECK-NEXT: b .LBB9_6
; CHECK-NEXT: .LBB9_3: // %if.end
; CHECK-NEXT: mov w0, #1
; CHECK-NEXT: bl zoo
; CHECK-NEXT: cinc w0, w19, gt
; CHECK-NEXT: fmov d8, d0
; CHECK-NEXT: bl xoo
-; CHECK-NEXT: fmov d0, #-1.00000000
; CHECK-NEXT: fcmp d8, #0.0
+; CHECK-NEXT: b.gt .LBB9_5
+; CHECK-NEXT: // %bb.4: // %cond.false12
+; CHECK-NEXT: fmov d0, #-1.00000000
+; CHECK-NEXT: fadd d8, d8, d0
+; CHECK-NEXT: .LBB9_5: // %cond.end14
+; CHECK-NEXT: fmov d0, d8
; CHECK-NEXT: fmov d1, #-2.00000000
-; CHECK-NEXT: fadd d0, d8, d0
-; CHECK-NEXT: fcsel d0, d8, d0, gt
; CHECK-NEXT: bl woo
; CHECK-NEXT: mov w0, #4
-; CHECK-NEXT: .LBB9_4: // %return
+; CHECK-NEXT: .LBB9_6: // %return
; CHECK-NEXT: ldp x30, x19, [sp, #16] // 16-byte Folded Reload
; CHECK-NEXT: ldr d8, [sp], #32 // 8-byte Folded Reload
; CHECK-NEXT: ret
; CHECK-LABEL: phi_i16:
; CHECK: // %bb.0: // %entry
; CHECK-NEXT: mov w8, wzr
-; CHECK-NEXT: mov w9, #1
; CHECK-NEXT: .LBB2_1: // %loop
; CHECK-NEXT: // =>This Inner Loop Header: Depth=1
+; CHECK-NEXT: add w9, w8, #2
; CHECK-NEXT: cmp w8, #128
-; CHECK-NEXT: cinc w10, w9, lo
-; CHECK-NEXT: add w8, w8, w10
+; CHECK-NEXT: csinc w8, w9, w8, lo
; CHECK-NEXT: cmp w8, #253
; CHECK-NEXT: b.lo .LBB2_1
; CHECK-NEXT: // %bb.2: // %exit
; CHECK-LABEL: ret_i8:
; CHECK: // %bb.0: // %entry
; CHECK-NEXT: mov w0, wzr
-; CHECK-NEXT: mov w8, #1
; CHECK-NEXT: .LBB3_1: // %loop
; CHECK-NEXT: // =>This Inner Loop Header: Depth=1
+; CHECK-NEXT: add w8, w0, #2
; CHECK-NEXT: cmp w0, #128
-; CHECK-NEXT: cinc w9, w8, lo
-; CHECK-NEXT: add w0, w0, w9
+; CHECK-NEXT: csinc w0, w8, w0, lo
; CHECK-NEXT: cmp w0, #252
; CHECK-NEXT: b.hi .LBB3_1
; CHECK-NEXT: // %bb.2: // %exit
define i16 @phi_multiple_undefs(i16 zeroext %arg) {
; CHECK-LABEL: phi_multiple_undefs:
; CHECK: // %bb.0: // %entry
-; CHECK-NEXT: mov w8, #1
-; CHECK-NEXT: // implicit-def: $w9
+; CHECK-NEXT: // implicit-def: $w8
; CHECK-NEXT: .LBB4_1: // %loop
; CHECK-NEXT: // =>This Inner Loop Header: Depth=1
-; CHECK-NEXT: cmp w9, #128
-; CHECK-NEXT: cinc w10, w8, lo
-; CHECK-NEXT: add w9, w9, w10
-; CHECK-NEXT: cmp w9, #253
+; CHECK-NEXT: add w9, w8, #2
+; CHECK-NEXT: cmp w8, #128
+; CHECK-NEXT: csinc w8, w9, w8, lo
+; CHECK-NEXT: cmp w8, #253
; CHECK-NEXT: b.lo .LBB4_1
; CHECK-NEXT: // %bb.2: // %exit
; CHECK-NEXT: ret
define i32 @test_ifcvt(i32 %a, i32 %b) #0 {
; CHECK-LABEL: test_ifcvt:
; CHECK: @ %bb.0: @ %common.ret
-; CHECK-NEXT: movs r2, #1
+; CHECK-NEXT: adds r2, r1, #1
; CHECK-NEXT: cmp r0, #0
; CHECK-NEXT: it eq
-; CHECK-NEXT: moveq.w r2, #-1
-; CHECK-NEXT: adds r0, r1, r2
+; CHECK-NEXT: subeq r2, r1, #1
+; CHECK-NEXT: mov r0, r2
; CHECK-NEXT: bx lr
%tmp2 = icmp eq i32 %a, 0
br i1 %tmp2, label %cond_false, label %cond_true
define i32 @t1(i32 %a, i32 %b) {
; A8-LABEL: t1:
; A8: @ %bb.0: @ %common.ret
-; A8-NEXT: mov r2, #1
+; A8-NEXT: add r2, r1, #1
; A8-NEXT: cmp r0, #0
-; A8-NEXT: mvneq r2, #0
-; A8-NEXT: add r0, r1, r2
+; A8-NEXT: subeq r2, r1, #1
+; A8-NEXT: mov r0, r2
; A8-NEXT: bx lr
;
; SWIFT-LABEL: t1:
; SWIFT: @ %bb.0: @ %common.ret
-; SWIFT-NEXT: mov r2, #1
+; SWIFT-NEXT: add r2, r1, #1
; SWIFT-NEXT: cmp r0, #0
-; SWIFT-NEXT: mvneq r2, #0
-; SWIFT-NEXT: add r0, r1, r2
+; SWIFT-NEXT: subeq r2, r1, #1
+; SWIFT-NEXT: mov r0, r2
; SWIFT-NEXT: bx lr
%tmp2 = icmp eq i32 %a, 0
br i1 %tmp2, label %cond_false, label %cond_true
; CHECK-NEXT: [[SUM2_NONCHR:%.*]] = select i1 [[TMP10]], i32 [[SUM1_NONCHR]], i32 [[TMP11]], !prof [[PROF16]]
; CHECK-NEXT: [[TMP12:%.*]] = and i32 [[TMP0]], 4
; CHECK-NEXT: [[TMP13:%.*]] = icmp eq i32 [[TMP12]], 0
+; CHECK-NEXT: br i1 [[TMP13]], label [[BB3]], label [[BB1_NONCHR:%.*]], !prof [[PROF16]]
+; CHECK: bb1.nonchr:
; CHECK-NEXT: [[TMP14:%.*]] = and i32 [[TMP0]], 8
; CHECK-NEXT: [[TMP15:%.*]] = icmp eq i32 [[TMP14]], 0
-; CHECK-NEXT: [[SUM4_NONCHR_V:%.*]] = select i1 [[TMP15]], i32 44, i32 88
+; CHECK-NEXT: [[SUM4_NONCHR_V:%.*]] = select i1 [[TMP15]], i32 44, i32 88, !prof [[PROF16]]
; CHECK-NEXT: [[SUM4_NONCHR:%.*]] = add i32 [[SUM2_NONCHR]], [[SUM4_NONCHR_V]]
-; CHECK-NEXT: [[SUM5_NONCHR:%.*]] = select i1 [[TMP13]], i32 [[SUM2_NONCHR]], i32 [[SUM4_NONCHR]], !prof [[PROF16]]
; CHECK-NEXT: br label [[BB3]]
; CHECK: bb3:
-; CHECK-NEXT: [[SUM6:%.*]] = phi i32 [ [[TMP4]], [[BB0]] ], [ [[SUM0]], [[ENTRY_SPLIT_NONCHR]] ], [ [[SUM5_NONCHR]], [[BB0_NONCHR]] ]
+; CHECK-NEXT: [[SUM6:%.*]] = phi i32 [ [[TMP4]], [[BB0]] ], [ [[SUM0]], [[ENTRY_SPLIT_NONCHR]] ], [ [[SUM2_NONCHR]], [[BB0_NONCHR]] ], [ [[SUM4_NONCHR]], [[BB1_NONCHR]] ]
; CHECK-NEXT: ret i32 [[SUM6]]
;
entry:
; CHECK-NEXT: [[SUM2_NONCHR:%.*]] = select i1 [[TMP13]], i32 [[SUM1_NONCHR]], i32 [[TMP14]], !prof [[PROF16]]
; CHECK-NEXT: [[TMP15:%.*]] = and i32 [[SUM0]], 4
; CHECK-NEXT: [[TMP16:%.*]] = icmp eq i32 [[TMP15]], 0
+; CHECK-NEXT: br i1 [[TMP16]], label [[BB3]], label [[BB1_NONCHR:%.*]], !prof [[PROF16]]
+; CHECK: bb1.nonchr:
; CHECK-NEXT: [[TMP17:%.*]] = and i32 [[TMP0]], 8
; CHECK-NEXT: [[TMP18:%.*]] = icmp eq i32 [[TMP17]], 0
-; CHECK-NEXT: [[SUM4_NONCHR_V:%.*]] = select i1 [[TMP18]], i32 44, i32 88
+; CHECK-NEXT: [[SUM4_NONCHR_V:%.*]] = select i1 [[TMP18]], i32 44, i32 88, !prof [[PROF16]]
; CHECK-NEXT: [[SUM4_NONCHR:%.*]] = add i32 [[SUM2_NONCHR]], [[SUM4_NONCHR_V]]
-; CHECK-NEXT: [[SUM5_NONCHR:%.*]] = select i1 [[TMP16]], i32 [[SUM2_NONCHR]], i32 [[SUM4_NONCHR]], !prof [[PROF16]]
; CHECK-NEXT: br label [[BB3]]
; CHECK: bb3:
-; CHECK-NEXT: [[SUM6:%.*]] = phi i32 [ [[TMP7]], [[BB0]] ], [ [[SUM0]], [[ENTRY_SPLIT_NONCHR]] ], [ [[SUM5_NONCHR]], [[BB0_NONCHR]] ]
+; CHECK-NEXT: [[SUM6:%.*]] = phi i32 [ [[TMP7]], [[BB0]] ], [ [[SUM0]], [[ENTRY_SPLIT_NONCHR]] ], [ [[SUM2_NONCHR]], [[BB0_NONCHR]] ], [ [[SUM4_NONCHR]], [[BB1_NONCHR]] ]
; CHECK-NEXT: ret i32 [[SUM6]]
;
entry:
; CHECK-NEXT: [[SUM2_NONCHR:%.*]] = select i1 [[V4_NONCHR]], i32 [[SUM0]], i32 [[V8_NONCHR]], !prof [[PROF16]]
; CHECK-NEXT: [[V9_NONCHR:%.*]] = and i32 [[J0]], 4
; CHECK-NEXT: [[V10_NONCHR:%.*]] = icmp eq i32 [[V9_NONCHR]], 0
+; CHECK-NEXT: br i1 [[V10_NONCHR]], label [[BB3]], label [[BB1_NONCHR:%.*]], !prof [[PROF16]]
+; CHECK: bb1.nonchr:
; CHECK-NEXT: [[V11_NONCHR:%.*]] = and i32 [[I0]], 8
; CHECK-NEXT: [[V12_NONCHR:%.*]] = icmp eq i32 [[V11_NONCHR]], 0
-; CHECK-NEXT: [[SUM4_NONCHR_V:%.*]] = select i1 [[V12_NONCHR]], i32 44, i32 88
+; CHECK-NEXT: [[SUM4_NONCHR_V:%.*]] = select i1 [[V12_NONCHR]], i32 44, i32 88, !prof [[PROF16]]
; CHECK-NEXT: [[SUM4_NONCHR:%.*]] = add i32 [[SUM2_NONCHR]], [[SUM4_NONCHR_V]]
-; CHECK-NEXT: [[SUM5_NONCHR:%.*]] = select i1 [[V10_NONCHR]], i32 [[SUM2_NONCHR]], i32 [[SUM4_NONCHR]], !prof [[PROF16]]
; CHECK-NEXT: br label [[BB3]]
; CHECK: bb3:
-; CHECK-NEXT: [[SUM6:%.*]] = phi i32 [ [[V13]], [[BB0]] ], [ [[SUM0]], [[ENTRY_SPLIT_NONCHR]] ], [ [[SUM5_NONCHR]], [[BB0_NONCHR]] ]
+; CHECK-NEXT: [[SUM6:%.*]] = phi i32 [ [[V13]], [[BB0]] ], [ [[SUM0]], [[ENTRY_SPLIT_NONCHR]] ], [ [[SUM2_NONCHR]], [[BB0_NONCHR]] ], [ [[SUM4_NONCHR]], [[BB1_NONCHR]] ]
; CHECK-NEXT: ret i32 [[SUM6]]
;
entry:
; CHECK-NEXT: [[TMP7:%.*]] = icmp eq i32 [[TMP6]], 0
; CHECK-NEXT: [[TMP8:%.*]] = add i32 [[SUM0]], 85
; CHECK-NEXT: [[SUM2_NONCHR:%.*]] = select i1 [[TMP7]], i32 [[SUM0]], i32 [[TMP8]], !prof [[PROF16]]
+; CHECK-NEXT: br i1 [[TMP7]], label [[BB3]], label [[BB1_NONCHR:%.*]], !prof [[PROF16]]
+; CHECK: bb1.nonchr:
; CHECK-NEXT: [[TMP9:%.*]] = and i32 [[TMP0]], 8
; CHECK-NEXT: [[TMP10:%.*]] = icmp eq i32 [[TMP9]], 0
-; CHECK-NEXT: [[SUM4_NONCHR_V:%.*]] = select i1 [[TMP10]], i32 44, i32 88
+; CHECK-NEXT: [[SUM4_NONCHR_V:%.*]] = select i1 [[TMP10]], i32 44, i32 88, !prof [[PROF16]]
; CHECK-NEXT: [[SUM4_NONCHR:%.*]] = add i32 [[SUM2_NONCHR]], [[SUM4_NONCHR_V]]
-; CHECK-NEXT: [[SUM5_NONCHR:%.*]] = select i1 [[TMP7]], i32 [[SUM2_NONCHR]], i32 [[SUM4_NONCHR]], !prof [[PROF16]]
; CHECK-NEXT: br label [[BB3]]
; CHECK: bb3:
-; CHECK-NEXT: [[SUM6:%.*]] = phi i32 [ [[TMP4]], [[BB0]] ], [ [[SUM0]], [[ENTRY_SPLIT_NONCHR]] ], [ [[SUM5_NONCHR]], [[BB0_NONCHR]] ]
+; CHECK-NEXT: [[SUM6:%.*]] = phi i32 [ [[TMP4]], [[BB0]] ], [ [[SUM0]], [[ENTRY_SPLIT_NONCHR]] ], [ [[SUM2_NONCHR]], [[BB0_NONCHR]] ], [ [[SUM4_NONCHR]], [[BB1_NONCHR]] ]
; CHECK-NEXT: ret i32 [[SUM6]]
;
entry:
; ALL-LABEL: @foo(
; ALL-NEXT: entry:
; ALL-NEXT: [[TOBOOL_NOT:%.*]] = icmp eq i32 [[ISHI:%.*]], 0
-; ALL-NEXT: [[LO_HI:%.*]] = select i1 [[TOBOOL_NOT]], i64 [[LO:%.*]], i64 [[HI:%.*]]
-; ALL-NEXT: [[ARRAYIDX1:%.*]] = getelementptr inbounds i32, i32* [[IN:%.*]], i64 [[LO_HI]]
-; ALL-NEXT: [[ARRAYVAL2:%.*]] = load i32, i32* [[ARRAYIDX1]], align 4
+; ALL-NEXT: [[ARRAYIDX1:%.*]] = getelementptr inbounds i32, i32* [[IN:%.*]], i64 [[LO:%.*]]
+; ALL-NEXT: [[ARRAYIDX:%.*]] = getelementptr inbounds i32, i32* [[IN]], i64 [[HI:%.*]]
+; ALL-NEXT: [[ARRAYIDX1_SINK1:%.*]] = select i1 [[TOBOOL_NOT]], i32* [[ARRAYIDX1]], i32* [[ARRAYIDX]]
+; ALL-NEXT: [[ARRAYIDX1_SINK:%.*]] = select i1 [[TOBOOL_NOT]], i32* [[ARRAYIDX1]], i32* [[ARRAYIDX]]
+; ALL-NEXT: [[ARRAYVAL2:%.*]] = load i32, i32* [[ARRAYIDX1_SINK1]], align 4
; ALL-NEXT: [[INC2:%.*]] = add nsw i32 [[ARRAYVAL2]], 1
-; ALL-NEXT: store i32 [[INC2]], i32* [[ARRAYIDX1]], align 4
+; ALL-NEXT: store i32 [[INC2]], i32* [[ARRAYIDX1_SINK]], align 4
; ALL-NEXT: ret void
;
entry:
define i1 @test1(i32 %c) {
; CHECK-LABEL: @test1(
; CHECK-NEXT: entry:
-; CHECK-NEXT: [[SWITCH_TABLEIDX:%.*]] = add i32 [[C:%.*]], -100
-; CHECK-NEXT: [[TMP0:%.*]] = icmp ult i32 [[SWITCH_TABLEIDX]], 20
-; CHECK-NEXT: [[SWITCH_CAST:%.*]] = trunc i32 [[SWITCH_TABLEIDX]] to i20
-; CHECK-NEXT: [[SWITCH_DOWNSHIFT:%.*]] = lshr i20 -490991, [[SWITCH_CAST]]
-; CHECK-NEXT: [[TMP1:%.*]] = and i20 [[SWITCH_DOWNSHIFT]], 1
-; CHECK-NEXT: [[SWITCH_MASKED:%.*]] = icmp ne i20 [[TMP1]], 0
-; CHECK-NEXT: [[I_0:%.*]] = select i1 [[TMP0]], i1 [[SWITCH_MASKED]], i1 false
-; CHECK-NEXT: ret i1 [[I_0]]
+; CHECK-NEXT: [[SWITCH_TABLEIDX:%.*]] = add i32 [[C:%.*]], -104
+; CHECK-NEXT: [[TMP0:%.*]] = icmp ult i32 [[SWITCH_TABLEIDX]], 12
+; CHECK-NEXT: [[SWITCH_CAST:%.*]] = trunc i32 [[SWITCH_TABLEIDX]] to i12
+; CHECK-NEXT: [[SWITCH_DOWNSHIFT:%.*]] = lshr i12 -2015, [[SWITCH_CAST]]
+; CHECK-NEXT: [[TMP1:%.*]] = and i12 [[SWITCH_DOWNSHIFT]], 1
+; CHECK-NEXT: [[SWITCH_MASKED:%.*]] = icmp ne i12 [[TMP1]], 0
+; CHECK-NEXT: [[_3_0:%.*]] = select i1 [[TMP0]], i1 [[SWITCH_MASKED]], i1 false
+; CHECK-NEXT: [[_10:%.*]] = icmp eq i32 [[C]], 100
+; CHECK-NEXT: [[_2_0:%.*]] = select i1 [[_3_0]], i1 true, i1 [[_10]]
+; CHECK-NEXT: [[_12:%.*]] = icmp eq i32 [[C]], 119
+; CHECK-NEXT: [[SPEC_SELECT:%.*]] = select i1 [[_2_0]], i1 true, i1 [[_12]]
+; CHECK-NEXT: ret i1 [[SPEC_SELECT]]
;
entry:
%_4 = alloca i8, align 1
define i1 @test2(i32 %c) {
; CHECK-LABEL: @test2(
-; CHECK-NEXT: [[TMP2:%.*]] = tail call i1 @test1(i32 [[TMP0:%.*]]) #[[ATTR0:[0-9]+]]
-; CHECK-NEXT: ret i1 [[TMP2]]
+; CHECK-NEXT: entry:
+; CHECK-NEXT: [[SWITCH_TABLEIDX:%.*]] = add i32 [[C:%.*]], -100
+; CHECK-NEXT: [[TMP0:%.*]] = icmp ult i32 [[SWITCH_TABLEIDX]], 20
+; CHECK-NEXT: [[SWITCH_CAST:%.*]] = trunc i32 [[SWITCH_TABLEIDX]] to i20
+; CHECK-NEXT: [[SWITCH_DOWNSHIFT:%.*]] = lshr i20 -490991, [[SWITCH_CAST]]
+; CHECK-NEXT: [[TMP1:%.*]] = and i20 [[SWITCH_DOWNSHIFT]], 1
+; CHECK-NEXT: [[SWITCH_MASKED:%.*]] = icmp ne i20 [[TMP1]], 0
+; CHECK-NEXT: [[I_0:%.*]] = select i1 [[TMP0]], i1 [[SWITCH_MASKED]], i1 false
+; CHECK-NEXT: ret i1 [[I_0]]
;
entry:
%i = alloca i8, align 1
define void @test5(i1 %cond, i8* %ptr) {
; CHECK-LABEL: @test5(
; CHECK-NEXT: entry:
-; CHECK-NEXT: [[TMP0:%.*]] = xor i1 [[COND:%.*]], true
-; CHECK-NEXT: call void @llvm.assume(i1 [[TMP0]])
-; CHECK-NEXT: store i8 2, i8* [[PTR:%.*]], align 8
+; CHECK-NEXT: [[PTR_2:%.*]] = select i1 [[COND:%.*]], i8* null, i8* [[PTR:%.*]]
+; CHECK-NEXT: store i8 2, i8* [[PTR_2]], align 8
; CHECK-NEXT: ret void
;
entry:
define void @test5_type_test_assume(i1 %cond, i8* %ptr, [3 x i8*]* %vtable) {
; CHECK-LABEL: @test5_type_test_assume(
; CHECK-NEXT: entry:
-; CHECK-NEXT: [[TMP0:%.*]] = xor i1 [[COND:%.*]], true
-; CHECK-NEXT: call void @llvm.assume(i1 [[TMP0]])
+; CHECK-NEXT: [[PTR_2:%.*]] = select i1 [[COND:%.*]], i8* null, i8* [[PTR:%.*]]
; CHECK-NEXT: [[VTABLEI8:%.*]] = bitcast [3 x i8*]* [[VTABLE:%.*]] to i8*
; CHECK-NEXT: [[P:%.*]] = call i1 @llvm.type.test(i8* [[VTABLEI8]], metadata !"foo")
; CHECK-NEXT: tail call void @llvm.assume(i1 [[P]])
-; CHECK-NEXT: store i8 2, i8* [[PTR:%.*]], align 8
+; CHECK-NEXT: store i8 2, i8* [[PTR_2]], align 8
; CHECK-NEXT: ret void
;
entry:
define void @test6(i1 %cond, i8* %ptr) {
; CHECK-LABEL: @test6(
; CHECK-NEXT: entry:
-; CHECK-NEXT: [[TMP0:%.*]] = xor i1 [[COND:%.*]], true
-; CHECK-NEXT: call void @llvm.assume(i1 [[TMP0]])
-; CHECK-NEXT: store i8 2, i8* [[PTR:%.*]], align 8
+; CHECK-NEXT: [[PTR_2:%.*]] = select i1 [[COND:%.*]], i8* null, i8* [[PTR:%.*]]
+; CHECK-NEXT: store i8 2, i8* [[PTR_2]], align 8
; CHECK-NEXT: ret void
;
entry:
define void @test8(i1 %X, void ()* %Y) {
; CHECK-LABEL: @test8(
; CHECK-NEXT: entry:
-; CHECK-NEXT: [[TMP0:%.*]] = xor i1 [[X:%.*]], true
-; CHECK-NEXT: call void @llvm.assume(i1 [[TMP0]])
-; CHECK-NEXT: call void [[Y:%.*]]()
+; CHECK-NEXT: [[PHI:%.*]] = select i1 [[X:%.*]], void ()* null, void ()* [[Y:%.*]]
+; CHECK-NEXT: call void [[PHI]]()
; CHECK-NEXT: ret void
;
entry:
define void @test9(i1 %X, i8* %Y) {
; CHECK-LABEL: @test9(
; CHECK-NEXT: entry:
-; CHECK-NEXT: [[TMP0:%.*]] = xor i1 [[X:%.*]], true
-; CHECK-NEXT: call void @llvm.assume(i1 [[TMP0]])
-; CHECK-NEXT: [[TMP1:%.*]] = call i8* @fn_nonnull_noundef_arg(i8* [[Y:%.*]])
+; CHECK-NEXT: [[PHI:%.*]] = select i1 [[X:%.*]], i8* null, i8* [[Y:%.*]]
+; CHECK-NEXT: [[TMP0:%.*]] = call i8* @fn_nonnull_noundef_arg(i8* [[PHI]])
; CHECK-NEXT: ret void
;
entry:
define void @test9_deref(i1 %X, i8* %Y) {
; CHECK-LABEL: @test9_deref(
; CHECK-NEXT: entry:
-; CHECK-NEXT: [[TMP0:%.*]] = xor i1 [[X:%.*]], true
-; CHECK-NEXT: call void @llvm.assume(i1 [[TMP0]])
-; CHECK-NEXT: [[TMP1:%.*]] = call i8* @fn_nonnull_deref_arg(i8* [[Y:%.*]])
+; CHECK-NEXT: [[PHI:%.*]] = select i1 [[X:%.*]], i8* null, i8* [[Y:%.*]]
+; CHECK-NEXT: [[TMP0:%.*]] = call i8* @fn_nonnull_deref_arg(i8* [[PHI]])
; CHECK-NEXT: ret void
;
entry:
define void @test9_deref_or_null(i1 %X, i8* %Y) {
; CHECK-LABEL: @test9_deref_or_null(
; CHECK-NEXT: entry:
-; CHECK-NEXT: [[TMP0:%.*]] = xor i1 [[X:%.*]], true
-; CHECK-NEXT: call void @llvm.assume(i1 [[TMP0]])
-; CHECK-NEXT: [[TMP1:%.*]] = call i8* @fn_nonnull_deref_or_null_arg(i8* [[Y:%.*]])
+; CHECK-NEXT: [[PHI:%.*]] = select i1 [[X:%.*]], i8* null, i8* [[Y:%.*]]
+; CHECK-NEXT: [[TMP0:%.*]] = call i8* @fn_nonnull_deref_or_null_arg(i8* [[PHI]])
; CHECK-NEXT: ret void
;
entry:
define void @test9_null_callsite(i1 %X, i8* %Y) {
; CHECK-LABEL: @test9_null_callsite(
; CHECK-NEXT: entry:
-; CHECK-NEXT: [[TMP0:%.*]] = xor i1 [[X:%.*]], true
-; CHECK-NEXT: call void @llvm.assume(i1 [[TMP0]])
-; CHECK-NEXT: [[TMP1:%.*]] = call i8* @fn_nonnull_arg(i8* noundef nonnull [[Y:%.*]])
+; CHECK-NEXT: [[PHI:%.*]] = select i1 [[X:%.*]], i8* null, i8* [[Y:%.*]]
+; CHECK-NEXT: [[TMP0:%.*]] = call i8* @fn_nonnull_arg(i8* noundef nonnull [[PHI]])
; CHECK-NEXT: ret void
;
entry:
define void @test9_gep_zero(i1 %X, i8* %Y) {
; CHECK-LABEL: @test9_gep_zero(
; CHECK-NEXT: entry:
-; CHECK-NEXT: [[TMP0:%.*]] = xor i1 [[X:%.*]], true
-; CHECK-NEXT: call void @llvm.assume(i1 [[TMP0]])
-; CHECK-NEXT: [[GEP:%.*]] = getelementptr inbounds i8, i8* [[Y:%.*]], i64 0
-; CHECK-NEXT: [[TMP1:%.*]] = call i8* @fn_nonnull_noundef_arg(i8* [[GEP]])
+; CHECK-NEXT: [[PHI:%.*]] = select i1 [[X:%.*]], i8* null, i8* [[Y:%.*]]
+; CHECK-NEXT: [[GEP:%.*]] = getelementptr inbounds i8, i8* [[PHI]], i64 0
+; CHECK-NEXT: [[TMP0:%.*]] = call i8* @fn_nonnull_noundef_arg(i8* [[GEP]])
; CHECK-NEXT: ret void
;
entry:
define void @test9_gep_bitcast(i1 %X, i32* %Y) {
; CHECK-LABEL: @test9_gep_bitcast(
; CHECK-NEXT: entry:
-; CHECK-NEXT: [[TMP0:%.*]] = xor i1 [[X:%.*]], true
-; CHECK-NEXT: call void @llvm.assume(i1 [[TMP0]])
-; CHECK-NEXT: [[GEP:%.*]] = getelementptr inbounds i32, i32* [[Y:%.*]], i64 0
+; CHECK-NEXT: [[PHI:%.*]] = select i1 [[X:%.*]], i32* null, i32* [[Y:%.*]]
+; CHECK-NEXT: [[GEP:%.*]] = getelementptr inbounds i32, i32* [[PHI]], i64 0
; CHECK-NEXT: [[BC:%.*]] = bitcast i32* [[GEP]] to i8*
-; CHECK-NEXT: [[TMP1:%.*]] = call i8* @fn_nonnull_noundef_arg(i8* [[BC]])
+; CHECK-NEXT: [[TMP0:%.*]] = call i8* @fn_nonnull_noundef_arg(i8* [[BC]])
; CHECK-NEXT: ret void
;
entry:
define i32 @test_insertvalue(i1 zeroext %flag, %TP %P) {
; CHECK-LABEL: @test_insertvalue(
; CHECK-NEXT: entry:
-; CHECK-NEXT: [[DOT:%.*]] = select i1 [[FLAG:%.*]], i32 0, i32 1
-; CHECK-NEXT: [[I2:%.*]] = insertvalue [[TP:%.*]] [[P:%.*]], i32 [[DOT]], 0
+; CHECK-NEXT: [[I1:%.*]] = insertvalue [[TP:%.*]] [[P:%.*]], i32 0, 0
+; CHECK-NEXT: [[I2:%.*]] = insertvalue [[TP]] [[P]], i32 1, 0
+; CHECK-NEXT: [[I:%.*]] = select i1 [[FLAG:%.*]], [[TP]] [[I1]], [[TP]] [[I2]]
; CHECK-NEXT: ret i32 1
;
entry:
define i16 @_Z7test_itv() {
; CHECK-LABEL: @_Z7test_itv(
; CHECK-NEXT: entry:
-; CHECK-NEXT: [[RETVAL_0:%.*]] = select i1 undef, i16 1, i16 0
+; CHECK-NEXT: [[SPEC_SELECT:%.*]] = select i1 undef, i16 1, i16 0
; CHECK-NEXT: ret i16 0
;
entry:
; CHECK-NEXT: [[AND:%.*]] = and i32 [[TMP0]], 1
; CHECK-NEXT: [[TOBOOL:%.*]] = icmp eq i32 [[AND]], 0
; CHECK-NEXT: [[OR:%.*]] = or i32 [[TMP0]], -2147483648
-; CHECK-NEXT: [[TMP1:%.*]] = select i1 [[TOBOOL]], i32 [[TMP0]], i32 [[OR]]
-; CHECK-NEXT: [[AND1:%.*]] = and i32 [[TMP1]], 2
+; CHECK-NEXT: [[SPEC_SELECT15:%.*]] = select i1 [[TOBOOL]], i32 [[TMP0]], i32 [[OR]]
+; CHECK-NEXT: [[AND1:%.*]] = and i32 [[SPEC_SELECT15]], 2
; CHECK-NEXT: [[TOBOOL2:%.*]] = icmp eq i32 [[AND1]], 0
-; CHECK-NEXT: [[OR4:%.*]] = or i32 [[TMP1]], 1073741824
-; CHECK-NEXT: [[TMP2:%.*]] = select i1 [[TOBOOL2]], i32 [[TMP1]], i32 [[OR4]]
-; CHECK-NEXT: [[TMP3:%.*]] = xor i1 [[TOBOOL]], true
-; CHECK-NEXT: [[TMP4:%.*]] = xor i1 [[TOBOOL2]], true
-; CHECK-NEXT: [[TMP5:%.*]] = or i1 [[TMP3]], [[TMP4]]
-; CHECK-NEXT: [[AND6:%.*]] = and i32 [[TMP2]], 4
+; CHECK-NEXT: [[OR4:%.*]] = or i32 [[SPEC_SELECT15]], 1073741824
+; CHECK-NEXT: [[SPEC_SELECT:%.*]] = select i1 [[TOBOOL2]], i32 [[SPEC_SELECT15]], i32 [[OR4]]
+; CHECK-NEXT: [[TMP1:%.*]] = xor i1 [[TOBOOL]], true
+; CHECK-NEXT: [[TMP2:%.*]] = xor i1 [[TOBOOL2]], true
+; CHECK-NEXT: [[TMP3:%.*]] = or i1 [[TMP1]], [[TMP2]]
+; CHECK-NEXT: [[AND6:%.*]] = and i32 [[SPEC_SELECT]], 4
; CHECK-NEXT: [[TOBOOL7:%.*]] = icmp eq i32 [[AND6]], 0
-; CHECK-NEXT: [[OR9:%.*]] = or i32 [[TMP2]], 536870912
-; CHECK-NEXT: [[SPEC_SELECT:%.*]] = select i1 [[TOBOOL7]], i32 [[TMP2]], i32 [[OR9]]
-; CHECK-NEXT: [[TMP6:%.*]] = xor i1 [[TMP5]], true
-; CHECK-NEXT: [[TMP7:%.*]] = xor i1 [[TOBOOL7]], true
-; CHECK-NEXT: [[TMP8:%.*]] = xor i1 [[TMP6]], true
-; CHECK-NEXT: [[TMP9:%.*]] = or i1 [[TMP8]], [[TMP7]]
-; CHECK-NEXT: [[AND11:%.*]] = and i32 [[SPEC_SELECT]], 8
+; CHECK-NEXT: [[OR9:%.*]] = or i32 [[SPEC_SELECT]], 536870912
+; CHECK-NEXT: [[SPEC_SELECT1:%.*]] = select i1 [[TOBOOL7]], i32 [[SPEC_SELECT]], i32 [[OR9]]
+; CHECK-NEXT: [[TMP4:%.*]] = xor i1 [[TMP3]], true
+; CHECK-NEXT: [[TMP5:%.*]] = xor i1 [[TOBOOL7]], true
+; CHECK-NEXT: [[TMP6:%.*]] = xor i1 [[TMP4]], true
+; CHECK-NEXT: [[TMP7:%.*]] = or i1 [[TMP6]], [[TMP5]]
+; CHECK-NEXT: [[AND11:%.*]] = and i32 [[SPEC_SELECT1]], 8
; CHECK-NEXT: [[TOBOOL12:%.*]] = icmp eq i32 [[AND11]], 0
-; CHECK-NEXT: [[OR14:%.*]] = or i32 [[SPEC_SELECT]], 268435456
-; CHECK-NEXT: [[SPEC_SELECT1:%.*]] = select i1 [[TOBOOL12]], i32 [[SPEC_SELECT]], i32 [[OR14]]
-; CHECK-NEXT: [[TMP10:%.*]] = xor i1 [[TMP9]], true
-; CHECK-NEXT: [[TMP11:%.*]] = xor i1 [[TOBOOL12]], true
-; CHECK-NEXT: [[TMP12:%.*]] = xor i1 [[TMP10]], true
-; CHECK-NEXT: [[TMP13:%.*]] = or i1 [[TMP12]], [[TMP11]]
-; CHECK-NEXT: [[AND16:%.*]] = and i32 [[SPEC_SELECT1]], 16
+; CHECK-NEXT: [[OR14:%.*]] = or i32 [[SPEC_SELECT1]], 268435456
+; CHECK-NEXT: [[SPEC_SELECT2:%.*]] = select i1 [[TOBOOL12]], i32 [[SPEC_SELECT1]], i32 [[OR14]]
+; CHECK-NEXT: [[TMP8:%.*]] = xor i1 [[TMP7]], true
+; CHECK-NEXT: [[TMP9:%.*]] = xor i1 [[TOBOOL12]], true
+; CHECK-NEXT: [[TMP10:%.*]] = xor i1 [[TMP8]], true
+; CHECK-NEXT: [[TMP11:%.*]] = or i1 [[TMP10]], [[TMP9]]
+; CHECK-NEXT: [[AND16:%.*]] = and i32 [[SPEC_SELECT2]], 16
; CHECK-NEXT: [[TOBOOL17:%.*]] = icmp eq i32 [[AND16]], 0
-; CHECK-NEXT: [[OR19:%.*]] = or i32 [[SPEC_SELECT1]], 134217728
-; CHECK-NEXT: [[SPEC_SELECT2:%.*]] = select i1 [[TOBOOL17]], i32 [[SPEC_SELECT1]], i32 [[OR19]]
-; CHECK-NEXT: [[TMP14:%.*]] = xor i1 [[TMP13]], true
-; CHECK-NEXT: [[TMP15:%.*]] = xor i1 [[TOBOOL17]], true
-; CHECK-NEXT: [[TMP16:%.*]] = xor i1 [[TMP14]], true
-; CHECK-NEXT: [[TMP17:%.*]] = or i1 [[TMP16]], [[TMP15]]
-; CHECK-NEXT: [[AND21:%.*]] = and i32 [[SPEC_SELECT2]], 32
+; CHECK-NEXT: [[OR19:%.*]] = or i32 [[SPEC_SELECT2]], 134217728
+; CHECK-NEXT: [[SPEC_SELECT3:%.*]] = select i1 [[TOBOOL17]], i32 [[SPEC_SELECT2]], i32 [[OR19]]
+; CHECK-NEXT: [[TMP12:%.*]] = xor i1 [[TMP11]], true
+; CHECK-NEXT: [[TMP13:%.*]] = xor i1 [[TOBOOL17]], true
+; CHECK-NEXT: [[TMP14:%.*]] = xor i1 [[TMP12]], true
+; CHECK-NEXT: [[TMP15:%.*]] = or i1 [[TMP14]], [[TMP13]]
+; CHECK-NEXT: [[AND21:%.*]] = and i32 [[SPEC_SELECT3]], 32
; CHECK-NEXT: [[TOBOOL22:%.*]] = icmp eq i32 [[AND21]], 0
-; CHECK-NEXT: [[OR24:%.*]] = or i32 [[SPEC_SELECT2]], 67108864
-; CHECK-NEXT: [[SPEC_SELECT3:%.*]] = select i1 [[TOBOOL22]], i32 [[SPEC_SELECT2]], i32 [[OR24]]
-; CHECK-NEXT: [[TMP18:%.*]] = xor i1 [[TMP17]], true
-; CHECK-NEXT: [[TMP19:%.*]] = xor i1 [[TOBOOL22]], true
-; CHECK-NEXT: [[TMP20:%.*]] = xor i1 [[TMP18]], true
-; CHECK-NEXT: [[TMP21:%.*]] = or i1 [[TMP20]], [[TMP19]]
-; CHECK-NEXT: [[AND26:%.*]] = and i32 [[SPEC_SELECT3]], 64
+; CHECK-NEXT: [[OR24:%.*]] = or i32 [[SPEC_SELECT3]], 67108864
+; CHECK-NEXT: [[SPEC_SELECT4:%.*]] = select i1 [[TOBOOL22]], i32 [[SPEC_SELECT3]], i32 [[OR24]]
+; CHECK-NEXT: [[TMP16:%.*]] = xor i1 [[TMP15]], true
+; CHECK-NEXT: [[TMP17:%.*]] = xor i1 [[TOBOOL22]], true
+; CHECK-NEXT: [[TMP18:%.*]] = xor i1 [[TMP16]], true
+; CHECK-NEXT: [[TMP19:%.*]] = or i1 [[TMP18]], [[TMP17]]
+; CHECK-NEXT: [[AND26:%.*]] = and i32 [[SPEC_SELECT4]], 64
; CHECK-NEXT: [[TOBOOL27:%.*]] = icmp eq i32 [[AND26]], 0
-; CHECK-NEXT: [[OR29:%.*]] = or i32 [[SPEC_SELECT3]], 33554432
-; CHECK-NEXT: [[SPEC_SELECT4:%.*]] = select i1 [[TOBOOL27]], i32 [[SPEC_SELECT3]], i32 [[OR29]]
-; CHECK-NEXT: [[TMP22:%.*]] = xor i1 [[TMP21]], true
-; CHECK-NEXT: [[TMP23:%.*]] = xor i1 [[TOBOOL27]], true
-; CHECK-NEXT: [[TMP24:%.*]] = xor i1 [[TMP22]], true
-; CHECK-NEXT: [[TMP25:%.*]] = or i1 [[TMP24]], [[TMP23]]
-; CHECK-NEXT: [[AND31:%.*]] = and i32 [[SPEC_SELECT4]], 256
+; CHECK-NEXT: [[OR29:%.*]] = or i32 [[SPEC_SELECT4]], 33554432
+; CHECK-NEXT: [[SPEC_SELECT5:%.*]] = select i1 [[TOBOOL27]], i32 [[SPEC_SELECT4]], i32 [[OR29]]
+; CHECK-NEXT: [[TMP20:%.*]] = xor i1 [[TMP19]], true
+; CHECK-NEXT: [[TMP21:%.*]] = xor i1 [[TOBOOL27]], true
+; CHECK-NEXT: [[TMP22:%.*]] = xor i1 [[TMP20]], true
+; CHECK-NEXT: [[TMP23:%.*]] = or i1 [[TMP22]], [[TMP21]]
+; CHECK-NEXT: [[AND31:%.*]] = and i32 [[SPEC_SELECT5]], 256
; CHECK-NEXT: [[TOBOOL32:%.*]] = icmp eq i32 [[AND31]], 0
-; CHECK-NEXT: [[OR34:%.*]] = or i32 [[SPEC_SELECT4]], 8388608
-; CHECK-NEXT: [[SPEC_SELECT5:%.*]] = select i1 [[TOBOOL32]], i32 [[SPEC_SELECT4]], i32 [[OR34]]
-; CHECK-NEXT: [[TMP26:%.*]] = xor i1 [[TMP25]], true
-; CHECK-NEXT: [[TMP27:%.*]] = xor i1 [[TOBOOL32]], true
-; CHECK-NEXT: [[TMP28:%.*]] = xor i1 [[TMP26]], true
-; CHECK-NEXT: [[TMP29:%.*]] = or i1 [[TMP28]], [[TMP27]]
-; CHECK-NEXT: [[AND36:%.*]] = and i32 [[SPEC_SELECT5]], 512
+; CHECK-NEXT: [[OR34:%.*]] = or i32 [[SPEC_SELECT5]], 8388608
+; CHECK-NEXT: [[SPEC_SELECT6:%.*]] = select i1 [[TOBOOL32]], i32 [[SPEC_SELECT5]], i32 [[OR34]]
+; CHECK-NEXT: [[TMP24:%.*]] = xor i1 [[TMP23]], true
+; CHECK-NEXT: [[TMP25:%.*]] = xor i1 [[TOBOOL32]], true
+; CHECK-NEXT: [[TMP26:%.*]] = xor i1 [[TMP24]], true
+; CHECK-NEXT: [[TMP27:%.*]] = or i1 [[TMP26]], [[TMP25]]
+; CHECK-NEXT: [[AND36:%.*]] = and i32 [[SPEC_SELECT6]], 512
; CHECK-NEXT: [[TOBOOL37:%.*]] = icmp eq i32 [[AND36]], 0
-; CHECK-NEXT: [[OR39:%.*]] = or i32 [[SPEC_SELECT5]], 4194304
-; CHECK-NEXT: [[SPEC_SELECT6:%.*]] = select i1 [[TOBOOL37]], i32 [[SPEC_SELECT5]], i32 [[OR39]]
-; CHECK-NEXT: [[TMP30:%.*]] = xor i1 [[TMP29]], true
-; CHECK-NEXT: [[TMP31:%.*]] = xor i1 [[TOBOOL37]], true
-; CHECK-NEXT: [[TMP32:%.*]] = xor i1 [[TMP30]], true
-; CHECK-NEXT: [[TMP33:%.*]] = or i1 [[TMP32]], [[TMP31]]
-; CHECK-NEXT: [[AND41:%.*]] = and i32 [[SPEC_SELECT6]], 1024
+; CHECK-NEXT: [[OR39:%.*]] = or i32 [[SPEC_SELECT6]], 4194304
+; CHECK-NEXT: [[SPEC_SELECT7:%.*]] = select i1 [[TOBOOL37]], i32 [[SPEC_SELECT6]], i32 [[OR39]]
+; CHECK-NEXT: [[TMP28:%.*]] = xor i1 [[TMP27]], true
+; CHECK-NEXT: [[TMP29:%.*]] = xor i1 [[TOBOOL37]], true
+; CHECK-NEXT: [[TMP30:%.*]] = xor i1 [[TMP28]], true
+; CHECK-NEXT: [[TMP31:%.*]] = or i1 [[TMP30]], [[TMP29]]
+; CHECK-NEXT: [[AND41:%.*]] = and i32 [[SPEC_SELECT7]], 1024
; CHECK-NEXT: [[TOBOOL42:%.*]] = icmp eq i32 [[AND41]], 0
-; CHECK-NEXT: [[OR44:%.*]] = or i32 [[SPEC_SELECT6]], 2097152
-; CHECK-NEXT: [[SPEC_SELECT7:%.*]] = select i1 [[TOBOOL42]], i32 [[SPEC_SELECT6]], i32 [[OR44]]
-; CHECK-NEXT: [[TMP34:%.*]] = xor i1 [[TMP33]], true
-; CHECK-NEXT: [[TMP35:%.*]] = xor i1 [[TOBOOL42]], true
-; CHECK-NEXT: [[TMP36:%.*]] = xor i1 [[TMP34]], true
-; CHECK-NEXT: [[TMP37:%.*]] = or i1 [[TMP36]], [[TMP35]]
-; CHECK-NEXT: [[AND46:%.*]] = and i32 [[SPEC_SELECT7]], 2048
+; CHECK-NEXT: [[OR44:%.*]] = or i32 [[SPEC_SELECT7]], 2097152
+; CHECK-NEXT: [[SPEC_SELECT8:%.*]] = select i1 [[TOBOOL42]], i32 [[SPEC_SELECT7]], i32 [[OR44]]
+; CHECK-NEXT: [[TMP32:%.*]] = xor i1 [[TMP31]], true
+; CHECK-NEXT: [[TMP33:%.*]] = xor i1 [[TOBOOL42]], true
+; CHECK-NEXT: [[TMP34:%.*]] = xor i1 [[TMP32]], true
+; CHECK-NEXT: [[TMP35:%.*]] = or i1 [[TMP34]], [[TMP33]]
+; CHECK-NEXT: [[AND46:%.*]] = and i32 [[SPEC_SELECT8]], 2048
; CHECK-NEXT: [[TOBOOL47:%.*]] = icmp eq i32 [[AND46]], 0
-; CHECK-NEXT: [[OR49:%.*]] = or i32 [[SPEC_SELECT7]], 1048576
-; CHECK-NEXT: [[SPEC_SELECT8:%.*]] = select i1 [[TOBOOL47]], i32 [[SPEC_SELECT7]], i32 [[OR49]]
-; CHECK-NEXT: [[TMP38:%.*]] = xor i1 [[TMP37]], true
-; CHECK-NEXT: [[TMP39:%.*]] = xor i1 [[TOBOOL47]], true
-; CHECK-NEXT: [[TMP40:%.*]] = xor i1 [[TMP38]], true
-; CHECK-NEXT: [[TMP41:%.*]] = or i1 [[TMP40]], [[TMP39]]
-; CHECK-NEXT: [[AND51:%.*]] = and i32 [[SPEC_SELECT8]], 4096
+; CHECK-NEXT: [[OR49:%.*]] = or i32 [[SPEC_SELECT8]], 1048576
+; CHECK-NEXT: [[SPEC_SELECT9:%.*]] = select i1 [[TOBOOL47]], i32 [[SPEC_SELECT8]], i32 [[OR49]]
+; CHECK-NEXT: [[TMP36:%.*]] = xor i1 [[TMP35]], true
+; CHECK-NEXT: [[TMP37:%.*]] = xor i1 [[TOBOOL47]], true
+; CHECK-NEXT: [[TMP38:%.*]] = xor i1 [[TMP36]], true
+; CHECK-NEXT: [[TMP39:%.*]] = or i1 [[TMP38]], [[TMP37]]
+; CHECK-NEXT: [[AND51:%.*]] = and i32 [[SPEC_SELECT9]], 4096
; CHECK-NEXT: [[TOBOOL52:%.*]] = icmp eq i32 [[AND51]], 0
-; CHECK-NEXT: [[OR54:%.*]] = or i32 [[SPEC_SELECT8]], 524288
-; CHECK-NEXT: [[SPEC_SELECT9:%.*]] = select i1 [[TOBOOL52]], i32 [[SPEC_SELECT8]], i32 [[OR54]]
-; CHECK-NEXT: [[TMP42:%.*]] = xor i1 [[TMP41]], true
-; CHECK-NEXT: [[TMP43:%.*]] = xor i1 [[TOBOOL52]], true
-; CHECK-NEXT: [[TMP44:%.*]] = xor i1 [[TMP42]], true
-; CHECK-NEXT: [[TMP45:%.*]] = or i1 [[TMP44]], [[TMP43]]
-; CHECK-NEXT: [[AND56:%.*]] = and i32 [[SPEC_SELECT9]], 8192
+; CHECK-NEXT: [[OR54:%.*]] = or i32 [[SPEC_SELECT9]], 524288
+; CHECK-NEXT: [[SPEC_SELECT10:%.*]] = select i1 [[TOBOOL52]], i32 [[SPEC_SELECT9]], i32 [[OR54]]
+; CHECK-NEXT: [[TMP40:%.*]] = xor i1 [[TMP39]], true
+; CHECK-NEXT: [[TMP41:%.*]] = xor i1 [[TOBOOL52]], true
+; CHECK-NEXT: [[TMP42:%.*]] = xor i1 [[TMP40]], true
+; CHECK-NEXT: [[TMP43:%.*]] = or i1 [[TMP42]], [[TMP41]]
+; CHECK-NEXT: [[AND56:%.*]] = and i32 [[SPEC_SELECT10]], 8192
; CHECK-NEXT: [[TOBOOL57:%.*]] = icmp eq i32 [[AND56]], 0
-; CHECK-NEXT: [[OR59:%.*]] = or i32 [[SPEC_SELECT9]], 262144
-; CHECK-NEXT: [[SPEC_SELECT10:%.*]] = select i1 [[TOBOOL57]], i32 [[SPEC_SELECT9]], i32 [[OR59]]
-; CHECK-NEXT: [[TMP46:%.*]] = xor i1 [[TMP45]], true
-; CHECK-NEXT: [[TMP47:%.*]] = xor i1 [[TOBOOL57]], true
-; CHECK-NEXT: [[TMP48:%.*]] = xor i1 [[TMP46]], true
-; CHECK-NEXT: [[TMP49:%.*]] = or i1 [[TMP48]], [[TMP47]]
-; CHECK-NEXT: [[AND61:%.*]] = and i32 [[SPEC_SELECT10]], 16384
+; CHECK-NEXT: [[OR59:%.*]] = or i32 [[SPEC_SELECT10]], 262144
+; CHECK-NEXT: [[SPEC_SELECT11:%.*]] = select i1 [[TOBOOL57]], i32 [[SPEC_SELECT10]], i32 [[OR59]]
+; CHECK-NEXT: [[TMP44:%.*]] = xor i1 [[TMP43]], true
+; CHECK-NEXT: [[TMP45:%.*]] = xor i1 [[TOBOOL57]], true
+; CHECK-NEXT: [[TMP46:%.*]] = xor i1 [[TMP44]], true
+; CHECK-NEXT: [[TMP47:%.*]] = or i1 [[TMP46]], [[TMP45]]
+; CHECK-NEXT: [[AND61:%.*]] = and i32 [[SPEC_SELECT11]], 16384
; CHECK-NEXT: [[TOBOOL62:%.*]] = icmp eq i32 [[AND61]], 0
-; CHECK-NEXT: [[OR64:%.*]] = or i32 [[SPEC_SELECT10]], 131072
-; CHECK-NEXT: [[SPEC_SELECT11:%.*]] = select i1 [[TOBOOL62]], i32 [[SPEC_SELECT10]], i32 [[OR64]]
-; CHECK-NEXT: [[TMP50:%.*]] = xor i1 [[TMP49]], true
-; CHECK-NEXT: [[TMP51:%.*]] = xor i1 [[TOBOOL62]], true
-; CHECK-NEXT: [[TMP52:%.*]] = xor i1 [[TMP50]], true
-; CHECK-NEXT: [[TMP53:%.*]] = or i1 [[TMP52]], [[TMP51]]
-; CHECK-NEXT: [[AND66:%.*]] = and i32 [[SPEC_SELECT11]], 32768
+; CHECK-NEXT: [[OR64:%.*]] = or i32 [[SPEC_SELECT11]], 131072
+; CHECK-NEXT: [[SPEC_SELECT12:%.*]] = select i1 [[TOBOOL62]], i32 [[SPEC_SELECT11]], i32 [[OR64]]
+; CHECK-NEXT: [[TMP48:%.*]] = xor i1 [[TMP47]], true
+; CHECK-NEXT: [[TMP49:%.*]] = xor i1 [[TOBOOL62]], true
+; CHECK-NEXT: [[TMP50:%.*]] = xor i1 [[TMP48]], true
+; CHECK-NEXT: [[TMP51:%.*]] = or i1 [[TMP50]], [[TMP49]]
+; CHECK-NEXT: [[AND66:%.*]] = and i32 [[SPEC_SELECT12]], 32768
; CHECK-NEXT: [[TOBOOL67:%.*]] = icmp eq i32 [[AND66]], 0
-; CHECK-NEXT: [[OR69:%.*]] = or i32 [[SPEC_SELECT11]], 65536
-; CHECK-NEXT: [[SPEC_SELECT12:%.*]] = select i1 [[TOBOOL67]], i32 [[SPEC_SELECT11]], i32 [[OR69]]
-; CHECK-NEXT: [[TMP54:%.*]] = xor i1 [[TMP53]], true
-; CHECK-NEXT: [[TMP55:%.*]] = xor i1 [[TOBOOL67]], true
-; CHECK-NEXT: [[TMP56:%.*]] = xor i1 [[TMP54]], true
-; CHECK-NEXT: [[TMP57:%.*]] = or i1 [[TMP56]], [[TMP55]]
-; CHECK-NEXT: [[AND71:%.*]] = and i32 [[SPEC_SELECT12]], 128
+; CHECK-NEXT: [[OR69:%.*]] = or i32 [[SPEC_SELECT12]], 65536
+; CHECK-NEXT: [[SPEC_SELECT13:%.*]] = select i1 [[TOBOOL67]], i32 [[SPEC_SELECT12]], i32 [[OR69]]
+; CHECK-NEXT: [[TMP52:%.*]] = xor i1 [[TMP51]], true
+; CHECK-NEXT: [[TMP53:%.*]] = xor i1 [[TOBOOL67]], true
+; CHECK-NEXT: [[TMP54:%.*]] = xor i1 [[TMP52]], true
+; CHECK-NEXT: [[TMP55:%.*]] = or i1 [[TMP54]], [[TMP53]]
+; CHECK-NEXT: [[AND71:%.*]] = and i32 [[SPEC_SELECT13]], 128
; CHECK-NEXT: [[TOBOOL72:%.*]] = icmp eq i32 [[AND71]], 0
-; CHECK-NEXT: [[OR74:%.*]] = or i32 [[SPEC_SELECT12]], 16777216
-; CHECK-NEXT: [[SPEC_SELECT13:%.*]] = select i1 [[TOBOOL72]], i32 [[SPEC_SELECT12]], i32 [[OR74]]
-; CHECK-NEXT: [[TMP58:%.*]] = xor i1 [[TMP57]], true
-; CHECK-NEXT: [[TMP59:%.*]] = xor i1 [[TOBOOL72]], true
-; CHECK-NEXT: [[TMP60:%.*]] = xor i1 [[TMP58]], true
-; CHECK-NEXT: [[TMP61:%.*]] = or i1 [[TMP60]], [[TMP59]]
-; CHECK-NEXT: br i1 [[TMP61]], label [[TMP62:%.*]], label [[TMP63:%.*]]
-; CHECK: 62:
-; CHECK-NEXT: store i32 [[SPEC_SELECT13]], i32* [[B]], align 4
-; CHECK-NEXT: br label [[TMP63]]
-; CHECK: 63:
+; CHECK-NEXT: [[OR74:%.*]] = or i32 [[SPEC_SELECT13]], 16777216
+; CHECK-NEXT: [[SPEC_SELECT14:%.*]] = select i1 [[TOBOOL72]], i32 [[SPEC_SELECT13]], i32 [[OR74]]
+; CHECK-NEXT: [[TMP56:%.*]] = xor i1 [[TMP55]], true
+; CHECK-NEXT: [[TMP57:%.*]] = xor i1 [[TOBOOL72]], true
+; CHECK-NEXT: [[TMP58:%.*]] = xor i1 [[TMP56]], true
+; CHECK-NEXT: [[TMP59:%.*]] = or i1 [[TMP58]], [[TMP57]]
+; CHECK-NEXT: br i1 [[TMP59]], label [[TMP60:%.*]], label [[TMP61:%.*]]
+; CHECK: 60:
+; CHECK-NEXT: store i32 [[SPEC_SELECT14]], i32* [[B]], align 4
+; CHECK-NEXT: br label [[TMP61]]
+; CHECK: 61:
; CHECK-NEXT: ret i32 0
;
entry:
define i1 @test2(i1 zeroext %flag, i8* %y, i8* %z) #0 {
; CHECK-LABEL: @test2(
; CHECK-NEXT: entry:
-; CHECK-NEXT: [[Y_Z:%.*]] = select i1 [[FLAG:%.*]], i8* [[Y:%.*]], i8* [[Z:%.*]]
-; CHECK-NEXT: [[S:%.*]] = call i1 @llvm.type.test(i8* [[Y_Z]], metadata [[META1]])
-; CHECK-NEXT: ret i1 [[S]]
+; CHECK-NEXT: [[S:%.*]] = call i1 @llvm.type.test(i8* [[Z:%.*]], metadata [[META1]])
+; CHECK-NEXT: [[R:%.*]] = call i1 @llvm.type.test(i8* [[Y:%.*]], metadata [[META1]])
+; CHECK-NEXT: [[T:%.*]] = select i1 [[FLAG:%.*]], i1 [[R]], i1 [[S]]
+; CHECK-NEXT: ret i1 [[T]]
;
entry:
br i1 %flag, label %if.then, label %if.else
; CHECK-NEXT: [[AND:%.*]] = and i64 [[TMP2]], 1
; CHECK-NEXT: [[TOBOOL:%.*]] = icmp eq i64 [[AND]], 0
; CHECK-NEXT: [[TMP3:%.*]] = add nsw <2 x i64> [[TMP0]], <i64 2, i64 2>
-; CHECK-NEXT: [[TMP4:%.*]] = select i1 [[TOBOOL]], <2 x i64> [[TMP1]], <2 x i64> [[TMP3]]
+; CHECK-NEXT: [[SPEC_SELECT1:%.*]] = select i1 [[TOBOOL]], <2 x i64> [[TMP1]], <2 x i64> [[TMP3]]
; CHECK-NEXT: [[AND4:%.*]] = and i64 [[TMP2]], 2
; CHECK-NEXT: [[TOBOOL5:%.*]] = icmp eq i64 [[AND4]], 0
-; CHECK-NEXT: [[TMP5:%.*]] = add nsw <2 x i64> [[TMP4]], <i64 1, i64 1>
-; CHECK-NEXT: [[SIMPLIFYCFG_MERGE:%.*]] = select i1 [[TOBOOL5]], <2 x i64> [[TMP4]], <2 x i64> [[TMP5]]
-; CHECK-NEXT: [[TMP6:%.*]] = xor i1 [[TOBOOL]], true
-; CHECK-NEXT: [[TMP7:%.*]] = xor i1 [[TOBOOL5]], true
-; CHECK-NEXT: [[TMP8:%.*]] = or i1 [[TMP6]], [[TMP7]]
-; CHECK-NEXT: br i1 [[TMP8]], label [[TMP9:%.*]], label [[TMP10:%.*]]
+; CHECK-NEXT: [[TMP4:%.*]] = add nsw <2 x i64> [[SPEC_SELECT1]], <i64 1, i64 1>
+; CHECK-NEXT: [[SPEC_SELECT:%.*]] = select i1 [[TOBOOL5]], <2 x i64> [[SPEC_SELECT1]], <2 x i64> [[TMP4]]
+; CHECK-NEXT: [[TMP5:%.*]] = xor i1 [[TOBOOL]], true
+; CHECK-NEXT: [[TMP6:%.*]] = xor i1 [[TOBOOL5]], true
+; CHECK-NEXT: [[TMP7:%.*]] = or i1 [[TMP5]], [[TMP6]]
+; CHECK-NEXT: br i1 [[TMP7]], label [[TMP8:%.*]], label [[TMP9:%.*]]
+; CHECK: 8:
+; CHECK-NEXT: store <2 x i64> [[SPEC_SELECT]], <2 x i64>* bitcast (i64* getelementptr inbounds ([[STRUCT_COUNTERS]], %struct.Counters* @counters, i64 0, i32 1) to <2 x i64>*), align 8
+; CHECK-NEXT: br label [[TMP9]]
; CHECK: 9:
-; CHECK-NEXT: store <2 x i64> [[SIMPLIFYCFG_MERGE]], <2 x i64>* bitcast (i64* getelementptr inbounds ([[STRUCT_COUNTERS]], %struct.Counters* @counters, i64 0, i32 1) to <2 x i64>*), align 8
-; CHECK-NEXT: br label [[TMP10]]
-; CHECK: 10:
; CHECK-NEXT: ret i32 0
;
entry:
; CHECK-NEXT: [[AND:%.*]] = and i64 [[TMP2]], 1
; CHECK-NEXT: [[TOBOOL:%.*]] = icmp eq i64 [[AND]], 0
; CHECK-NEXT: [[TMP3:%.*]] = add nsw <2 x i64> [[TMP0]], <i64 2, i64 2>
-; CHECK-NEXT: [[TMP4:%.*]] = select i1 [[TOBOOL]], <2 x i64> [[TMP1]], <2 x i64> [[TMP3]]
+; CHECK-NEXT: [[SPEC_SELECT1:%.*]] = select i1 [[TOBOOL]], <2 x i64> [[TMP1]], <2 x i64> [[TMP3]]
; CHECK-NEXT: [[AND4:%.*]] = and i64 [[TMP2]], 2
; CHECK-NEXT: [[TOBOOL5:%.*]] = icmp eq i64 [[AND4]], 0
-; CHECK-NEXT: [[TMP5:%.*]] = add nsw <2 x i64> [[TMP4]], <i64 1, i64 1>
-; CHECK-NEXT: [[SIMPLIFYCFG_MERGE:%.*]] = select i1 [[TOBOOL5]], <2 x i64> [[TMP4]], <2 x i64> [[TMP5]]
-; CHECK-NEXT: [[TMP6:%.*]] = xor i1 [[TOBOOL]], true
-; CHECK-NEXT: [[TMP7:%.*]] = xor i1 [[TOBOOL5]], true
-; CHECK-NEXT: [[TMP8:%.*]] = or i1 [[TMP6]], [[TMP7]]
-; CHECK-NEXT: br i1 [[TMP8]], label [[TMP9:%.*]], label [[TMP10:%.*]]
+; CHECK-NEXT: [[TMP4:%.*]] = add nsw <2 x i64> [[SPEC_SELECT1]], <i64 1, i64 1>
+; CHECK-NEXT: [[SPEC_SELECT:%.*]] = select i1 [[TOBOOL5]], <2 x i64> [[SPEC_SELECT1]], <2 x i64> [[TMP4]]
+; CHECK-NEXT: [[TMP5:%.*]] = xor i1 [[TOBOOL]], true
+; CHECK-NEXT: [[TMP6:%.*]] = xor i1 [[TOBOOL5]], true
+; CHECK-NEXT: [[TMP7:%.*]] = or i1 [[TMP5]], [[TMP6]]
+; CHECK-NEXT: br i1 [[TMP7]], label [[TMP8:%.*]], label [[TMP9:%.*]]
+; CHECK: 8:
+; CHECK-NEXT: store <2 x i64> [[SPEC_SELECT]], <2 x i64>* bitcast (i64* getelementptr inbounds ([[STRUCT_COUNTERS]], %struct.Counters* @counters, i64 0, i32 1) to <2 x i64>*), align 8
+; CHECK-NEXT: br label [[TMP9]]
; CHECK: 9:
-; CHECK-NEXT: store <2 x i64> [[SIMPLIFYCFG_MERGE]], <2 x i64>* bitcast (i64* getelementptr inbounds ([[STRUCT_COUNTERS]], %struct.Counters* @counters, i64 0, i32 1) to <2 x i64>*), align 8
-; CHECK-NEXT: br label [[TMP10]]
-; CHECK: 10:
; CHECK-NEXT: ret i32 0
;
entry:
; CHECK-NEXT: [[AND:%.*]] = and i64 [[TMP2]], 1
; CHECK-NEXT: [[TOBOOL:%.*]] = icmp eq i64 [[AND]], 0
; CHECK-NEXT: [[TMP3:%.*]] = add nsw <2 x i64> [[TMP0]], <i64 2, i64 2>
-; CHECK-NEXT: [[TMP4:%.*]] = select i1 [[TOBOOL]], <2 x i64> [[TMP1]], <2 x i64> [[TMP3]]
+; CHECK-NEXT: [[SPEC_SELECT1:%.*]] = select i1 [[TOBOOL]], <2 x i64> [[TMP1]], <2 x i64> [[TMP3]]
; CHECK-NEXT: [[AND4:%.*]] = and i64 [[TMP2]], 2
; CHECK-NEXT: [[TOBOOL5:%.*]] = icmp eq i64 [[AND4]], 0
-; CHECK-NEXT: [[TMP5:%.*]] = add nsw <2 x i64> [[TMP4]], <i64 1, i64 1>
-; CHECK-NEXT: [[SIMPLIFYCFG_MERGE:%.*]] = select i1 [[TOBOOL5]], <2 x i64> [[TMP4]], <2 x i64> [[TMP5]]
-; CHECK-NEXT: [[TMP6:%.*]] = xor i1 [[TOBOOL]], true
-; CHECK-NEXT: [[TMP7:%.*]] = xor i1 [[TOBOOL5]], true
-; CHECK-NEXT: [[TMP8:%.*]] = or i1 [[TMP6]], [[TMP7]]
-; CHECK-NEXT: br i1 [[TMP8]], label [[TMP9:%.*]], label [[TMP10:%.*]]
+; CHECK-NEXT: [[TMP4:%.*]] = add nsw <2 x i64> [[SPEC_SELECT1]], <i64 1, i64 1>
+; CHECK-NEXT: [[SPEC_SELECT:%.*]] = select i1 [[TOBOOL5]], <2 x i64> [[SPEC_SELECT1]], <2 x i64> [[TMP4]]
+; CHECK-NEXT: [[TMP5:%.*]] = xor i1 [[TOBOOL]], true
+; CHECK-NEXT: [[TMP6:%.*]] = xor i1 [[TOBOOL5]], true
+; CHECK-NEXT: [[TMP7:%.*]] = or i1 [[TMP5]], [[TMP6]]
+; CHECK-NEXT: br i1 [[TMP7]], label [[TMP8:%.*]], label [[TMP9:%.*]]
+; CHECK: 8:
+; CHECK-NEXT: store <2 x i64> [[SPEC_SELECT]], <2 x i64>* bitcast (i64* getelementptr inbounds ([[STRUCT_COUNTERS]], %struct.Counters* @counters, i64 0, i32 1) to <2 x i64>*), align 8
+; CHECK-NEXT: br label [[TMP9]]
; CHECK: 9:
-; CHECK-NEXT: store <2 x i64> [[SIMPLIFYCFG_MERGE]], <2 x i64>* bitcast (i64* getelementptr inbounds ([[STRUCT_COUNTERS]], %struct.Counters* @counters, i64 0, i32 1) to <2 x i64>*), align 8
-; CHECK-NEXT: br label [[TMP10]]
-; CHECK: 10:
; CHECK-NEXT: ret i32 0
;
entry:
; CHECK-NEXT: [[AND:%.*]] = and i64 [[TMP2]], 1
; CHECK-NEXT: [[TOBOOL:%.*]] = icmp eq i64 [[AND]], 0
; CHECK-NEXT: [[TMP3:%.*]] = add nsw <2 x i64> [[TMP0]], <i64 2, i64 2>
-; CHECK-NEXT: [[TMP4:%.*]] = select i1 [[TOBOOL]], <2 x i64> [[TMP1]], <2 x i64> [[TMP3]]
+; CHECK-NEXT: [[SPEC_SELECT1:%.*]] = select i1 [[TOBOOL]], <2 x i64> [[TMP1]], <2 x i64> [[TMP3]]
; CHECK-NEXT: [[AND4:%.*]] = and i64 [[TMP2]], 2
; CHECK-NEXT: [[TOBOOL5:%.*]] = icmp eq i64 [[AND4]], 0
-; CHECK-NEXT: [[TMP5:%.*]] = add nsw <2 x i64> [[TMP4]], <i64 1, i64 1>
-; CHECK-NEXT: [[SIMPLIFYCFG_MERGE:%.*]] = select i1 [[TOBOOL5]], <2 x i64> [[TMP4]], <2 x i64> [[TMP5]]
-; CHECK-NEXT: [[TMP6:%.*]] = xor i1 [[TOBOOL]], true
-; CHECK-NEXT: [[TMP7:%.*]] = xor i1 [[TOBOOL5]], true
-; CHECK-NEXT: [[TMP8:%.*]] = or i1 [[TMP6]], [[TMP7]]
-; CHECK-NEXT: br i1 [[TMP8]], label [[TMP9:%.*]], label [[TMP10:%.*]]
+; CHECK-NEXT: [[TMP4:%.*]] = add nsw <2 x i64> [[SPEC_SELECT1]], <i64 1, i64 1>
+; CHECK-NEXT: [[SPEC_SELECT:%.*]] = select i1 [[TOBOOL5]], <2 x i64> [[SPEC_SELECT1]], <2 x i64> [[TMP4]]
+; CHECK-NEXT: [[TMP5:%.*]] = xor i1 [[TOBOOL]], true
+; CHECK-NEXT: [[TMP6:%.*]] = xor i1 [[TOBOOL5]], true
+; CHECK-NEXT: [[TMP7:%.*]] = or i1 [[TMP5]], [[TMP6]]
+; CHECK-NEXT: br i1 [[TMP7]], label [[TMP8:%.*]], label [[TMP9:%.*]]
+; CHECK: 8:
+; CHECK-NEXT: store <2 x i64> [[SPEC_SELECT]], <2 x i64>* bitcast (i64* getelementptr inbounds ([[STRUCT_COUNTERS]], %struct.Counters* @counters, i64 0, i32 1) to <2 x i64>*), align 16
+; CHECK-NEXT: br label [[TMP9]]
; CHECK: 9:
-; CHECK-NEXT: store <2 x i64> [[SIMPLIFYCFG_MERGE]], <2 x i64>* bitcast (i64* getelementptr inbounds ([[STRUCT_COUNTERS]], %struct.Counters* @counters, i64 0, i32 1) to <2 x i64>*), align 16
-; CHECK-NEXT: br label [[TMP10]]
-; CHECK: 10:
; CHECK-NEXT: ret i32 0
;
entry:
; CHECK-NEXT: [[AND:%.*]] = and i64 [[TMP2]], 1
; CHECK-NEXT: [[TOBOOL:%.*]] = icmp eq i64 [[AND]], 0
; CHECK-NEXT: [[TMP3:%.*]] = add nsw <2 x i64> [[TMP0]], <i64 2, i64 2>
-; CHECK-NEXT: [[TMP4:%.*]] = select i1 [[TOBOOL]], <2 x i64> [[TMP1]], <2 x i64> [[TMP3]]
+; CHECK-NEXT: [[SPEC_SELECT1:%.*]] = select i1 [[TOBOOL]], <2 x i64> [[TMP1]], <2 x i64> [[TMP3]]
; CHECK-NEXT: [[AND4:%.*]] = and i64 [[TMP2]], 2
; CHECK-NEXT: [[TOBOOL5:%.*]] = icmp eq i64 [[AND4]], 0
-; CHECK-NEXT: [[TMP5:%.*]] = add nsw <2 x i64> [[TMP4]], <i64 1, i64 1>
-; CHECK-NEXT: [[SIMPLIFYCFG_MERGE:%.*]] = select i1 [[TOBOOL5]], <2 x i64> [[TMP4]], <2 x i64> [[TMP5]]
-; CHECK-NEXT: [[TMP6:%.*]] = xor i1 [[TOBOOL]], true
-; CHECK-NEXT: [[TMP7:%.*]] = xor i1 [[TOBOOL5]], true
-; CHECK-NEXT: [[TMP8:%.*]] = or i1 [[TMP6]], [[TMP7]]
-; CHECK-NEXT: br i1 [[TMP8]], label [[TMP9:%.*]], label [[TMP10:%.*]]
+; CHECK-NEXT: [[TMP4:%.*]] = add nsw <2 x i64> [[SPEC_SELECT1]], <i64 1, i64 1>
+; CHECK-NEXT: [[SPEC_SELECT:%.*]] = select i1 [[TOBOOL5]], <2 x i64> [[SPEC_SELECT1]], <2 x i64> [[TMP4]]
+; CHECK-NEXT: [[TMP5:%.*]] = xor i1 [[TOBOOL]], true
+; CHECK-NEXT: [[TMP6:%.*]] = xor i1 [[TOBOOL5]], true
+; CHECK-NEXT: [[TMP7:%.*]] = or i1 [[TMP5]], [[TMP6]]
+; CHECK-NEXT: br i1 [[TMP7]], label [[TMP8:%.*]], label [[TMP9:%.*]]
+; CHECK: 8:
+; CHECK-NEXT: store <2 x i64> [[SPEC_SELECT]], <2 x i64>* bitcast (i64* getelementptr inbounds ([[STRUCT_COUNTERS]], %struct.Counters* @counters, i64 0, i32 1) to <2 x i64>*), align 16
+; CHECK-NEXT: br label [[TMP9]]
; CHECK: 9:
-; CHECK-NEXT: store <2 x i64> [[SIMPLIFYCFG_MERGE]], <2 x i64>* bitcast (i64* getelementptr inbounds ([[STRUCT_COUNTERS]], %struct.Counters* @counters, i64 0, i32 1) to <2 x i64>*), align 16
-; CHECK-NEXT: br label [[TMP10]]
-; CHECK: 10:
; CHECK-NEXT: ret i32 0
;
entry: