[llvm] 6102310 - [InstSimplify][EarlyCSE] Try to CSE PHI nodes in the same basic block
Roman Lebedev via llvm-commits
llvm-commits at lists.llvm.org
Thu Aug 27 12:43:25 PDT 2020
On Thu, Aug 27, 2020 at 9:55 PM Nikita Popov <nikita.ppv at gmail.com> wrote:
>
> On Thu, Aug 27, 2020 at 5:47 PM Roman Lebedev via llvm-commits <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.
True.
> I'm a bit uncomfortable with this as a general direction.
Please can you be more specific?
> Would we lose out much transformation power if we did this in InstCombine only instead?
I'm not really sure, let me see how it affects -stats i guess.
> 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.
Well, right, because that is what SimplifyPHINode() only knew to do.
> It's not immediately clear that PHI CSE is desired and/or safe in all those cases.
I'm not really following.
If you have concrete examples i'd take a look.
Roman
>> 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.
Right, thanks, fixed.
>> + // 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 ], [ %[[VECTOR:.*]], %middle.block ]
>> -;CHECK: %sum.copy = phi i32 [ %[[SCALAR]], %.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
>> https://lists.llvm.org/cgi-bin/mailman/listinfo/llvm-commits
More information about the llvm-commits
mailing list