[llvm] 6102310 - [InstSimplify][EarlyCSE] Try to CSE PHI nodes in the same basic block

Philip Reames via llvm-commits llvm-commits at lists.llvm.org
Thu Aug 27 12:43:42 PDT 2020


On 8/27/20 11:54 AM, Nikita Popov via llvm-commits wrote:
> On Thu, Aug 27, 2020 at 5:47 PM Roman Lebedev via llvm-commits 
> <llvm-commits at lists.llvm.org <mailto:llvm-commits at lists.llvm.org>> wrote:
>
>
>     Author: Roman Lebedev
>     Date: 2020-08-27T18:47:04+03:00
>     New Revision: 6102310d814ad73eab60a88b21dd70874f7a056f
>
>     URL:
>     https://github.com/llvm/llvm-project/commit/6102310d814ad73eab60a88b21dd70874f7a056f
>     DIFF:
>     https://github.com/llvm/llvm-project/commit/6102310d814ad73eab60a88b21dd70874f7a056f.diff
>
>     LOG: [InstSimplify][EarlyCSE] Try to CSE PHI nodes in the same
>     basic block
>
>     Apparently, we don't do this, neither in EarlyCSE, nor in
>     InstSimplify,
>     nor in (old) GVN, but do in NewGVN and SimplifyCFG of all places..
>
>     While i could teach EarlyCSE how to hash PHI nodes,
>     we can't really do much (anything?) even if we find two identical
>     PHI nodes in different basic blocks, same-BB case is the
>     interesting one,
>     and if we teach InstSimplify about it (which is what i wanted
>     originally,
>     https://reviews.llvm.org/D86530), we get EarlyCSE support for free.
>
>     So i would think this is pretty uncontroversial.
>
>     On vanilla llvm test-suite + RawSpeed, this has the following effects:
>     ```
>     | statistic name                                     | baseline  |
>     proposed  |      Δ |        % |    \|%\| |
>     |----------------------------------------------------|-----------|-----------|-------:|---------:|---------:|
>     | instsimplify.NumPHICSE                             | 0      |
>     23779     |  23779 |    0.00% |    0.00% |
>     | asm-printer.EmittedInsts                           | 7942328   |
>     7942392   |     64 |    0.00% |    0.00% |
>     | assembler.ObjectBytes                              | 273069192 |
>     273084704 |  15512 |    0.01% |    0.01% |
>     | correlated-value-propagation.NumPhis               | 18412     |
>     18539     |    127 |    0.69% |    0.69% |
>     | early-cse.NumCSE                                   | 2183283   |
>     2183227   |    -56 |    0.00% |    0.00% |
>     | early-cse.NumSimplify                              | 550105    |
>     542090    |  -8015 |   -1.46% |    1.46% |
>     | instcombine.NumAggregateReconstructionsSimplified  | 73     |
>     4506      |   4433 | 6072.60% | 6072.60% |
>     | instcombine.NumCombined                            | 3640264   |
>     3664769   |  24505 |    0.67% |    0.67% |
>     | instcombine.NumDeadInst                            | 1778193   |
>     1783183   |   4990 |    0.28% |    0.28% |
>     | instcount.NumCallInst                              | 1758401   |
>     1758799   |    398 |    0.02% |    0.02% |
>     | instcount.NumInvokeInst                            | 59478     |
>     59502     |     24 |    0.04% |    0.04% |
>     | instcount.NumPHIInst                               | 330557    |
>     330533    |    -24 |   -0.01% |    0.01% |
>     | instcount.TotalInsts                               | 8831952   |
>     8832286   |    334 |    0.00% |    0.00% |
>     | simplifycfg.NumInvokes                             | 4300     |
>     4410      |    110 |    2.56% |    2.56% |
>     | simplifycfg.NumSimpl                               | 1019808   |
>     999607    | -20201 |   -1.98% |    1.98% |
>     ```
>     I.e. it fires ~24k times, causes +110 (+2.56%) more `invoke` -> `call`
>     transforms, and counter-intuitively results in *more* instructions
>     total.
>
>     That being said, the PHI count doesn't decrease that much,
>     and looking at some examples, it seems at least some of them
>     were previously getting PHI CSE'd in SimplifyCFG of all places..
>
>     I'm adjusting `Instruction::isIdenticalToWhenDefined()` at the
>     same time.
>     As a comment in `InstCombinerImpl::visitPHINode()` already stated,
>     there are no guarantees on the ordering of the operands of a PHI node,
>     so if we just naively compare them, we may false-negatively say that
>     the nodes are not equal when the only difference is operand order,
>     which is especially important since the fold is in InstSimplify,
>     so we can't rely on InstCombine sorting them beforehand.
>
>     Fixing this for the general case is costly (geomean +0.02%),
>     and does not appear to catch anything in test-suite, but for
>     the same-BB case, it's trivial, so let's fix at least that.
>
>     As per
>     http://llvm-compile-time-tracker.com/compare.php?from=04879086b44348cad600a0a1ccbe1f7776cc3cf9&to=82bdedb888b945df1e9f130dd3ac4dd3c96e2925&stat=instructions
>     this appears to cause geomean +0.03% compile time increase
>     (regression),
>     but geomean -0.01%..-0.04% code size decrease (improvement).
>
>
> This transform seems to be breaking some new ground for InstSimplify, 
> in that it can now simplify to instructions that are not def-use 
> "reachable" from the root instruction. I'm a bit uncomfortable with 
> this as a general direction. Would we lose out much transformation 
> power if we did this in InstCombine only instead?
>
> Calling SimplifyInstruction on phi nodes is a very common pattern, and 
> pretty much all of those uses have a comment above them that 
> specifically says that the simplification call is being made to reduce 
> the phi to a common operand. It's not immediately clear that PHI CSE 
> is desired and/or safe in all those cases.
+1 to this.
>
>     Added:
>
>
>     Modified:
>         llvm/lib/Analysis/InstructionSimplify.cpp
>         llvm/lib/IR/Instruction.cpp
>         llvm/test/CodeGen/X86/statepoint-vector.ll
>         llvm/test/Transforms/EarlyCSE/phi.ll
>     llvm/test/Transforms/InstCombine/merging-multiple-stores-into-successor.ll
>     llvm/test/Transforms/InstCombine/phi-aware-aggregate-reconstruction.ll
>     llvm/test/Transforms/InstCombine/phi-equal-incoming-pointers.ll
>         llvm/test/Transforms/InstCombine/select.ll
>         llvm/test/Transforms/InstSimplify/phi-cse.ll
>         llvm/test/Transforms/JumpThreading/loop-phi.ll
>         llvm/test/Transforms/LoopVectorize/reduction.ll
>
>     Removed:
>
>
>
>     ################################################################################
>     diff  --git a/llvm/lib/Analysis/InstructionSimplify.cpp
>     b/llvm/lib/Analysis/InstructionSimplify.cpp
>     index eb0d95182c73..41217ea792c5 100644
>     --- a/llvm/lib/Analysis/InstructionSimplify.cpp
>     +++ b/llvm/lib/Analysis/InstructionSimplify.cpp
>     @@ -4403,6 +4403,19 @@ Value
>     *llvm::SimplifyExtractElementInst(Value *Vec, Value *Idx,
>
>      /// See if we can fold the given phi. If not, returns null.
>      static Value *SimplifyPHINode(PHINode *PN, const SimplifyQuery &Q) {
>     +  // Is there an identical PHI node before this one in this basic
>     block?
>     +  for (PHINode &Src : PN->getParent()->phis()) {
>
>
> This should probably check whether PN->getParent() is null. It is 
> legal to invoke Simplify queries on instructions that have not been 
> inserted yet.
>
>     +    // Once we've reached the PHI node we've been asked about,
>     stop looking.
>     +    if (&Src == PN)
>     +      break;
>     +    // If the previous PHI is currently trivially dead, ignore it,
>     +    // it might have been already recorded as being dead.
>     +    if (Src.use_empty())
>     +      continue;
>
>
> This is another indication that this general class of transforms can 
> break implicit assumptions (InstSimplify cannot simplify to a dead 
> inst, as it would not be use-def reachable).
>
>     +    if (PN->isIdenticalToWhenDefined(&Src))
>     +      return &Src;
>     +  }
>     +
>        // If all of the PHI's incoming values are the same then
>     replace the PHI node
>        // with the common value.
>        Value *CommonValue = nullptr;
>
>     diff  --git a/llvm/lib/IR/Instruction.cpp
>     b/llvm/lib/IR/Instruction.cpp
>     index bfbd801cb7a7..f09142530949 100644
>     --- a/llvm/lib/IR/Instruction.cpp
>     +++ b/llvm/lib/IR/Instruction.cpp
>     @@ -483,17 +483,33 @@ bool
>     Instruction::isIdenticalToWhenDefined(const Instruction *I) const {
>        if (getNumOperands() == 0 && I->getNumOperands() == 0)
>          return haveSameSpecialState(this, I);
>
>     -  // We have two instructions of identical opcode and #operands. 
>     Check to see
>     -  // if all operands are the same.
>     -  if (!std::equal(op_begin(), op_end(), I->op_begin()))
>     -    return false;
>     -
>     +  // PHI nodes are special.
>        if (const PHINode *thisPHI = dyn_cast<PHINode>(this)) {
>          const PHINode *otherPHI = cast<PHINode>(I);
>     -    return std::equal(thisPHI->block_begin(), thisPHI->block_end(),
>     +    // PHI nodes don't nessesairly have their operands in the
>     same order,
>     +    // so we shouldn't just compare ranges of incoming blocks/values.
>     +
>     +    // If both PHI's are in the same basic block, which is the
>     most interesting
>     +    // case, we know they must have identical predecessor list,
>     +    // so we only need to check the incoming values.
>     +    if (thisPHI->getParent() == otherPHI->getParent()) {
>     +      return all_of(thisPHI->blocks(), [thisPHI,
>     otherPHI](BasicBlock *PredBB) {
>     +        return thisPHI->getIncomingValueForBlock(PredBB) ==
>     +  otherPHI->getIncomingValueForBlock(PredBB);
>     +      });
>     +    }
>     +
>     +    // Otherwise, let's just naively compare operands/blocks.
>     +    return std::equal(op_begin(), op_end(), I->op_begin()) &&
>     +           std::equal(thisPHI->block_begin(), thisPHI->block_end(),
>                            otherPHI->block_begin());
>        }
>
>     +  // We have two instructions of identical opcode and #operands. 
>     Check to see
>     +  // if all operands are the same.
>     +  if (!std::equal(op_begin(), op_end(), I->op_begin()))
>     +    return false;
>     +
>        return haveSameSpecialState(this, I);
>      }
>
>
>     diff  --git a/llvm/test/CodeGen/X86/statepoint-vector.ll
>     b/llvm/test/CodeGen/X86/statepoint-vector.ll
>     index a7d7be8ed069..367eea88c185 100644
>     --- a/llvm/test/CodeGen/X86/statepoint-vector.ll
>     +++ b/llvm/test/CodeGen/X86/statepoint-vector.ll
>     @@ -57,16 +57,15 @@ entry:
>      define <2 x i64 addrspace(1)*> @test3(i1 %cnd, <2 x i64
>     addrspace(1)*>* %ptr) gc "statepoint-example" {
>      ; CHECK-LABEL: test3:
>      ; CHECK:       # %bb.0: # %entry
>     -; CHECK-NEXT:    subq $40, %rsp
>     -; CHECK-NEXT:    .cfi_def_cfa_offset 48
>     +; CHECK-NEXT:    subq $24, %rsp
>     +; CHECK-NEXT:    .cfi_def_cfa_offset 32
>      ; CHECK-NEXT:    testb $1, %dil
>      ; CHECK-NEXT:    movaps (%rsi), %xmm0
>      ; CHECK-NEXT:    movaps %xmm0, (%rsp)
>     -; CHECK-NEXT:    movaps %xmm0, {{[0-9]+}}(%rsp)
>      ; CHECK-NEXT:    callq do_safepoint
>      ; CHECK-NEXT:  .Ltmp2:
>      ; CHECK-NEXT:    movaps (%rsp), %xmm0
>     -; CHECK-NEXT:    addq $40, %rsp
>     +; CHECK-NEXT:    addq $24, %rsp
>      ; CHECK-NEXT:    .cfi_def_cfa_offset 8
>      ; CHECK-NEXT:    retq
>      entry:
>     @@ -115,7 +114,7 @@ entry:
>      ; Check that we can lower a constant typed as i128 correctly.  We
>     don't have
>      ; a representation of larger than 64 bit constant in the StackMap
>     format. At
>      ; the moment, this simply means spilling them, but there's a
>     potential
>     -; optimization for values representable as sext(Con64).
>     +; optimization for values representable as sext(Con64).
>      define void @test5() gc "statepoint-example" {
>      ; CHECK-LABEL: test5:
>      ; CHECK:       # %bb.0: # %entry
>     @@ -172,31 +171,17 @@ entry:
>      ; CHECK: .long 0
>
>      ; CHECK: .Ltmp2-test3
>     -; Check for the four spill slots
>     -; Stack Maps:          Loc 3: Indirect 7+16    [encoding: .byte
>     3, .byte 0, .short 16, .short 7, .short 0, .int 16]
>     -; Stack Maps:          Loc 4: Indirect 7+16    [encoding: .byte
>     3, .byte 0, .short 16, .short 7, .short 0, .int 16]
>     -; Stack Maps:          Loc 5: Indirect 7+16    [encoding: .byte
>     3, .byte 0, .short 16, .short 7, .short 0, .int 16]
>     -; Stack Maps:          Loc 6: Indirect 7+0     [encoding: .byte
>     3, .byte 0, .short 16, .short 7, .short 0, .int 0]
>     +; Check for the two spill slots
>     +; Stack Maps:          Loc 3: Indirect 7+0     [encoding: .byte
>     3, .byte 0, .short 16, .short 7, .short 0, .int 0]
>     +; Stack Maps:          Loc 4: Indirect 7+0     [encoding: .byte
>     3, .byte 0, .short 16, .short 7, .short 0, .int 0]
>      ; CHECK: .byte 3
>      ; CHECK: .byte 0
>      ; CHECK: .short 16
>      ; CHECK: .short        7
>      ; CHECK: .short        0
>     -; CHECK: .long 16
>     -; CHECK: .byte 3
>     -; CHECK: .byte  0
>     -; CHECK: .short 16
>     -; CHECK: .short        7
>     -; CHECK: .short        0
>     -; CHECK: .long 16
>     -; CHECK: .byte 3
>     -; CHECK: .byte  0
>     -; CHECK: .short 16
>     -; CHECK: .short        7
>     -; CHECK: .short        0
>     -; CHECK: .long 16
>     +; CHECK: .long 0
>      ; CHECK: .byte 3
>     -; CHECK: .byte  0
>     +; CHECK: .byte 0
>      ; CHECK: .short 16
>      ; CHECK: .short        7
>      ; CHECK: .short        0
>
>     diff  --git a/llvm/test/Transforms/EarlyCSE/phi.ll
>     b/llvm/test/Transforms/EarlyCSE/phi.ll
>     index 2c2972be5104..efe08a63948e 100644
>     --- a/llvm/test/Transforms/EarlyCSE/phi.ll
>     +++ b/llvm/test/Transforms/EarlyCSE/phi.ll
>     @@ -13,9 +13,8 @@ define void @test0(i32 %v0, i32 %v1, i1 %c, i32*
>     %d0, i32* %d1) {
>      ; CHECK-NEXT:    br label [[END]]
>      ; CHECK:       end:
>      ; CHECK-NEXT:    [[I0:%.*]] = phi i32 [ [[V0:%.*]], [[B0]] ], [
>     [[V1:%.*]], [[B1]] ]
>     -; CHECK-NEXT:    [[I1:%.*]] = phi i32 [ [[V0]], [[B0]] ], [
>     [[V1]], [[B1]] ]
>      ; CHECK-NEXT:    store i32 [[I0]], i32* [[D0:%.*]], align 4
>     -; CHECK-NEXT:    store i32 [[I1]], i32* [[D1:%.*]], align 4
>     +; CHECK-NEXT:    store i32 [[I0]], i32* [[D1:%.*]], align 4
>      ; CHECK-NEXT:    ret void
>      ;
>      entry:
>     @@ -46,9 +45,8 @@ define void @test1(i32 %v0, i32 %v1, i1 %c, i32*
>     %d0, i32* %d1) {
>      ; CHECK-NEXT:    br label [[END]]
>      ; CHECK:       end:
>      ; CHECK-NEXT:    [[I0:%.*]] = phi i32 [ [[V0:%.*]], [[B0]] ], [
>     [[V1:%.*]], [[B1]] ]
>     -; CHECK-NEXT:    [[I1:%.*]] = phi i32 [ [[V1]], [[B1]] ], [
>     [[V0]], [[B0]] ]
>      ; CHECK-NEXT:    store i32 [[I0]], i32* [[D0:%.*]], align 4
>     -; CHECK-NEXT:    store i32 [[I1]], i32* [[D1:%.*]], align 4
>     +; CHECK-NEXT:    store i32 [[I0]], i32* [[D1:%.*]], align 4
>      ; CHECK-NEXT:    ret void
>      ;
>      entry:
>     @@ -141,9 +139,8 @@ define void @negative_test4(i32 %v0, i32 %v1,
>     i1 %c, i32* %d0, i32* %d1) {
>      ; CHECK-NEXT:    br label [[END]]
>      ; CHECK:       end:
>      ; CHECK-NEXT:    [[I0:%.*]] = phi i32 [ [[V0:%.*]], [[B0]] ], [
>     [[V1:%.*]], [[B1]] ]
>     -; CHECK-NEXT:    [[I1:%.*]] = phi i32 [ [[V1]], [[B1]] ], [
>     [[V0]], [[B0]] ]
>      ; CHECK-NEXT:    store i32 [[I0]], i32* [[D0:%.*]], align 4
>     -; CHECK-NEXT:    store i32 [[I1]], i32* [[D1:%.*]], align 4
>     +; CHECK-NEXT:    store i32 [[I0]], i32* [[D1:%.*]], align 4
>      ; CHECK-NEXT:    ret void
>      ;
>      entry:
>     @@ -234,9 +231,8 @@ define void @test7(i32 %v0, i32 %v1, i16 %v2,
>     i16 %v3, i1 %c, i32* %d0, i32* %d1
>      ; CHECK:       end:
>      ; CHECK-NEXT:    [[IBAD:%.*]] = phi i16 [ [[V2:%.*]], [[B0]] ], [
>     [[V3:%.*]], [[B1]] ]
>      ; CHECK-NEXT:    [[I0:%.*]] = phi i32 [ [[V0:%.*]], [[B0]] ], [
>     [[V1:%.*]], [[B1]] ]
>     -; CHECK-NEXT:    [[I1:%.*]] = phi i32 [ [[V0]], [[B0]] ], [
>     [[V1]], [[B1]] ]
>      ; CHECK-NEXT:    store i32 [[I0]], i32* [[D0:%.*]], align 4
>     -; CHECK-NEXT:    store i32 [[I1]], i32* [[D1:%.*]], align 4
>     +; CHECK-NEXT:    store i32 [[I0]], i32* [[D1:%.*]], align 4
>      ; CHECK-NEXT:    store i16 [[IBAD]], i16* [[D2:%.*]], align 2
>      ; CHECK-NEXT:    ret void
>      ;
>     @@ -269,9 +265,8 @@ define void @test8(i32 %v0, i32 %v1, i16 %v2,
>     i16 %v3, i1 %c, i32* %d0, i32* %d1
>      ; CHECK:       end:
>      ; CHECK-NEXT:    [[I0:%.*]] = phi i32 [ [[V0:%.*]], [[B0]] ], [
>     [[V1:%.*]], [[B1]] ]
>      ; CHECK-NEXT:    [[IBAD:%.*]] = phi i16 [ [[V2:%.*]], [[B0]] ], [
>     [[V3:%.*]], [[B1]] ]
>     -; CHECK-NEXT:    [[I1:%.*]] = phi i32 [ [[V0]], [[B0]] ], [
>     [[V1]], [[B1]] ]
>      ; CHECK-NEXT:    store i32 [[I0]], i32* [[D0:%.*]], align 4
>     -; CHECK-NEXT:    store i32 [[I1]], i32* [[D1:%.*]], align 4
>     +; CHECK-NEXT:    store i32 [[I0]], i32* [[D1:%.*]], align 4
>      ; CHECK-NEXT:    store i16 [[IBAD]], i16* [[D2:%.*]], align 2
>      ; CHECK-NEXT:    ret void
>      ;
>     @@ -303,10 +298,9 @@ define void @test9(i32 %v0, i32 %v1, i16 %v2,
>     i16 %v3, i1 %c, i32* %d0, i32* %d1
>      ; CHECK-NEXT:    br label [[END]]
>      ; CHECK:       end:
>      ; CHECK-NEXT:    [[I0:%.*]] = phi i32 [ [[V0:%.*]], [[B0]] ], [
>     [[V1:%.*]], [[B1]] ]
>     -; CHECK-NEXT:    [[I1:%.*]] = phi i32 [ [[V0]], [[B0]] ], [
>     [[V1]], [[B1]] ]
>      ; CHECK-NEXT:    [[IBAD:%.*]] = phi i16 [ [[V2:%.*]], [[B0]] ], [
>     [[V3:%.*]], [[B1]] ]
>      ; CHECK-NEXT:    store i32 [[I0]], i32* [[D0:%.*]], align 4
>     -; CHECK-NEXT:    store i32 [[I1]], i32* [[D1:%.*]], align 4
>     +; CHECK-NEXT:    store i32 [[I0]], i32* [[D1:%.*]], align 4
>      ; CHECK-NEXT:    store i16 [[IBAD]], i16* [[D2:%.*]], align 2
>      ; CHECK-NEXT:    ret void
>      ;
>
>     diff  --git
>     a/llvm/test/Transforms/InstCombine/merging-multiple-stores-into-successor.ll
>     b/llvm/test/Transforms/InstCombine/merging-multiple-stores-into-successor.ll
>     index 5be341fa6228..be00822834d8 100644
>     ---
>     a/llvm/test/Transforms/InstCombine/merging-multiple-stores-into-successor.ll
>     +++
>     b/llvm/test/Transforms/InstCombine/merging-multiple-stores-into-successor.ll
>     @@ -1,5 +1,5 @@
>      ; NOTE: Assertions have been autogenerated by
>     utils/update_test_checks.py
>     -; RUN: opt %s -instcombine -instcombine-infinite-loop-threshold=2
>     -S | FileCheck %s
>     +; RUN: opt %s -instcombine -instcombine-infinite-loop-threshold=3
>     -S | FileCheck %s
>
>      @var_7 = external global i8, align 1
>      @var_1 = external global i32, align 4
>     @@ -29,11 +29,10 @@ define void @_Z4testv() {
>      ; CHECK-NEXT:    br label [[BB12]]
>      ; CHECK:       bb12:
>      ; CHECK-NEXT:    [[STOREMERGE1:%.*]] = phi i32 [ [[I11]],
>     [[BB10]] ], [ 1, [[BB9]] ]
>     -; CHECK-NEXT:    [[STOREMERGE:%.*]] = phi i32 [ [[I11]], [[BB10]]
>     ], [ 1, [[BB9]] ]
>      ; CHECK-NEXT:    store i32 [[STOREMERGE1]], i32* getelementptr
>     inbounds ([0 x i32], [0 x i32]* @arr_2, i64 0, i64 0), align 4
>      ; CHECK-NEXT:    store i16 [[I4]], i16* getelementptr inbounds
>     ([0 x i16], [0 x i16]* @arr_4, i64 0, i64 0), align 2
>      ; CHECK-NEXT:    store i32 [[I8]], i32* getelementptr inbounds
>     ([8 x i32], [8 x i32]* @arr_3, i64 0, i64 0), align 16
>     -; CHECK-NEXT:    store i32 [[STOREMERGE]], i32* getelementptr
>     inbounds ([0 x i32], [0 x i32]* @arr_2, i64 0, i64 1), align 4
>     +; CHECK-NEXT:    store i32 [[STOREMERGE1]], i32* getelementptr
>     inbounds ([0 x i32], [0 x i32]* @arr_2, i64 0, i64 1), align 4
>      ; CHECK-NEXT:    store i16 [[I4]], i16* getelementptr inbounds
>     ([0 x i16], [0 x i16]* @arr_4, i64 0, i64 1), align 2
>      ; CHECK-NEXT:    store i32 [[I8]], i32* getelementptr inbounds
>     ([8 x i32], [8 x i32]* @arr_3, i64 0, i64 1), align 4
>      ; CHECK-NEXT:    ret void
>
>     diff  --git
>     a/llvm/test/Transforms/InstCombine/phi-aware-aggregate-reconstruction.ll
>     b/llvm/test/Transforms/InstCombine/phi-aware-aggregate-reconstruction.ll
>     index 866750c27177..0befa4b7a2ad 100644
>     ---
>     a/llvm/test/Transforms/InstCombine/phi-aware-aggregate-reconstruction.ll
>     +++
>     b/llvm/test/Transforms/InstCombine/phi-aware-aggregate-reconstruction.ll
>     @@ -25,13 +25,8 @@ define { i32, i32 } @test0({ i32, i32 }
>     %agg_left, { i32, i32 } %agg_right, i1 %
>      ; CHECK-NEXT:    br label [[END]]
>      ; CHECK:       end:
>      ; CHECK-NEXT:    [[AGG_LEFT_PN:%.*]] = phi { i32, i32 } [
>     [[AGG_LEFT:%.*]], [[LEFT]] ], [ [[AGG_RIGHT:%.*]], [[RIGHT]] ]
>     -; CHECK-NEXT:    [[AGG_LEFT_PN1:%.*]] = phi { i32, i32 } [
>     [[AGG_LEFT]], [[LEFT]] ], [ [[AGG_RIGHT]], [[RIGHT]] ]
>     -; CHECK-NEXT:    [[I6:%.*]] = extractvalue { i32, i32 }
>     [[AGG_LEFT_PN1]], 1
>     -; CHECK-NEXT:    [[I5:%.*]] = extractvalue { i32, i32 }
>     [[AGG_LEFT_PN]], 0
>      ; CHECK-NEXT:    call void @baz()
>     -; CHECK-NEXT:    [[I7:%.*]] = insertvalue { i32, i32 } undef, i32
>     [[I5]], 0
>     -; CHECK-NEXT:    [[I8:%.*]] = insertvalue { i32, i32 } [[I7]],
>     i32 [[I6]], 1
>     -; CHECK-NEXT:    ret { i32, i32 } [[I8]]
>     +; CHECK-NEXT:    ret { i32, i32 } [[AGG_LEFT_PN]]
>      ;
>      entry:
>        br i1 %c, label %left, label %right
>     @@ -162,19 +157,13 @@ define { i32, i32 } @test3({ i32, i32 }
>     %agg_00, { i32, i32 } %agg_01, { i32, i3
>      ; CHECK-NEXT:    br label [[BB0_MERGE]]
>      ; CHECK:       bb0.merge:
>      ; CHECK-NEXT:    [[AGG_00_PN:%.*]] = phi { i32, i32 } [
>     [[AGG_00:%.*]], [[BB00]] ], [ [[AGG_01:%.*]], [[BB01]] ]
>     -; CHECK-NEXT:    [[AGG_00_PN1:%.*]] = phi { i32, i32 } [
>     [[AGG_00]], [[BB00]] ], [ [[AGG_01]], [[BB01]] ]
>      ; CHECK-NEXT:    br label [[END:%.*]]
>      ; CHECK:       bb10:
>      ; CHECK-NEXT:    br label [[END]]
>      ; CHECK:       end:
>      ; CHECK-NEXT:    [[AGG_00_PN_PN:%.*]] = phi { i32, i32 } [
>     [[AGG_00_PN]], [[BB0_MERGE]] ], [ [[AGG_10:%.*]], [[BB10]] ]
>     -; CHECK-NEXT:    [[AGG_00_PN1_PN:%.*]] = phi { i32, i32 } [
>     [[AGG_00_PN1]], [[BB0_MERGE]] ], [ [[AGG_10]], [[BB10]] ]
>     -; CHECK-NEXT:    [[I9:%.*]] = extractvalue { i32, i32 }
>     [[AGG_00_PN1_PN]], 1
>     -; CHECK-NEXT:    [[I8:%.*]] = extractvalue { i32, i32 }
>     [[AGG_00_PN_PN]], 0
>      ; CHECK-NEXT:    call void @baz()
>     -; CHECK-NEXT:    [[I10:%.*]] = insertvalue { i32, i32 } undef,
>     i32 [[I8]], 0
>     -; CHECK-NEXT:    [[I11:%.*]] = insertvalue { i32, i32 } [[I10]],
>     i32 [[I9]], 1
>     -; CHECK-NEXT:    ret { i32, i32 } [[I11]]
>     +; CHECK-NEXT:    ret { i32, i32 } [[AGG_00_PN_PN]]
>      ;
>      entry:
>        br i1 %c0, label %bb0.dispatch, label %bb10
>     @@ -277,17 +266,12 @@ define { i32, i32 } @test5({ i32, i32 }
>     %agg_left, { i32, i32 } %agg_right, i1 %
>      ; CHECK-NEXT:    call void @bar()
>      ; CHECK-NEXT:    br label [[MIDDLE]]
>      ; CHECK:       middle:
>     -; CHECK-NEXT:    [[AGG_LEFT_PN:%.*]] = phi { i32, i32 } [
>     [[AGG_LEFT:%.*]], [[LEFT]] ], [ [[AGG_RIGHT:%.*]], [[RIGHT]] ], [
>     [[I8:%.*]], [[MIDDLE]] ]
>     -; CHECK-NEXT:    [[AGG_LEFT_PN1:%.*]] = phi { i32, i32 } [
>     [[AGG_LEFT]], [[LEFT]] ], [ [[AGG_RIGHT]], [[RIGHT]] ], [ [[I8]],
>     [[MIDDLE]] ]
>     -; CHECK-NEXT:    [[I6:%.*]] = extractvalue { i32, i32 }
>     [[AGG_LEFT_PN1]], 1
>     -; CHECK-NEXT:    [[I5:%.*]] = extractvalue { i32, i32 }
>     [[AGG_LEFT_PN]], 0
>     +; CHECK-NEXT:    [[AGG_LEFT_PN:%.*]] = phi { i32, i32 } [
>     [[AGG_LEFT:%.*]], [[LEFT]] ], [ [[AGG_RIGHT:%.*]], [[RIGHT]] ], [
>     [[AGG_LEFT_PN]], [[MIDDLE]] ]
>      ; CHECK-NEXT:    call void @baz()
>     -; CHECK-NEXT:    [[I7:%.*]] = insertvalue { i32, i32 } undef, i32
>     [[I5]], 0
>     -; CHECK-NEXT:    [[I8]] = insertvalue { i32, i32 } [[I7]], i32
>     [[I6]], 1
>      ; CHECK-NEXT:    [[C1:%.*]] = call i1 @geni1()
>      ; CHECK-NEXT:    br i1 [[C1]], label [[END:%.*]], label [[MIDDLE]]
>      ; CHECK:       end:
>     -; CHECK-NEXT:    ret { i32, i32 } [[I8]]
>     +; CHECK-NEXT:    ret { i32, i32 } [[AGG_LEFT_PN]]
>      ;
>      entry:
>        br i1 %c0, label %left, label %right
>     @@ -332,19 +316,14 @@ define { i32, i32 } @test6({ i32, i32 }
>     %agg_left, { i32, i32 } %agg_right, i1 %
>      ; CHECK-NEXT:    br label [[MERGE]]
>      ; CHECK:       merge:
>      ; CHECK-NEXT:    [[AGG_LEFT_PN:%.*]] = phi { i32, i32 } [
>     [[AGG_LEFT:%.*]], [[LEFT]] ], [ [[AGG_RIGHT:%.*]], [[RIGHT]] ]
>     -; CHECK-NEXT:    [[AGG_LEFT_PN1:%.*]] = phi { i32, i32 } [
>     [[AGG_LEFT]], [[LEFT]] ], [ [[AGG_RIGHT]], [[RIGHT]] ]
>      ; CHECK-NEXT:    call void @baz()
>      ; CHECK-NEXT:    br i1 [[C1:%.*]], label [[END:%.*]], label
>     [[PASSTHROUGH:%.*]]
>      ; CHECK:       passthrough:
>      ; CHECK-NEXT:    call void @qux()
>      ; CHECK-NEXT:    br label [[END]]
>      ; CHECK:       end:
>     -; CHECK-NEXT:    [[I6:%.*]] = extractvalue { i32, i32 }
>     [[AGG_LEFT_PN1]], 1
>     -; CHECK-NEXT:    [[I5:%.*]] = extractvalue { i32, i32 }
>     [[AGG_LEFT_PN]], 0
>      ; CHECK-NEXT:    call void @quux()
>     -; CHECK-NEXT:    [[I7:%.*]] = insertvalue { i32, i32 } undef, i32
>     [[I5]], 0
>     -; CHECK-NEXT:    [[I8:%.*]] = insertvalue { i32, i32 } [[I7]],
>     i32 [[I6]], 1
>     -; CHECK-NEXT:    ret { i32, i32 } [[I8]]
>     +; CHECK-NEXT:    ret { i32, i32 } [[AGG_LEFT_PN]]
>      ;
>      entry:
>        br i1 %c0, label %left, label %right
>     @@ -451,13 +430,8 @@ define { i32, i32 } @test8({ i32, i32 }
>     %agg_left, { i32, i32 } %agg_right, i1 %
>      ; CHECK-NEXT:    unreachable
>      ; CHECK:       end:
>      ; CHECK-NEXT:    [[AGG_LEFT_PN:%.*]] = phi { i32, i32 } [
>     [[AGG_LEFT:%.*]], [[LEFT]] ], [ [[AGG_LEFT]], [[LEFT]] ], [
>     [[AGG_RIGHT:%.*]], [[RIGHT]] ], [ [[AGG_RIGHT]], [[RIGHT]] ]
>     -; CHECK-NEXT:    [[AGG_LEFT_PN1:%.*]] = phi { i32, i32 } [
>     [[AGG_LEFT]], [[LEFT]] ], [ [[AGG_LEFT]], [[LEFT]] ], [
>     [[AGG_RIGHT]], [[RIGHT]] ], [ [[AGG_RIGHT]], [[RIGHT]] ]
>     -; CHECK-NEXT:    [[I6:%.*]] = extractvalue { i32, i32 }
>     [[AGG_LEFT_PN1]], 1
>     -; CHECK-NEXT:    [[I5:%.*]] = extractvalue { i32, i32 }
>     [[AGG_LEFT_PN]], 0
>      ; CHECK-NEXT:    call void @baz()
>     -; CHECK-NEXT:    [[I7:%.*]] = insertvalue { i32, i32 } undef, i32
>     [[I5]], 0
>     -; CHECK-NEXT:    [[I8:%.*]] = insertvalue { i32, i32 } [[I7]],
>     i32 [[I6]], 1
>     -; CHECK-NEXT:    ret { i32, i32 } [[I8]]
>     +; CHECK-NEXT:    ret { i32, i32 } [[AGG_LEFT_PN]]
>      ;
>      entry:
>        br i1 %c, label %left, label %right
>     @@ -505,13 +479,8 @@ define { i32, i32 } @test9({ i32, i32 }
>     %agg_left, { i32, i32 } %agg_right, i1 %
>      ; CHECK-NEXT:    br label [[END]]
>      ; CHECK:       end:
>      ; CHECK-NEXT:    [[AGG_LEFT_PN:%.*]] = phi { i32, i32 } [
>     [[AGG_LEFT:%.*]], [[LEFT]] ], [ [[AGG_RIGHT:%.*]], [[RIGHT]] ]
>     -; CHECK-NEXT:    [[AGG_LEFT_PN1:%.*]] = phi { i32, i32 } [
>     [[AGG_LEFT]], [[LEFT]] ], [ [[AGG_RIGHT]], [[RIGHT]] ]
>     -; CHECK-NEXT:    [[I7:%.*]] = extractvalue { i32, i32 }
>     [[AGG_LEFT_PN1]], 1
>     -; CHECK-NEXT:    [[I0_PN:%.*]] = extractvalue { i32, i32 }
>     [[AGG_LEFT_PN]], 0
>     -; CHECK-NEXT:    [[I6:%.*]] = insertvalue { i32, i32 } undef, i32
>     [[I0_PN]], 0
>      ; CHECK-NEXT:    call void @baz()
>     -; CHECK-NEXT:    [[I8:%.*]] = insertvalue { i32, i32 } [[I6]],
>     i32 [[I7]], 1
>     -; CHECK-NEXT:    ret { i32, i32 } [[I8]]
>     +; CHECK-NEXT:    ret { i32, i32 } [[AGG_LEFT_PN]]
>      ;
>      entry:
>        br i1 %c, label %left, label %right
>
>     diff  --git
>     a/llvm/test/Transforms/InstCombine/phi-equal-incoming-pointers.ll
>     b/llvm/test/Transforms/InstCombine/phi-equal-incoming-pointers.ll
>     index db5402bd78c1..4e37dfc1357f 100644
>     --- a/llvm/test/Transforms/InstCombine/phi-equal-incoming-pointers.ll
>     +++ b/llvm/test/Transforms/InstCombine/phi-equal-incoming-pointers.ll
>     @@ -15,17 +15,13 @@ define i32 @test_gep_and_bitcast(i1 %cond, i1
>     %cond2) {
>      ; ALL-NEXT:    [[OBJ:%.*]] = call i8* @get_ptr.i8()
>      ; ALL-NEXT:    br i1 [[COND:%.*]], label [[BB1:%.*]], label
>     [[BB2:%.*]]
>      ; ALL:       bb1:
>     -; ALL-NEXT:    [[PTR1:%.*]] = getelementptr inbounds i8, i8*
>     [[OBJ]], i64 16
>     -; ALL-NEXT:    [[PTR1_TYPED:%.*]] = bitcast i8* [[PTR1]] to i32*
>      ; ALL-NEXT:    br label [[EXIT:%.*]]
>      ; ALL:       bb2:
>     -; ALL-NEXT:    [[PTR2:%.*]] = getelementptr inbounds i8, i8*
>     [[OBJ]], i64 16
>     -; ALL-NEXT:    [[PTR2_TYPED:%.*]] = bitcast i8* [[PTR2]] to i32*
>      ; ALL-NEXT:    br label [[EXIT]]
>      ; ALL:       exit:
>     -; ALL-NEXT:    [[PTR_TYPED:%.*]] = phi i32* [ [[PTR1_TYPED]],
>     [[BB1]] ], [ [[PTR2_TYPED]], [[BB2]] ]
>     -; ALL-NEXT:    [[RES_PHI_IN:%.*]] = phi i32* [ [[PTR1_TYPED]],
>     [[BB1]] ], [ [[PTR2_TYPED]], [[BB2]] ]
>     -; ALL-NEXT:    [[RES_PHI:%.*]] = load i32, i32* [[RES_PHI_IN]],
>     align 4
>     +; ALL-NEXT:    [[PTR_TYPED_IN:%.*]] = getelementptr inbounds i8,
>     i8* [[OBJ]], i64 16
>     +; ALL-NEXT:    [[PTR_TYPED:%.*]] = bitcast i8* [[PTR_TYPED_IN]]
>     to i32*
>     +; ALL-NEXT:    [[RES_PHI:%.*]] = load i32, i32* [[PTR_TYPED]],
>     align 4
>      ; ALL-NEXT:    store i32 1, i32* [[PTR_TYPED]], align 4
>      ; ALL-NEXT:    [[RES:%.*]] = select i1 [[COND2:%.*]], i32
>     [[RES_PHI]], i32 1
>      ; ALL-NEXT:    ret i32 [[RES]]
>     @@ -60,17 +56,13 @@ define i32 @test_gep_and_bitcast_arg(i8* %obj,
>     i1 %cond, i1 %cond2) {
>      ; ALL-NEXT:  entry:
>      ; ALL-NEXT:    br i1 [[COND:%.*]], label [[BB1:%.*]], label
>     [[BB2:%.*]]
>      ; ALL:       bb1:
>     -; ALL-NEXT:    [[PTR1:%.*]] = getelementptr inbounds i8, i8*
>     [[OBJ:%.*]], i64 16
>     -; ALL-NEXT:    [[PTR1_TYPED:%.*]] = bitcast i8* [[PTR1]] to i32*
>      ; ALL-NEXT:    br label [[EXIT:%.*]]
>      ; ALL:       bb2:
>     -; ALL-NEXT:    [[PTR2:%.*]] = getelementptr inbounds i8, i8*
>     [[OBJ]], i64 16
>     -; ALL-NEXT:    [[PTR2_TYPED:%.*]] = bitcast i8* [[PTR2]] to i32*
>      ; ALL-NEXT:    br label [[EXIT]]
>      ; ALL:       exit:
>     -; ALL-NEXT:    [[PTR_TYPED:%.*]] = phi i32* [ [[PTR1_TYPED]],
>     [[BB1]] ], [ [[PTR2_TYPED]], [[BB2]] ]
>     -; ALL-NEXT:    [[RES_PHI_IN:%.*]] = phi i32* [ [[PTR1_TYPED]],
>     [[BB1]] ], [ [[PTR2_TYPED]], [[BB2]] ]
>     -; ALL-NEXT:    [[RES_PHI:%.*]] = load i32, i32* [[RES_PHI_IN]],
>     align 4
>     +; ALL-NEXT:    [[PTR_TYPED_IN:%.*]] = getelementptr inbounds i8,
>     i8* [[OBJ:%.*]], i64 16
>     +; ALL-NEXT:    [[PTR_TYPED:%.*]] = bitcast i8* [[PTR_TYPED_IN]]
>     to i32*
>     +; ALL-NEXT:    [[RES_PHI:%.*]] = load i32, i32* [[PTR_TYPED]],
>     align 4
>      ; ALL-NEXT:    store i32 1, i32* [[PTR_TYPED]], align 4
>      ; ALL-NEXT:    [[RES:%.*]] = select i1 [[COND2:%.*]], i32
>     [[RES_PHI]], i32 1
>      ; ALL-NEXT:    ret i32 [[RES]]
>     @@ -116,17 +108,13 @@ define i32 @test_gep_and_bitcast_phi(i1
>     %cond, i1 %cond2, i1 %cond3) {
>      ; ALL-NEXT:    call void @foo.i8(i8* [[ANOTHER_PHI]])
>      ; ALL-NEXT:    br i1 [[COND2:%.*]], label [[BB3:%.*]], label
>     [[BB4:%.*]]
>      ; ALL:       bb3:
>     -; ALL-NEXT:    [[PTR1:%.*]] = getelementptr inbounds i8, i8*
>     [[OBJ]], i64 16
>     -; ALL-NEXT:    [[PTR1_TYPED:%.*]] = bitcast i8* [[PTR1]] to i32*
>      ; ALL-NEXT:    br label [[EXIT:%.*]]
>      ; ALL:       bb4:
>     -; ALL-NEXT:    [[PTR2:%.*]] = getelementptr inbounds i8, i8*
>     [[OBJ]], i64 16
>     -; ALL-NEXT:    [[PTR2_TYPED:%.*]] = bitcast i8* [[PTR2]] to i32*
>      ; ALL-NEXT:    br label [[EXIT]]
>      ; ALL:       exit:
>     -; ALL-NEXT:    [[PTR_TYPED:%.*]] = phi i32* [ [[PTR1_TYPED]],
>     [[BB3]] ], [ [[PTR2_TYPED]], [[BB4]] ]
>     -; ALL-NEXT:    [[RES_PHI_IN:%.*]] = phi i32* [ [[PTR1_TYPED]],
>     [[BB3]] ], [ [[PTR2_TYPED]], [[BB4]] ]
>     -; ALL-NEXT:    [[RES_PHI:%.*]] = load i32, i32* [[RES_PHI_IN]],
>     align 4
>     +; ALL-NEXT:    [[PTR_TYPED_IN:%.*]] = getelementptr inbounds i8,
>     i8* [[OBJ]], i64 16
>     +; ALL-NEXT:    [[PTR_TYPED:%.*]] = bitcast i8* [[PTR_TYPED_IN]]
>     to i32*
>     +; ALL-NEXT:    [[RES_PHI:%.*]] = load i32, i32* [[PTR_TYPED]],
>     align 4
>      ; ALL-NEXT:    store i32 1, i32* [[PTR_TYPED]], align 4
>      ; ALL-NEXT:    [[RES:%.*]] = select i1 [[COND3:%.*]], i32
>     [[RES_PHI]], i32 1
>      ; ALL-NEXT:    ret i32 [[RES]]
>     @@ -176,15 +164,12 @@ define i32 @test_gep_i32ptr(i1 %cond, i1
>     %cond2) {
>      ; ALL-NEXT:    [[OBJ:%.*]] = call i32* @get_ptr.i32()
>      ; ALL-NEXT:    br i1 [[COND:%.*]], label [[BB1:%.*]], label
>     [[BB2:%.*]]
>      ; ALL:       bb1:
>     -; ALL-NEXT:    [[PTR1_TYPED:%.*]] = getelementptr inbounds i32,
>     i32* [[OBJ]], i64 16
>      ; ALL-NEXT:    br label [[EXIT:%.*]]
>      ; ALL:       bb2:
>     -; ALL-NEXT:    [[PTR2_TYPED:%.*]] = getelementptr inbounds i32,
>     i32* [[OBJ]], i64 16
>      ; ALL-NEXT:    br label [[EXIT]]
>      ; ALL:       exit:
>     -; ALL-NEXT:    [[PTR_TYPED:%.*]] = phi i32* [ [[PTR1_TYPED]],
>     [[BB1]] ], [ [[PTR2_TYPED]], [[BB2]] ]
>     -; ALL-NEXT:    [[RES_PHI_IN:%.*]] = phi i32* [ [[PTR1_TYPED]],
>     [[BB1]] ], [ [[PTR2_TYPED]], [[BB2]] ]
>     -; ALL-NEXT:    [[RES_PHI:%.*]] = load i32, i32* [[RES_PHI_IN]],
>     align 4
>     +; ALL-NEXT:    [[PTR_TYPED:%.*]] = getelementptr inbounds i32,
>     i32* [[OBJ]], i64 16
>     +; ALL-NEXT:    [[RES_PHI:%.*]] = load i32, i32* [[PTR_TYPED]],
>     align 4
>      ; ALL-NEXT:    store i32 1, i32* [[PTR_TYPED]], align 4
>      ; ALL-NEXT:    [[RES:%.*]] = select i1 [[COND2:%.*]], i32
>     [[RES_PHI]], i32 1
>      ; ALL-NEXT:    ret i32 [[RES]]
>     @@ -218,17 +203,13 @@ define i32
>     @test_gep_and_bitcast_gep_base_ptr(i1 %cond, i1 %cond2) {
>      ; ALL-NEXT:    [[OBJ0:%.*]] = call i8* @get_ptr.i8()
>      ; ALL-NEXT:    br i1 [[COND:%.*]], label [[BB1:%.*]], label
>     [[BB2:%.*]]
>      ; ALL:       bb1:
>     -; ALL-NEXT:    [[PTR1:%.*]] = getelementptr inbounds i8, i8*
>     [[OBJ0]], i64 32
>     -; ALL-NEXT:    [[PTR1_TYPED:%.*]] = bitcast i8* [[PTR1]] to i32*
>      ; ALL-NEXT:    br label [[EXIT:%.*]]
>      ; ALL:       bb2:
>     -; ALL-NEXT:    [[PTR2:%.*]] = getelementptr inbounds i8, i8*
>     [[OBJ0]], i64 32
>     -; ALL-NEXT:    [[PTR2_TYPED:%.*]] = bitcast i8* [[PTR2]] to i32*
>      ; ALL-NEXT:    br label [[EXIT]]
>      ; ALL:       exit:
>     -; ALL-NEXT:    [[PTR_TYPED:%.*]] = phi i32* [ [[PTR1_TYPED]],
>     [[BB1]] ], [ [[PTR2_TYPED]], [[BB2]] ]
>     -; ALL-NEXT:    [[RES_PHI_IN:%.*]] = phi i32* [ [[PTR1_TYPED]],
>     [[BB1]] ], [ [[PTR2_TYPED]], [[BB2]] ]
>     -; ALL-NEXT:    [[RES_PHI:%.*]] = load i32, i32* [[RES_PHI_IN]],
>     align 4
>     +; ALL-NEXT:    [[PTR_TYPED_IN:%.*]] = getelementptr inbounds i8,
>     i8* [[OBJ0]], i64 32
>     +; ALL-NEXT:    [[PTR_TYPED:%.*]] = bitcast i8* [[PTR_TYPED_IN]]
>     to i32*
>     +; ALL-NEXT:    [[RES_PHI:%.*]] = load i32, i32* [[PTR_TYPED]],
>     align 4
>      ; ALL-NEXT:    store i32 1, i32* [[PTR_TYPED]], align 4
>      ; ALL-NEXT:    [[RES:%.*]] = select i1 [[COND2:%.*]], i32
>     [[RES_PHI]], i32 1
>      ; ALL-NEXT:    ret i32 [[RES]]
>     @@ -260,37 +241,19 @@ exit:
>      }
>
>      define i32 @test_gep_and_bitcast_same_bb(i1 %cond, i1 %cond2) {
>     -; INSTCOMBINE-LABEL: @test_gep_and_bitcast_same_bb(
>     -; INSTCOMBINE-NEXT:  entry:
>     -; INSTCOMBINE-NEXT:    [[OBJ:%.*]] = call i8* @get_ptr.i8()
>     -; INSTCOMBINE-NEXT:    [[PTR1:%.*]] = getelementptr inbounds i8,
>     i8* [[OBJ]], i64 16
>     -; INSTCOMBINE-NEXT:    [[PTR1_TYPED:%.*]] = bitcast i8* [[PTR1]]
>     to i32*
>     -; INSTCOMBINE-NEXT:    br i1 [[COND:%.*]], label [[EXIT:%.*]],
>     label [[BB2:%.*]]
>     -; INSTCOMBINE:       bb2:
>     -; INSTCOMBINE-NEXT:    [[PTR2:%.*]] = getelementptr inbounds i8,
>     i8* [[OBJ]], i64 16
>     -; INSTCOMBINE-NEXT:    [[PTR2_TYPED:%.*]] = bitcast i8* [[PTR2]]
>     to i32*
>     -; INSTCOMBINE-NEXT:    br label [[EXIT]]
>     -; INSTCOMBINE:       exit:
>     -; INSTCOMBINE-NEXT:    [[PTR_TYPED:%.*]] = phi i32* [
>     [[PTR1_TYPED]], [[ENTRY:%.*]] ], [ [[PTR2_TYPED]], [[BB2]] ]
>     -; INSTCOMBINE-NEXT:    [[RES_PHI_IN:%.*]] = phi i32* [
>     [[PTR1_TYPED]], [[ENTRY]] ], [ [[PTR2_TYPED]], [[BB2]] ]
>     -; INSTCOMBINE-NEXT:    [[RES_PHI:%.*]] = load i32, i32*
>     [[RES_PHI_IN]], align 4
>     -; INSTCOMBINE-NEXT:    store i32 1, i32* [[PTR_TYPED]], align 4
>     -; INSTCOMBINE-NEXT:    [[RES:%.*]] = select i1 [[COND2:%.*]], i32
>     [[RES_PHI]], i32 1
>     -; INSTCOMBINE-NEXT:    ret i32 [[RES]]
>     -;
>     -; INSTCOMBINEGVN-LABEL: @test_gep_and_bitcast_same_bb(
>     -; INSTCOMBINEGVN-NEXT:  entry:
>     -; INSTCOMBINEGVN-NEXT:    [[OBJ:%.*]] = call i8* @get_ptr.i8()
>     -; INSTCOMBINEGVN-NEXT:    [[PTR1:%.*]] = getelementptr inbounds
>     i8, i8* [[OBJ]], i64 16
>     -; INSTCOMBINEGVN-NEXT:    [[PTR1_TYPED:%.*]] = bitcast i8*
>     [[PTR1]] to i32*
>     -; INSTCOMBINEGVN-NEXT:    br i1 [[COND:%.*]], label [[EXIT:%.*]],
>     label [[BB2:%.*]]
>     -; INSTCOMBINEGVN:       bb2:
>     -; INSTCOMBINEGVN-NEXT:    br label [[EXIT]]
>     -; INSTCOMBINEGVN:       exit:
>     -; INSTCOMBINEGVN-NEXT:    [[RES_PHI:%.*]] = load i32, i32*
>     [[PTR1_TYPED]], align 4
>     -; INSTCOMBINEGVN-NEXT:    store i32 1, i32* [[PTR1_TYPED]], align 4
>     -; INSTCOMBINEGVN-NEXT:    [[RES:%.*]] = select i1 [[COND2:%.*]],
>     i32 [[RES_PHI]], i32 1
>     -; INSTCOMBINEGVN-NEXT:    ret i32 [[RES]]
>     +; ALL-LABEL: @test_gep_and_bitcast_same_bb(
>     +; ALL-NEXT:  entry:
>     +; ALL-NEXT:    [[OBJ:%.*]] = call i8* @get_ptr.i8()
>     +; ALL-NEXT:    br i1 [[COND:%.*]], label [[EXIT:%.*]], label
>     [[BB2:%.*]]
>     +; ALL:       bb2:
>     +; ALL-NEXT:    br label [[EXIT]]
>     +; ALL:       exit:
>     +; ALL-NEXT:    [[PTR_TYPED_IN:%.*]] = getelementptr inbounds i8,
>     i8* [[OBJ]], i64 16
>     +; ALL-NEXT:    [[PTR_TYPED:%.*]] = bitcast i8* [[PTR_TYPED_IN]]
>     to i32*
>     +; ALL-NEXT:    [[RES_PHI:%.*]] = load i32, i32* [[PTR_TYPED]],
>     align 4
>     +; ALL-NEXT:    store i32 1, i32* [[PTR_TYPED]], align 4
>     +; ALL-NEXT:    [[RES:%.*]] = select i1 [[COND2:%.*]], i32
>     [[RES_PHI]], i32 1
>     +; ALL-NEXT:    ret i32 [[RES]]
>      ;
>      entry:
>        %obj = call i8* @get_ptr.i8()
>     @@ -328,8 +291,7 @@ define i32
>     @test_gep_and_bitcast_same_bb_and_extra_use(i1 %cond, i1 %cond2) {
>      ; INSTCOMBINE-NEXT:    br label [[EXIT]]
>      ; INSTCOMBINE:       exit:
>      ; INSTCOMBINE-NEXT:    [[PTR_TYPED:%.*]] = phi i32* [
>     [[PTR1_TYPED]], [[ENTRY:%.*]] ], [ [[PTR2_TYPED]], [[BB2]] ]
>     -; INSTCOMBINE-NEXT:    [[RES_PHI_IN:%.*]] = phi i32* [
>     [[PTR1_TYPED]], [[ENTRY]] ], [ [[PTR2_TYPED]], [[BB2]] ]
>     -; INSTCOMBINE-NEXT:    [[RES_PHI:%.*]] = load i32, i32*
>     [[RES_PHI_IN]], align 4
>     +; INSTCOMBINE-NEXT:    [[RES_PHI:%.*]] = load i32, i32*
>     [[PTR_TYPED]], align 4
>      ; INSTCOMBINE-NEXT:    store i32 1, i32* [[PTR_TYPED]], align 4
>      ; INSTCOMBINE-NEXT:    [[RES:%.*]] = select i1 [[COND2:%.*]], i32
>     [[RES_PHI]], i32 1
>      ; INSTCOMBINE-NEXT:    ret i32 [[RES]]
>     @@ -378,15 +340,12 @@ define i8 @test_gep(i1 %cond, i1 %cond2) {
>      ; ALL-NEXT:    [[OBJ:%.*]] = call i8* @get_ptr.i8()
>      ; ALL-NEXT:    br i1 [[COND:%.*]], label [[BB1:%.*]], label
>     [[BB2:%.*]]
>      ; ALL:       bb1:
>     -; ALL-NEXT:    [[PTR1:%.*]] = getelementptr inbounds i8, i8*
>     [[OBJ]], i64 16
>      ; ALL-NEXT:    br label [[EXIT:%.*]]
>      ; ALL:       bb2:
>     -; ALL-NEXT:    [[PTR2:%.*]] = getelementptr inbounds i8, i8*
>     [[OBJ]], i64 16
>      ; ALL-NEXT:    br label [[EXIT]]
>      ; ALL:       exit:
>     -; ALL-NEXT:    [[PTR_TYPED:%.*]] = phi i8* [ [[PTR1]], [[BB1]] ],
>     [ [[PTR2]], [[BB2]] ]
>     -; ALL-NEXT:    [[RES_PHI_IN:%.*]] = phi i8* [ [[PTR1]], [[BB1]]
>     ], [ [[PTR2]], [[BB2]] ]
>     -; ALL-NEXT:    [[RES_PHI:%.*]] = load i8, i8* [[RES_PHI_IN]], align 1
>     +; ALL-NEXT:    [[PTR_TYPED:%.*]] = getelementptr inbounds i8, i8*
>     [[OBJ]], i64 16
>     +; ALL-NEXT:    [[RES_PHI:%.*]] = load i8, i8* [[PTR_TYPED]], align 1
>      ; ALL-NEXT:    store i8 1, i8* [[PTR_TYPED]], align 1
>      ; ALL-NEXT:    [[RES:%.*]] = select i1 [[COND2:%.*]], i8
>     [[RES_PHI]], i8 1
>      ; ALL-NEXT:    ret i8 [[RES]]
>
>     diff  --git a/llvm/test/Transforms/InstCombine/select.ll
>     b/llvm/test/Transforms/InstCombine/select.ll
>     index 73e1e4af7aac..aa5472ef43b8 100644
>     --- a/llvm/test/Transforms/InstCombine/select.ll
>     +++ b/llvm/test/Transforms/InstCombine/select.ll
>     @@ -1926,10 +1926,7 @@ define i32 @select_dominance_chain(i1
>     %cond, i32 %x, i32 %y) {
>      ; CHECK-NEXT:    br label [[MERGE_3]]
>      ; CHECK:       merge.3:
>      ; CHECK-NEXT:    [[S_3:%.*]] = phi i32 [ [[Y:%.*]],
>     [[IF_FALSE_3]] ], [ [[X:%.*]], [[IF_TRUE_3]] ]
>     -; CHECK-NEXT:    [[S_2:%.*]] = phi i32 [ [[Y]], [[IF_FALSE_3]] ],
>     [ [[X]], [[IF_TRUE_3]] ]
>     -; CHECK-NEXT:    [[S_1:%.*]] = phi i32 [ [[Y]], [[IF_FALSE_3]] ],
>     [ [[X]], [[IF_TRUE_3]] ]
>     -; CHECK-NEXT:    [[SUM_1:%.*]] = add i32 [[S_1]], [[S_2]]
>     -; CHECK-NEXT:    [[SUM_2:%.*]] = add i32 [[SUM_1]], [[S_3]]
>     +; CHECK-NEXT:    [[SUM_2:%.*]] = mul i32 [[S_3]], 3
>      ; CHECK-NEXT:    ret i32 [[SUM_2]]
>      ;
>      entry:
>
>     diff  --git a/llvm/test/Transforms/InstSimplify/phi-cse.ll
>     b/llvm/test/Transforms/InstSimplify/phi-cse.ll
>     index a032adff0526..ba5d2b614830 100644
>     --- a/llvm/test/Transforms/InstSimplify/phi-cse.ll
>     +++ b/llvm/test/Transforms/InstSimplify/phi-cse.ll
>     @@ -12,9 +12,8 @@ define void @test0(i32 %v0, i32 %v1, i1 %c, i32*
>     %d0, i32* %d1) {
>      ; CHECK-NEXT:    br label [[END]]
>      ; CHECK:       end:
>      ; CHECK-NEXT:    [[I0:%.*]] = phi i32 [ [[V0:%.*]], [[B0]] ], [
>     [[V1:%.*]], [[B1]] ]
>     -; CHECK-NEXT:    [[I1:%.*]] = phi i32 [ [[V0]], [[B0]] ], [
>     [[V1]], [[B1]] ]
>      ; CHECK-NEXT:    store i32 [[I0]], i32* [[D0:%.*]], align 4
>     -; CHECK-NEXT:    store i32 [[I1]], i32* [[D1:%.*]], align 4
>     +; CHECK-NEXT:    store i32 [[I0]], i32* [[D1:%.*]], align 4
>      ; CHECK-NEXT:    ret void
>      ;
>      entry:
>     @@ -45,9 +44,8 @@ define void @test1(i32 %v0, i32 %v1, i1 %c, i32*
>     %d0, i32* %d1) {
>      ; CHECK-NEXT:    br label [[END]]
>      ; CHECK:       end:
>      ; CHECK-NEXT:    [[I0:%.*]] = phi i32 [ [[V0:%.*]], [[B0]] ], [
>     [[V1:%.*]], [[B1]] ]
>     -; CHECK-NEXT:    [[I1:%.*]] = phi i32 [ [[V1]], [[B1]] ], [
>     [[V0]], [[B0]] ]
>      ; CHECK-NEXT:    store i32 [[I0]], i32* [[D0:%.*]], align 4
>     -; CHECK-NEXT:    store i32 [[I1]], i32* [[D1:%.*]], align 4
>     +; CHECK-NEXT:    store i32 [[I0]], i32* [[D1:%.*]], align 4
>      ; CHECK-NEXT:    ret void
>      ;
>      entry:
>     @@ -140,9 +138,8 @@ define void @negative_test4(i32 %v0, i32 %v1,
>     i1 %c, i32* %d0, i32* %d1) {
>      ; CHECK-NEXT:    br label [[END]]
>      ; CHECK:       end:
>      ; CHECK-NEXT:    [[I0:%.*]] = phi i32 [ [[V0:%.*]], [[B0]] ], [
>     [[V1:%.*]], [[B1]] ]
>     -; CHECK-NEXT:    [[I1:%.*]] = phi i32 [ [[V1]], [[B1]] ], [
>     [[V0]], [[B0]] ]
>      ; CHECK-NEXT:    store i32 [[I0]], i32* [[D0:%.*]], align 4
>     -; CHECK-NEXT:    store i32 [[I1]], i32* [[D1:%.*]], align 4
>     +; CHECK-NEXT:    store i32 [[I0]], i32* [[D1:%.*]], align 4
>      ; CHECK-NEXT:    ret void
>      ;
>      entry:
>     @@ -233,9 +230,8 @@ define void @test7(i32 %v0, i32 %v1, i16 %v2,
>     i16 %v3, i1 %c, i32* %d0, i32* %d1
>      ; CHECK:       end:
>      ; CHECK-NEXT:    [[IBAD:%.*]] = phi i16 [ [[V2:%.*]], [[B0]] ], [
>     [[V3:%.*]], [[B1]] ]
>      ; CHECK-NEXT:    [[I0:%.*]] = phi i32 [ [[V0:%.*]], [[B0]] ], [
>     [[V1:%.*]], [[B1]] ]
>     -; CHECK-NEXT:    [[I1:%.*]] = phi i32 [ [[V0]], [[B0]] ], [
>     [[V1]], [[B1]] ]
>      ; CHECK-NEXT:    store i32 [[I0]], i32* [[D0:%.*]], align 4
>     -; CHECK-NEXT:    store i32 [[I1]], i32* [[D1:%.*]], align 4
>     +; CHECK-NEXT:    store i32 [[I0]], i32* [[D1:%.*]], align 4
>      ; CHECK-NEXT:    store i16 [[IBAD]], i16* [[D2:%.*]], align 2
>      ; CHECK-NEXT:    ret void
>      ;
>     @@ -268,9 +264,8 @@ define void @test8(i32 %v0, i32 %v1, i16 %v2,
>     i16 %v3, i1 %c, i32* %d0, i32* %d1
>      ; CHECK:       end:
>      ; CHECK-NEXT:    [[I0:%.*]] = phi i32 [ [[V0:%.*]], [[B0]] ], [
>     [[V1:%.*]], [[B1]] ]
>      ; CHECK-NEXT:    [[IBAD:%.*]] = phi i16 [ [[V2:%.*]], [[B0]] ], [
>     [[V3:%.*]], [[B1]] ]
>     -; CHECK-NEXT:    [[I1:%.*]] = phi i32 [ [[V0]], [[B0]] ], [
>     [[V1]], [[B1]] ]
>      ; CHECK-NEXT:    store i32 [[I0]], i32* [[D0:%.*]], align 4
>     -; CHECK-NEXT:    store i32 [[I1]], i32* [[D1:%.*]], align 4
>     +; CHECK-NEXT:    store i32 [[I0]], i32* [[D1:%.*]], align 4
>      ; CHECK-NEXT:    store i16 [[IBAD]], i16* [[D2:%.*]], align 2
>      ; CHECK-NEXT:    ret void
>      ;
>     @@ -302,10 +297,9 @@ define void @test9(i32 %v0, i32 %v1, i16 %v2,
>     i16 %v3, i1 %c, i32* %d0, i32* %d1
>      ; CHECK-NEXT:    br label [[END]]
>      ; CHECK:       end:
>      ; CHECK-NEXT:    [[I0:%.*]] = phi i32 [ [[V0:%.*]], [[B0]] ], [
>     [[V1:%.*]], [[B1]] ]
>     -; CHECK-NEXT:    [[I1:%.*]] = phi i32 [ [[V0]], [[B0]] ], [
>     [[V1]], [[B1]] ]
>      ; CHECK-NEXT:    [[IBAD:%.*]] = phi i16 [ [[V2:%.*]], [[B0]] ], [
>     [[V3:%.*]], [[B1]] ]
>      ; CHECK-NEXT:    store i32 [[I0]], i32* [[D0:%.*]], align 4
>     -; CHECK-NEXT:    store i32 [[I1]], i32* [[D1:%.*]], align 4
>     +; CHECK-NEXT:    store i32 [[I0]], i32* [[D1:%.*]], align 4
>      ; CHECK-NEXT:    store i16 [[IBAD]], i16* [[D2:%.*]], align 2
>      ; CHECK-NEXT:    ret void
>      ;
>
>     diff  --git a/llvm/test/Transforms/JumpThreading/loop-phi.ll
>     b/llvm/test/Transforms/JumpThreading/loop-phi.ll
>     index 7ec69f97c258..0f4551e9200d 100644
>     --- a/llvm/test/Transforms/JumpThreading/loop-phi.ll
>     +++ b/llvm/test/Transforms/JumpThreading/loop-phi.ll
>     @@ -9,7 +9,7 @@
>
>      ; CHECK:      latch1:
>      ; CHECK-NEXT: %tmp165 = phi i32 [ %tmp163, %body2.thread ], [
>     %tmp16, %body2 ]
>     -; CHECK-NEXT: %tmp154 = phi i32 [ %tmp165, %body2.thread ], [
>     %tmp15, %body2 ]
>     +; CHECK-NEXT: %tmp154 = phi i32 [ %tmp165, %body2.thread ], [
>     %tmp14, %body2 ]
>
>      define i32 @test(i1 %ARG1, i1 %ARG2, i32 %n) {
>      entry:
>
>     diff  --git a/llvm/test/Transforms/LoopVectorize/reduction.ll
>     b/llvm/test/Transforms/LoopVectorize/reduction.ll
>     index 4599899f7378..29fd1221362b 100644
>     --- a/llvm/test/Transforms/LoopVectorize/reduction.ll
>     +++ b/llvm/test/Transforms/LoopVectorize/reduction.ll
>     @@ -504,7 +504,6 @@ exit:
>      ;CHECK: add <4 x i32>
>      ;CHECK: extractelement <4 x i32> %{{.*}}, i32 0
>      ;CHECK: %sum.lcssa = phi i32 [ %[[SCALAR:.*]], %.lr.ph
>     <http://lr.ph> ], [ %[[VECTOR:.*]], %middle.block ]
>     -;CHECK: %sum.copy = phi i32 [ %[[SCALAR]], %.lr.ph <http://lr.ph>
>     ], [ %[[VECTOR]], %middle.block ]
>      ;CHECK: ret i32
>      define i32 @reduction_sum_multiuse(i32 %n, i32* noalias nocapture
>     %A, i32* noalias nocapture %B) {
>        %1 = icmp sgt i32 %n, 0
>
>
>
>     _______________________________________________
>     llvm-commits mailing list
>     llvm-commits at lists.llvm.org <mailto:llvm-commits at lists.llvm.org>
>     https://lists.llvm.org/cgi-bin/mailman/listinfo/llvm-commits
>
>
> _______________________________________________
> llvm-commits mailing list
> llvm-commits at lists.llvm.org
> https://lists.llvm.org/cgi-bin/mailman/listinfo/llvm-commits
-------------- next part --------------
An HTML attachment was scrubbed...
URL: <http://lists.llvm.org/pipermail/llvm-commits/attachments/20200827/15967fc2/attachment.html>


More information about the llvm-commits mailing list