[SimplifyCFG] Start redesigning `FoldTwoEntryPHINode()`.
authorRoman Lebedev <lebedev.ri@gmail.com>
Sun, 23 Jan 2022 14:05:22 +0000 (17:05 +0300)
committerRoman Lebedev <lebedev.ri@gmail.com>
Wed, 2 Feb 2022 14:53:56 +0000 (17:53 +0300)
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.

15 files changed:
llvm/lib/Transforms/Utils/SimplifyCFG.cpp
llvm/test/CodeGen/AArch64/check-sign-bit-before-extension.ll
llvm/test/CodeGen/AArch64/combine-comparisons-by-cse.ll
llvm/test/CodeGen/AArch64/typepromotion-phisret.ll
llvm/test/CodeGen/ARM/ifcvt-callback.ll
llvm/test/CodeGen/ARM/ifcvt1.ll
llvm/test/Transforms/PGOProfile/chr.ll
llvm/test/Transforms/PhaseOrdering/X86/earlycse-after-simplifycfg-two-entry-phi-node-folding.ll
llvm/test/Transforms/PhaseOrdering/X86/merge-functions.ll
llvm/test/Transforms/SimplifyCFG/UnreachableEliminate.ll
llvm/test/Transforms/SimplifyCFG/X86/sink-common-code.ll
llvm/test/Transforms/SimplifyCFG/bbi-23595.ll
llvm/test/Transforms/SimplifyCFG/merge-cond-stores-2.ll
llvm/test/Transforms/SimplifyCFG/no-md-sink.ll
llvm/test/Transforms/SimplifyCFG/preserve-store-alignment.ll

index 335ac03..b16fbd1 100644 (file)
@@ -2960,6 +2960,81 @@ static bool FoldTwoEntryPHINode(PHINode *PN, const TargetTransformInfo &TTI,
   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 = "") {
@@ -6521,6 +6596,11 @@ bool SimplifyCFGOpt::simplifyCondBranch(BranchInst *BI, IRBuilder<> &Builder) {
         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()))
@@ -6736,15 +6816,6 @@ bool SimplifyCFGOpt::simplifyOnce(BasicBlock *BB) {
 
   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()) {
index 8fbed8b..ff0a9e8 100644 (file)
 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
@@ -35,10 +37,12 @@ B:
 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
@@ -57,9 +61,11 @@ B:
 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
@@ -78,10 +84,12 @@ B:
 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
@@ -100,10 +108,12 @@ B:
 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
@@ -122,9 +132,11 @@ B:
 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
@@ -144,10 +156,12 @@ define i64 @f_i32_sign_extend_i64(i32 %in, i64 %a, i64 %b) nounwind {
 ; 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
@@ -168,10 +182,12 @@ define i64 @g_i32_sign_extend_i64(i32 %in, i64 %a, i64 %b) nounwind {
 ; 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
index 018905e..b69b272 100644 (file)
@@ -654,7 +654,7 @@ define i32 @fcmpri(i32 %argc, i8** nocapture readonly %argv) {
 ; 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
@@ -666,14 +666,17 @@ define i32 @fcmpri(i32 %argc, i8** nocapture readonly %argv) {
 ; 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
index 34d0d35..d704fe2 100644 (file)
@@ -103,12 +103,11 @@ define void @phi_i16() {
 ; 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
@@ -142,12 +141,11 @@ define i8 @ret_i8() {
 ; 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
@@ -180,14 +178,13 @@ exit:                                             ; preds = %if.end
 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
index 345033a..7e06a0e 100644 (file)
@@ -8,11 +8,11 @@
 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
index d419cbc..bdabe14 100644 (file)
@@ -5,18 +5,18 @@
 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
index ec21526..345b9f2 100644 (file)
@@ -471,14 +471,15 @@ define i32 @test_chr_5(i32* %i, i32 %sum0) !prof !14 {
 ; 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:
@@ -571,14 +572,15 @@ define i32 @test_chr_5_1(i32* %i, i32 %sum0) !prof !14 {
 ; 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:
@@ -668,14 +670,15 @@ define i32 @test_chr_6(i32* %i, i32* %j, i32 %sum0) !prof !14 {
 ; 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:
@@ -1753,14 +1756,15 @@ define i32 @test_chr_19(i32* %i, i32 %sum0) !prof !14 {
 ; 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:
index 8a369bb..e8bba44 100644 (file)
@@ -11,11 +11,13 @@ define dso_local void @foo(i32* %in, i64 %lo, i64 %hi, i32 %ishi) #0 {
 ; 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:
index 39cd34a..89692a4 100644 (file)
@@ -10,14 +10,18 @@ target triple = "x86_64-unknown-linux-gnu"
 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
@@ -90,8 +94,15 @@ bb3:                                              ; preds = %bb1, %bb2
 
 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
index 824f6b9..8e3bb9f 100644 (file)
@@ -64,9 +64,8 @@ T:
 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:
@@ -93,12 +92,11 @@ declare i1 @llvm.type.test(i8*, metadata) nounwind readnone
 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:
@@ -144,9 +142,8 @@ bb2:
 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:
@@ -203,9 +200,8 @@ else:
 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:
@@ -248,9 +244,8 @@ declare i8* @fn_noundef_arg(i8* noundef %p)
 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:
@@ -269,9 +264,8 @@ else:
 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:
@@ -290,9 +284,8 @@ else:
 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:
@@ -346,9 +339,8 @@ else:
 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:
@@ -387,10 +379,9 @@ else:
 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:
@@ -409,11 +400,10 @@ else:
 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:
index 2ac555c..fb08f5e 100644 (file)
@@ -1261,8 +1261,9 @@ merge:
 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:
index 2076ce5..79e92ac 100644 (file)
@@ -14,7 +14,7 @@
 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:
index eeae8b2..251aa8e 100644 (file)
@@ -15,131 +15,131 @@ define i32 @f(i32* %b) {
 ; 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:
index 4d54c05..d99de98 100644 (file)
@@ -34,9 +34,10 @@ declare i1 @llvm.type.test(i8* %ptr, metadata %bitset) nounwind readnone
 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
index bf77c36..4bf1911 100644 (file)
@@ -16,19 +16,19 @@ define i32 @align_both_equal() local_unnamed_addr {
 ; 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:
@@ -70,19 +70,19 @@ define i32 @align_not_equal() local_unnamed_addr {
 ; 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:
@@ -124,19 +124,19 @@ define i32 @align_single_zero() local_unnamed_addr {
 ; 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:
@@ -178,19 +178,19 @@ define i32 @align_single_zero_second_greater_default() local_unnamed_addr {
 ; 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:
@@ -232,19 +232,19 @@ define i32 @align_both_zero() local_unnamed_addr {
 ; 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: