From 7405581f7ca3ba54be8a04c394a96fe6d980f073 Mon Sep 17 00:00:00 2001 From: Roman Lebedev Date: Fri, 4 Mar 2022 21:47:54 +0300 Subject: [PATCH] Revert "[SROA] Maintain shadow/backing alloca when some slices are noncapturnig read-only calls to allow alloca partitioning/promotion" Bots are reporting that the assertion about only expecting loads is wrong. This reverts commit 703240c71fd640af7490069e8149d32d78d14da1. --- llvm/lib/Transforms/Scalar/SROA.cpp | 151 +---------- .../Transforms/SROA/non-capturing-call-readonly.ll | 296 +++++++++++++-------- 2 files changed, 183 insertions(+), 264 deletions(-) diff --git a/llvm/lib/Transforms/Scalar/SROA.cpp b/llvm/lib/Transforms/Scalar/SROA.cpp index 5c3a46c..eb56fea 100644 --- a/llvm/lib/Transforms/Scalar/SROA.cpp +++ b/llvm/lib/Transforms/Scalar/SROA.cpp @@ -167,7 +167,6 @@ public: void makeUnsplittable() { UseAndIsSplittable.setInt(false); } Use *getUse() const { return UseAndIsSplittable.getPointer(); } - void setUse(Use *U) { UseAndIsSplittable.setPointer(U); } bool isDead() const { return getUse() == nullptr; } void kill() { UseAndIsSplittable.setPointer(nullptr); } @@ -219,7 +218,7 @@ public: class llvm::sroa::AllocaSlices { public: /// Construct the slices of a particular alloca. - AllocaSlices(const DataLayout &DL, AllocaInst &AI, bool &Changed); + AllocaSlices(const DataLayout &DL, AllocaInst &AI); /// Test whether a pointer to the allocation escapes our analysis. /// @@ -271,12 +270,6 @@ public: return DeadUseIfPromotable; } - void forgetTheDead() { - DeadUsers.clear(); - DeadUseIfPromotable.clear(); - DeadOperands.clear(); - }; - /// Access the dead operands referring to this alloca. /// /// These are operands which have cannot actually be used to refer to the @@ -302,18 +295,11 @@ private: friend class AllocaSlices::SliceBuilder; - void formBackingAlloca(AllocaInst *AI, bool &Changed); - #if !defined(NDEBUG) || defined(LLVM_ENABLE_DUMP) /// Handle to alloca instruction to simplify method interfaces. AllocaInst &AI; #endif - /// Certain escaping uses of an alloca (non-capturing-ones) - /// do not prevent promotion, but force retention of the alloca. - /// This records if there are any such uses. - bool NeedsBackingAlloca = false; - /// The instruction responsible for this alloca not having a known set /// of slices. /// @@ -1076,22 +1062,11 @@ private: void visitSelectInst(SelectInst &SI) { visitPHINodeOrSelectInst(SI); } - void visitCallBase(CallBase &CB) { - if (!IsOffsetKnown || !CB.doesNotCapture(U->getOperandNo())) - return PI.setAborted(&CB); - // If we know that the callee does not retain the pointer, - // then it does not prevent SROA, although we have to workaround this. - // However, for now, only allow uses, that, at most, read from said memory. - if (!CB.onlyReadsMemory() && !CB.onlyReadsMemory(U->getOperandNo())) - return PI.setAborted(&CB); - AS.NeedsBackingAlloca = true; - } - /// Disable SROA entirely if there are unhandled users of the alloca. void visitInstruction(Instruction &I) { PI.setAborted(&I); } }; -AllocaSlices::AllocaSlices(const DataLayout &DL, AllocaInst &AI, bool &Changed) +AllocaSlices::AllocaSlices(const DataLayout &DL, AllocaInst &AI) : #if !defined(NDEBUG) || defined(LLVM_ENABLE_DUMP) AI(AI), @@ -1108,10 +1083,6 @@ AllocaSlices::AllocaSlices(const DataLayout &DL, AllocaInst &AI, bool &Changed) return; } - // We may have found that the pointer to the AI escapes, but isn't captured. - if (NeedsBackingAlloca) - formBackingAlloca(&AI, Changed); - llvm::erase_if(Slices, [](const Slice &S) { return S.isDead(); }); // Sort the uses. This arranges for the offsets to be in ascending order, @@ -3616,122 +3587,6 @@ private: } // end anonymous namespace -/// Apparently, we can promote the alloca, but some uses of the alloca -/// are calls (that don't capture it's address), which require for the -/// trace alloca to remain. To do so, we must form a new "backing" alloca, -/// which will be kept as an up-to-date backup of the to-be-promoted-alloca's -/// content, and used in it's place in these non-capturing calls. -/// FIXME: support non-readonly non-capturing calls. -void AllocaSlices::formBackingAlloca(AllocaInst *AllocaToPromote, - bool &Changed) { - assert(NeedsBackingAlloca && - "Should not be called if there is no need to rewrite."); - - // We are going to preserve all of the original instructions that were - // operating on the original alloca, so we must forget any instructions - // that were deemed as dead-to-be-deleted during normal promotion. - forgetTheDead(); - - Changed = true; - - // Now, we want to retain all of the instructions operating on the original - // alloca, so to avoid much hassle, create a new alloca, and swap (RAUW) them. - AllocaInst *ShadowAlloca = cast(AllocaToPromote->clone()); - ShadowAlloca->takeName(AllocaToPromote); - AllocaToPromote->setName(ShadowAlloca->getName() + ".prom"); - ShadowAlloca->insertBefore(AllocaToPromote); - AllocaToPromote->replaceAllUsesWith(ShadowAlloca); - - // Avoid recomputing the same pointer over and over again, cache it. - SmallDenseMap, Value *> RebasedPtrsCSE; - - // Don't do anything fancy, just put new insts "right after" the alloca. - IRBuilderTy Builder(AllocaToPromote->getContext()); - BasicBlock *AllocaToPromoteBB = AllocaToPromote->getParent(); - Builder.SetInsertPoint(AllocaToPromoteBB, - AllocaToPromoteBB->getFirstInsertionPt()); - - // Give a pointer `Offset` bytes into the `AllocaToPromote` with `PtrTy` type. - auto getRebasedPtr = [&RebasedPtrsCSE, &Builder, AllocaToPromote, - DL = AllocaToPromote->getModule()->getDataLayout()]( - PointerType *PtrTy, const uint64_t Offset) { - // Look it up in a cache first. - auto It = RebasedPtrsCSE.find({Offset, PtrTy}); - if (It != RebasedPtrsCSE.end()) - return It->second; - - // Otherwise, create a new pointer, and cache it for the future. - Value *NewPtr = getAdjustedPtr( - Builder, DL, AllocaToPromote, - APInt(DL.getIndexSizeInBits(PtrTy->getAddressSpace()), Offset), PtrTy, - ""); - RebasedPtrsCSE[{Offset, PtrTy}] = NewPtr; - - return NewPtr; - }; - - // Some instructions may have several uses of an alloca, and there's - // a separate slice for each use, so we must cache each instruction - // we clone, so that we only clone it once, - // not for each slice that references it. - SmallDenseMap InstrCloneMap; - - // Now, let's just deal with each slice. Roughly, we need to clone each - // instruction that is referenced by a slice (once per instruction!), - // and change the appropriate pointer from pointing at the shadow alloca - // into pointing into the alloca we are going to promote. - // - // NOTE: the original instruction is generally preserved, - // because we need to maintain the content parity between the two allocas! - for (Slice &S : Slices) { - // Just completely ignore dead slices. - if (S.isDead()) - continue; - - // Which instruction does this slice represent? - Use *OrigUse = S.getUse(); - auto *OrigInstr = cast(OrigUse->getUser()); - - // Now, we need to make a clone of this instruction, but operating on - // the alloca-to-be-promoted instead. - Instruction *ClonedInstr; - // Only clone instruction once! See if we already did that for this instr. - auto It = InstrCloneMap.find(OrigInstr); - if (It != InstrCloneMap.end()) - ClonedInstr = It->second; - else { - // This is the first time this instruction is seen. - // Clone it next to the original instruction, and cache it. - ClonedInstr = OrigInstr->clone(); - ClonedInstr->insertBefore(OrigInstr); - InstrCloneMap.insert({OrigInstr, ClonedInstr}); - - // Also, if the instruction was returning anything, we do that instead. - if (!ClonedInstr->getType()->isVoidTy()) { - assert(isa(OrigInstr) && - "Not expecting to encounter here anything other than a `load`."); - ClonedInstr->setName(OrigInstr->getName() + ".prom"); - OrigInstr->replaceAllUsesWith(ClonedInstr); - } - - if (isa(OrigInstr)) - // We know that all the offending (non-capturing) calls do not modify - // the content of the shadow alloca, so we do not need to propagate - // the content of the shadow alloca to the alloca-to-be-promoted. - DeadUsers.push_back(OrigInstr); - } - - // Final touch: the slice should refer to the - // use of the alloca-to-be-promoted, while it currently refers to - // use of the shadow alloca, so rectify that. - Value *NewPtr = getRebasedPtr(cast(OrigUse->get()->getType()), - S.beginOffset()); - Use &ClonedUse = ClonedInstr->getOperandUse(OrigUse->getOperandNo()); - ClonedUse.set(NewPtr); - S.setUse(&ClonedUse); - } -} - /// Strip aggregate type wrapping. /// /// This removes no-op aggregate types wrapping an underlying type. It will @@ -4757,7 +4612,7 @@ bool SROAPass::runOnAlloca(AllocaInst &AI) { Changed |= AggRewriter.rewrite(AI); // Build the slices using a recursive instruction-visiting builder. - AllocaSlices AS(DL, AI, Changed); + AllocaSlices AS(DL, AI); LLVM_DEBUG(AS.print(dbgs())); if (AS.isEscaped()) return Changed; diff --git a/llvm/test/Transforms/SROA/non-capturing-call-readonly.ll b/llvm/test/Transforms/SROA/non-capturing-call-readonly.ll index 2e27d13..c3c8fb4 100644 --- a/llvm/test/Transforms/SROA/non-capturing-call-readonly.ll +++ b/llvm/test/Transforms/SROA/non-capturing-call-readonly.ll @@ -9,18 +9,19 @@ define i32 @alloca_used_in_call(i32* %data, i64 %n) { ; CHECK-NEXT: store i32 0, i32* [[RETVAL]], align 4 ; CHECK-NEXT: br label [[LOOP:%.*]] ; CHECK: loop: -; CHECK-NEXT: [[RETVAL_PROM_0:%.*]] = phi i32 [ 0, [[ENTRY:%.*]] ], [ [[RDX_INC:%.*]], [[LOOP]] ] -; CHECK-NEXT: [[INDVARS_IV:%.*]] = phi i64 [ 0, [[ENTRY]] ], [ [[INDVARS_IV_NEXT:%.*]], [[LOOP]] ] +; CHECK-NEXT: [[INDVARS_IV:%.*]] = phi i64 [ 0, [[ENTRY:%.*]] ], [ [[INDVARS_IV_NEXT:%.*]], [[LOOP]] ] ; CHECK-NEXT: [[ARRAYIDX:%.*]] = getelementptr inbounds i32, i32* [[DATA:%.*]], i64 [[INDVARS_IV]] ; CHECK-NEXT: [[LD:%.*]] = load i32, i32* [[ARRAYIDX]], align 4 -; CHECK-NEXT: [[RDX_INC]] = add nsw i32 [[RETVAL_PROM_0]], [[LD]] +; CHECK-NEXT: [[RDX:%.*]] = load i32, i32* [[RETVAL]], align 4 +; CHECK-NEXT: [[RDX_INC:%.*]] = add nsw i32 [[RDX]], [[LD]] ; CHECK-NEXT: store i32 [[RDX_INC]], i32* [[RETVAL]], align 4 ; CHECK-NEXT: [[INDVARS_IV_NEXT]] = add nsw i64 [[INDVARS_IV]], 1 ; CHECK-NEXT: [[EXITCOND:%.*]] = icmp ne i64 [[INDVARS_IV_NEXT]], [[N:%.*]] ; CHECK-NEXT: br i1 [[EXITCOND]], label [[LOOP]], label [[EXIT:%.*]] ; CHECK: exit: ; CHECK-NEXT: [[I0:%.*]] = call i32 @user_of_alloca(i32* [[RETVAL]]) -; CHECK-NEXT: ret i32 [[RDX_INC]] +; CHECK-NEXT: [[I1:%.*]] = load i32, i32* [[RETVAL]], align 4 +; CHECK-NEXT: ret i32 [[I1]] ; ; CHECK-OPAQUE-LABEL: @alloca_used_in_call( ; CHECK-OPAQUE-NEXT: entry: @@ -28,18 +29,19 @@ define i32 @alloca_used_in_call(i32* %data, i64 %n) { ; CHECK-OPAQUE-NEXT: store i32 0, ptr [[RETVAL]], align 4 ; CHECK-OPAQUE-NEXT: br label [[LOOP:%.*]] ; CHECK-OPAQUE: loop: -; CHECK-OPAQUE-NEXT: [[RETVAL_PROM_0:%.*]] = phi i32 [ 0, [[ENTRY:%.*]] ], [ [[RDX_INC:%.*]], [[LOOP]] ] -; CHECK-OPAQUE-NEXT: [[INDVARS_IV:%.*]] = phi i64 [ 0, [[ENTRY]] ], [ [[INDVARS_IV_NEXT:%.*]], [[LOOP]] ] +; CHECK-OPAQUE-NEXT: [[INDVARS_IV:%.*]] = phi i64 [ 0, [[ENTRY:%.*]] ], [ [[INDVARS_IV_NEXT:%.*]], [[LOOP]] ] ; CHECK-OPAQUE-NEXT: [[ARRAYIDX:%.*]] = getelementptr inbounds i32, ptr [[DATA:%.*]], i64 [[INDVARS_IV]] ; CHECK-OPAQUE-NEXT: [[LD:%.*]] = load i32, ptr [[ARRAYIDX]], align 4 -; CHECK-OPAQUE-NEXT: [[RDX_INC]] = add nsw i32 [[RETVAL_PROM_0]], [[LD]] +; CHECK-OPAQUE-NEXT: [[RDX:%.*]] = load i32, ptr [[RETVAL]], align 4 +; CHECK-OPAQUE-NEXT: [[RDX_INC:%.*]] = add nsw i32 [[RDX]], [[LD]] ; CHECK-OPAQUE-NEXT: store i32 [[RDX_INC]], ptr [[RETVAL]], align 4 ; CHECK-OPAQUE-NEXT: [[INDVARS_IV_NEXT]] = add nsw i64 [[INDVARS_IV]], 1 ; CHECK-OPAQUE-NEXT: [[EXITCOND:%.*]] = icmp ne i64 [[INDVARS_IV_NEXT]], [[N:%.*]] ; CHECK-OPAQUE-NEXT: br i1 [[EXITCOND]], label [[LOOP]], label [[EXIT:%.*]] ; CHECK-OPAQUE: exit: ; CHECK-OPAQUE-NEXT: [[I0:%.*]] = call i32 @user_of_alloca(ptr [[RETVAL]]) -; CHECK-OPAQUE-NEXT: ret i32 [[RDX_INC]] +; CHECK-OPAQUE-NEXT: [[I1:%.*]] = load i32, ptr [[RETVAL]], align 4 +; CHECK-OPAQUE-NEXT: ret i32 [[I1]] ; entry: %retval = alloca i32, align 4 @@ -196,18 +198,19 @@ define i32 @alloca_not_captured_and_readonly_as_per_operand_attr(i32* %data, i64 ; CHECK-NEXT: store i32 0, i32* [[RETVAL]], align 4 ; CHECK-NEXT: br label [[LOOP:%.*]] ; CHECK: loop: -; CHECK-NEXT: [[RETVAL_PROM_0:%.*]] = phi i32 [ 0, [[ENTRY:%.*]] ], [ [[RDX_INC:%.*]], [[LOOP]] ] -; CHECK-NEXT: [[INDVARS_IV:%.*]] = phi i64 [ 0, [[ENTRY]] ], [ [[INDVARS_IV_NEXT:%.*]], [[LOOP]] ] +; CHECK-NEXT: [[INDVARS_IV:%.*]] = phi i64 [ 0, [[ENTRY:%.*]] ], [ [[INDVARS_IV_NEXT:%.*]], [[LOOP]] ] ; CHECK-NEXT: [[ARRAYIDX:%.*]] = getelementptr inbounds i32, i32* [[DATA:%.*]], i64 [[INDVARS_IV]] ; CHECK-NEXT: [[LD:%.*]] = load i32, i32* [[ARRAYIDX]], align 4 -; CHECK-NEXT: [[RDX_INC]] = add nsw i32 [[RETVAL_PROM_0]], [[LD]] +; CHECK-NEXT: [[RDX:%.*]] = load i32, i32* [[RETVAL]], align 4 +; CHECK-NEXT: [[RDX_INC:%.*]] = add nsw i32 [[RDX]], [[LD]] ; CHECK-NEXT: store i32 [[RDX_INC]], i32* [[RETVAL]], align 4 ; CHECK-NEXT: [[INDVARS_IV_NEXT]] = add nsw i64 [[INDVARS_IV]], 1 ; CHECK-NEXT: [[EXITCOND:%.*]] = icmp ne i64 [[INDVARS_IV_NEXT]], [[N:%.*]] ; CHECK-NEXT: br i1 [[EXITCOND]], label [[LOOP]], label [[EXIT:%.*]] ; CHECK: exit: ; CHECK-NEXT: [[I0:%.*]] = call i32 @capture_of_alloca(i32* nocapture readonly [[RETVAL]]) -; CHECK-NEXT: ret i32 [[RDX_INC]] +; CHECK-NEXT: [[I1:%.*]] = load i32, i32* [[RETVAL]], align 4 +; CHECK-NEXT: ret i32 [[I1]] ; ; CHECK-OPAQUE-LABEL: @alloca_not_captured_and_readonly_as_per_operand_attr( ; CHECK-OPAQUE-NEXT: entry: @@ -215,18 +218,19 @@ define i32 @alloca_not_captured_and_readonly_as_per_operand_attr(i32* %data, i64 ; CHECK-OPAQUE-NEXT: store i32 0, ptr [[RETVAL]], align 4 ; CHECK-OPAQUE-NEXT: br label [[LOOP:%.*]] ; CHECK-OPAQUE: loop: -; CHECK-OPAQUE-NEXT: [[RETVAL_PROM_0:%.*]] = phi i32 [ 0, [[ENTRY:%.*]] ], [ [[RDX_INC:%.*]], [[LOOP]] ] -; CHECK-OPAQUE-NEXT: [[INDVARS_IV:%.*]] = phi i64 [ 0, [[ENTRY]] ], [ [[INDVARS_IV_NEXT:%.*]], [[LOOP]] ] +; CHECK-OPAQUE-NEXT: [[INDVARS_IV:%.*]] = phi i64 [ 0, [[ENTRY:%.*]] ], [ [[INDVARS_IV_NEXT:%.*]], [[LOOP]] ] ; CHECK-OPAQUE-NEXT: [[ARRAYIDX:%.*]] = getelementptr inbounds i32, ptr [[DATA:%.*]], i64 [[INDVARS_IV]] ; CHECK-OPAQUE-NEXT: [[LD:%.*]] = load i32, ptr [[ARRAYIDX]], align 4 -; CHECK-OPAQUE-NEXT: [[RDX_INC]] = add nsw i32 [[RETVAL_PROM_0]], [[LD]] +; CHECK-OPAQUE-NEXT: [[RDX:%.*]] = load i32, ptr [[RETVAL]], align 4 +; CHECK-OPAQUE-NEXT: [[RDX_INC:%.*]] = add nsw i32 [[RDX]], [[LD]] ; CHECK-OPAQUE-NEXT: store i32 [[RDX_INC]], ptr [[RETVAL]], align 4 ; CHECK-OPAQUE-NEXT: [[INDVARS_IV_NEXT]] = add nsw i64 [[INDVARS_IV]], 1 ; CHECK-OPAQUE-NEXT: [[EXITCOND:%.*]] = icmp ne i64 [[INDVARS_IV_NEXT]], [[N:%.*]] ; CHECK-OPAQUE-NEXT: br i1 [[EXITCOND]], label [[LOOP]], label [[EXIT:%.*]] ; CHECK-OPAQUE: exit: ; CHECK-OPAQUE-NEXT: [[I0:%.*]] = call i32 @capture_of_alloca(ptr nocapture readonly [[RETVAL]]) -; CHECK-OPAQUE-NEXT: ret i32 [[RDX_INC]] +; CHECK-OPAQUE-NEXT: [[I1:%.*]] = load i32, ptr [[RETVAL]], align 4 +; CHECK-OPAQUE-NEXT: ret i32 [[I1]] ; entry: %retval = alloca i32, align 4 @@ -257,18 +261,19 @@ define i32 @alloca_not_captured_as_per_operand_attr_and_readonly_as_per_callbase ; CHECK-NEXT: store i32 0, i32* [[RETVAL]], align 4 ; CHECK-NEXT: br label [[LOOP:%.*]] ; CHECK: loop: -; CHECK-NEXT: [[RETVAL_PROM_0:%.*]] = phi i32 [ 0, [[ENTRY:%.*]] ], [ [[RDX_INC:%.*]], [[LOOP]] ] -; CHECK-NEXT: [[INDVARS_IV:%.*]] = phi i64 [ 0, [[ENTRY]] ], [ [[INDVARS_IV_NEXT:%.*]], [[LOOP]] ] +; CHECK-NEXT: [[INDVARS_IV:%.*]] = phi i64 [ 0, [[ENTRY:%.*]] ], [ [[INDVARS_IV_NEXT:%.*]], [[LOOP]] ] ; CHECK-NEXT: [[ARRAYIDX:%.*]] = getelementptr inbounds i32, i32* [[DATA:%.*]], i64 [[INDVARS_IV]] ; CHECK-NEXT: [[LD:%.*]] = load i32, i32* [[ARRAYIDX]], align 4 -; CHECK-NEXT: [[RDX_INC]] = add nsw i32 [[RETVAL_PROM_0]], [[LD]] +; CHECK-NEXT: [[RDX:%.*]] = load i32, i32* [[RETVAL]], align 4 +; CHECK-NEXT: [[RDX_INC:%.*]] = add nsw i32 [[RDX]], [[LD]] ; CHECK-NEXT: store i32 [[RDX_INC]], i32* [[RETVAL]], align 4 ; CHECK-NEXT: [[INDVARS_IV_NEXT]] = add nsw i64 [[INDVARS_IV]], 1 ; CHECK-NEXT: [[EXITCOND:%.*]] = icmp ne i64 [[INDVARS_IV_NEXT]], [[N:%.*]] ; CHECK-NEXT: br i1 [[EXITCOND]], label [[LOOP]], label [[EXIT:%.*]] ; CHECK: exit: ; CHECK-NEXT: [[I0:%.*]] = call i32 @capture_of_alloca(i32* nocapture [[RETVAL]]) #[[ATTR2:[0-9]+]] -; CHECK-NEXT: ret i32 [[RDX_INC]] +; CHECK-NEXT: [[I1:%.*]] = load i32, i32* [[RETVAL]], align 4 +; CHECK-NEXT: ret i32 [[I1]] ; ; CHECK-OPAQUE-LABEL: @alloca_not_captured_as_per_operand_attr_and_readonly_as_per_callbase_attr( ; CHECK-OPAQUE-NEXT: entry: @@ -276,18 +281,19 @@ define i32 @alloca_not_captured_as_per_operand_attr_and_readonly_as_per_callbase ; CHECK-OPAQUE-NEXT: store i32 0, ptr [[RETVAL]], align 4 ; CHECK-OPAQUE-NEXT: br label [[LOOP:%.*]] ; CHECK-OPAQUE: loop: -; CHECK-OPAQUE-NEXT: [[RETVAL_PROM_0:%.*]] = phi i32 [ 0, [[ENTRY:%.*]] ], [ [[RDX_INC:%.*]], [[LOOP]] ] -; CHECK-OPAQUE-NEXT: [[INDVARS_IV:%.*]] = phi i64 [ 0, [[ENTRY]] ], [ [[INDVARS_IV_NEXT:%.*]], [[LOOP]] ] +; CHECK-OPAQUE-NEXT: [[INDVARS_IV:%.*]] = phi i64 [ 0, [[ENTRY:%.*]] ], [ [[INDVARS_IV_NEXT:%.*]], [[LOOP]] ] ; CHECK-OPAQUE-NEXT: [[ARRAYIDX:%.*]] = getelementptr inbounds i32, ptr [[DATA:%.*]], i64 [[INDVARS_IV]] ; CHECK-OPAQUE-NEXT: [[LD:%.*]] = load i32, ptr [[ARRAYIDX]], align 4 -; CHECK-OPAQUE-NEXT: [[RDX_INC]] = add nsw i32 [[RETVAL_PROM_0]], [[LD]] +; CHECK-OPAQUE-NEXT: [[RDX:%.*]] = load i32, ptr [[RETVAL]], align 4 +; CHECK-OPAQUE-NEXT: [[RDX_INC:%.*]] = add nsw i32 [[RDX]], [[LD]] ; CHECK-OPAQUE-NEXT: store i32 [[RDX_INC]], ptr [[RETVAL]], align 4 ; CHECK-OPAQUE-NEXT: [[INDVARS_IV_NEXT]] = add nsw i64 [[INDVARS_IV]], 1 ; CHECK-OPAQUE-NEXT: [[EXITCOND:%.*]] = icmp ne i64 [[INDVARS_IV_NEXT]], [[N:%.*]] ; CHECK-OPAQUE-NEXT: br i1 [[EXITCOND]], label [[LOOP]], label [[EXIT:%.*]] ; CHECK-OPAQUE: exit: ; CHECK-OPAQUE-NEXT: [[I0:%.*]] = call i32 @capture_of_alloca(ptr nocapture [[RETVAL]]) #[[ATTR2:[0-9]+]] -; CHECK-OPAQUE-NEXT: ret i32 [[RDX_INC]] +; CHECK-OPAQUE-NEXT: [[I1:%.*]] = load i32, ptr [[RETVAL]], align 4 +; CHECK-OPAQUE-NEXT: ret i32 [[I1]] ; entry: %retval = alloca i32, align 4 @@ -381,11 +387,11 @@ define i32 @alloca_with_gep_used_in_call(i32* %data, i64 %n) { ; CHECK-NEXT: store i32 0, i32* [[RETVAL]], align 4 ; CHECK-NEXT: br label [[LOOP:%.*]] ; CHECK: loop: -; CHECK-NEXT: [[RETVAL_PROM_0:%.*]] = phi i32 [ 0, [[ENTRY:%.*]] ], [ [[RDX_INC:%.*]], [[LOOP]] ] -; CHECK-NEXT: [[INDVARS_IV:%.*]] = phi i64 [ 0, [[ENTRY]] ], [ [[INDVARS_IV_NEXT:%.*]], [[LOOP]] ] +; CHECK-NEXT: [[INDVARS_IV:%.*]] = phi i64 [ 0, [[ENTRY:%.*]] ], [ [[INDVARS_IV_NEXT:%.*]], [[LOOP]] ] ; CHECK-NEXT: [[ARRAYIDX:%.*]] = getelementptr inbounds i32, i32* [[DATA:%.*]], i64 [[INDVARS_IV]] ; CHECK-NEXT: [[LD:%.*]] = load i32, i32* [[ARRAYIDX]], align 4 -; CHECK-NEXT: [[RDX_INC]] = add nsw i32 [[RETVAL_PROM_0]], [[LD]] +; CHECK-NEXT: [[RDX:%.*]] = load i32, i32* [[RETVAL]], align 4 +; CHECK-NEXT: [[RDX_INC:%.*]] = add nsw i32 [[RDX]], [[LD]] ; CHECK-NEXT: store i32 [[RDX_INC]], i32* [[RETVAL]], align 4 ; CHECK-NEXT: [[INDVARS_IV_NEXT]] = add nsw i64 [[INDVARS_IV]], 1 ; CHECK-NEXT: [[EXITCOND:%.*]] = icmp ne i64 [[INDVARS_IV_NEXT]], [[N:%.*]] @@ -393,7 +399,8 @@ define i32 @alloca_with_gep_used_in_call(i32* %data, i64 %n) { ; CHECK: exit: ; CHECK-NEXT: [[GEP:%.*]] = getelementptr i32, i32* [[RETVAL]], i32 0 ; CHECK-NEXT: [[I0:%.*]] = call i32 @user_of_alloca(i32* [[GEP]]) -; CHECK-NEXT: ret i32 [[RDX_INC]] +; CHECK-NEXT: [[I1:%.*]] = load i32, i32* [[RETVAL]], align 4 +; CHECK-NEXT: ret i32 [[I1]] ; ; CHECK-OPAQUE-LABEL: @alloca_with_gep_used_in_call( ; CHECK-OPAQUE-NEXT: entry: @@ -401,11 +408,11 @@ define i32 @alloca_with_gep_used_in_call(i32* %data, i64 %n) { ; CHECK-OPAQUE-NEXT: store i32 0, ptr [[RETVAL]], align 4 ; CHECK-OPAQUE-NEXT: br label [[LOOP:%.*]] ; CHECK-OPAQUE: loop: -; CHECK-OPAQUE-NEXT: [[RETVAL_PROM_0:%.*]] = phi i32 [ 0, [[ENTRY:%.*]] ], [ [[RDX_INC:%.*]], [[LOOP]] ] -; CHECK-OPAQUE-NEXT: [[INDVARS_IV:%.*]] = phi i64 [ 0, [[ENTRY]] ], [ [[INDVARS_IV_NEXT:%.*]], [[LOOP]] ] +; CHECK-OPAQUE-NEXT: [[INDVARS_IV:%.*]] = phi i64 [ 0, [[ENTRY:%.*]] ], [ [[INDVARS_IV_NEXT:%.*]], [[LOOP]] ] ; CHECK-OPAQUE-NEXT: [[ARRAYIDX:%.*]] = getelementptr inbounds i32, ptr [[DATA:%.*]], i64 [[INDVARS_IV]] ; CHECK-OPAQUE-NEXT: [[LD:%.*]] = load i32, ptr [[ARRAYIDX]], align 4 -; CHECK-OPAQUE-NEXT: [[RDX_INC]] = add nsw i32 [[RETVAL_PROM_0]], [[LD]] +; CHECK-OPAQUE-NEXT: [[RDX:%.*]] = load i32, ptr [[RETVAL]], align 4 +; CHECK-OPAQUE-NEXT: [[RDX_INC:%.*]] = add nsw i32 [[RDX]], [[LD]] ; CHECK-OPAQUE-NEXT: store i32 [[RDX_INC]], ptr [[RETVAL]], align 4 ; CHECK-OPAQUE-NEXT: [[INDVARS_IV_NEXT]] = add nsw i64 [[INDVARS_IV]], 1 ; CHECK-OPAQUE-NEXT: [[EXITCOND:%.*]] = icmp ne i64 [[INDVARS_IV_NEXT]], [[N:%.*]] @@ -413,7 +420,8 @@ define i32 @alloca_with_gep_used_in_call(i32* %data, i64 %n) { ; CHECK-OPAQUE: exit: ; CHECK-OPAQUE-NEXT: [[GEP:%.*]] = getelementptr i32, ptr [[RETVAL]], i32 0 ; CHECK-OPAQUE-NEXT: [[I0:%.*]] = call i32 @user_of_alloca(ptr [[GEP]]) -; CHECK-OPAQUE-NEXT: ret i32 [[RDX_INC]] +; CHECK-OPAQUE-NEXT: [[I1:%.*]] = load i32, ptr [[RETVAL]], align 4 +; CHECK-OPAQUE-NEXT: ret i32 [[I1]] ; entry: %retval = alloca i32, align 4 @@ -508,11 +516,11 @@ define i32 @alloca_used_in_maybe_throwing_call(i32* %data, i64 %n) personality i ; CHECK-NEXT: store i32 0, i32* [[RETVAL]], align 4 ; CHECK-NEXT: br label [[LOOP:%.*]] ; CHECK: loop: -; CHECK-NEXT: [[RETVAL_PROM_0:%.*]] = phi i32 [ 0, [[ENTRY:%.*]] ], [ [[RDX_INC:%.*]], [[LOOP]] ] -; CHECK-NEXT: [[INDVARS_IV:%.*]] = phi i64 [ 0, [[ENTRY]] ], [ [[INDVARS_IV_NEXT:%.*]], [[LOOP]] ] +; CHECK-NEXT: [[INDVARS_IV:%.*]] = phi i64 [ 0, [[ENTRY:%.*]] ], [ [[INDVARS_IV_NEXT:%.*]], [[LOOP]] ] ; CHECK-NEXT: [[ARRAYIDX:%.*]] = getelementptr inbounds i32, i32* [[DATA:%.*]], i64 [[INDVARS_IV]] ; CHECK-NEXT: [[LD:%.*]] = load i32, i32* [[ARRAYIDX]], align 4 -; CHECK-NEXT: [[RDX_INC]] = add nsw i32 [[RETVAL_PROM_0]], [[LD]] +; CHECK-NEXT: [[RDX:%.*]] = load i32, i32* [[RETVAL]], align 4 +; CHECK-NEXT: [[RDX_INC:%.*]] = add nsw i32 [[RDX]], [[LD]] ; CHECK-NEXT: store i32 [[RDX_INC]], i32* [[RETVAL]], align 4 ; CHECK-NEXT: [[INDVARS_IV_NEXT]] = add nsw i64 [[INDVARS_IV]], 1 ; CHECK-NEXT: [[EXITCOND:%.*]] = icmp ne i64 [[INDVARS_IV_NEXT]], [[N:%.*]] @@ -527,7 +535,8 @@ define i32 @alloca_used_in_maybe_throwing_call(i32* %data, i64 %n) personality i ; CHECK-NEXT: catch i8* null ; CHECK-NEXT: br label [[END]] ; CHECK: end: -; CHECK-NEXT: ret i32 [[RDX_INC]] +; CHECK-NEXT: [[I2:%.*]] = load i32, i32* [[RETVAL]], align 4 +; CHECK-NEXT: ret i32 [[I2]] ; ; CHECK-OPAQUE-LABEL: @alloca_used_in_maybe_throwing_call( ; CHECK-OPAQUE-NEXT: entry: @@ -535,11 +544,11 @@ define i32 @alloca_used_in_maybe_throwing_call(i32* %data, i64 %n) personality i ; CHECK-OPAQUE-NEXT: store i32 0, ptr [[RETVAL]], align 4 ; CHECK-OPAQUE-NEXT: br label [[LOOP:%.*]] ; CHECK-OPAQUE: loop: -; CHECK-OPAQUE-NEXT: [[RETVAL_PROM_0:%.*]] = phi i32 [ 0, [[ENTRY:%.*]] ], [ [[RDX_INC:%.*]], [[LOOP]] ] -; CHECK-OPAQUE-NEXT: [[INDVARS_IV:%.*]] = phi i64 [ 0, [[ENTRY]] ], [ [[INDVARS_IV_NEXT:%.*]], [[LOOP]] ] +; CHECK-OPAQUE-NEXT: [[INDVARS_IV:%.*]] = phi i64 [ 0, [[ENTRY:%.*]] ], [ [[INDVARS_IV_NEXT:%.*]], [[LOOP]] ] ; CHECK-OPAQUE-NEXT: [[ARRAYIDX:%.*]] = getelementptr inbounds i32, ptr [[DATA:%.*]], i64 [[INDVARS_IV]] ; CHECK-OPAQUE-NEXT: [[LD:%.*]] = load i32, ptr [[ARRAYIDX]], align 4 -; CHECK-OPAQUE-NEXT: [[RDX_INC]] = add nsw i32 [[RETVAL_PROM_0]], [[LD]] +; CHECK-OPAQUE-NEXT: [[RDX:%.*]] = load i32, ptr [[RETVAL]], align 4 +; CHECK-OPAQUE-NEXT: [[RDX_INC:%.*]] = add nsw i32 [[RDX]], [[LD]] ; CHECK-OPAQUE-NEXT: store i32 [[RDX_INC]], ptr [[RETVAL]], align 4 ; CHECK-OPAQUE-NEXT: [[INDVARS_IV_NEXT]] = add nsw i64 [[INDVARS_IV]], 1 ; CHECK-OPAQUE-NEXT: [[EXITCOND:%.*]] = icmp ne i64 [[INDVARS_IV_NEXT]], [[N:%.*]] @@ -554,7 +563,8 @@ define i32 @alloca_used_in_maybe_throwing_call(i32* %data, i64 %n) personality i ; CHECK-OPAQUE-NEXT: catch ptr null ; CHECK-OPAQUE-NEXT: br label [[END]] ; CHECK-OPAQUE: end: -; CHECK-OPAQUE-NEXT: ret i32 [[RDX_INC]] +; CHECK-OPAQUE-NEXT: [[I2:%.*]] = load i32, ptr [[RETVAL]], align 4 +; CHECK-OPAQUE-NEXT: ret i32 [[I2]] ; entry: %retval = alloca i32, align 4 @@ -594,11 +604,11 @@ define i32 @alloca_used_in_maybe_throwing_call_with_same_dests(i32* %data, i64 % ; CHECK-NEXT: store i32 0, i32* [[RETVAL]], align 4 ; CHECK-NEXT: br label [[LOOP:%.*]] ; CHECK: loop: -; CHECK-NEXT: [[RETVAL_PROM_0:%.*]] = phi i32 [ 0, [[ENTRY:%.*]] ], [ [[RDX_INC:%.*]], [[LOOP]] ] -; CHECK-NEXT: [[INDVARS_IV:%.*]] = phi i64 [ 0, [[ENTRY]] ], [ [[INDVARS_IV_NEXT:%.*]], [[LOOP]] ] +; CHECK-NEXT: [[INDVARS_IV:%.*]] = phi i64 [ 0, [[ENTRY:%.*]] ], [ [[INDVARS_IV_NEXT:%.*]], [[LOOP]] ] ; CHECK-NEXT: [[ARRAYIDX:%.*]] = getelementptr inbounds i32, i32* [[DATA:%.*]], i64 [[INDVARS_IV]] ; CHECK-NEXT: [[LD:%.*]] = load i32, i32* [[ARRAYIDX]], align 4 -; CHECK-NEXT: [[RDX_INC]] = add nsw i32 [[RETVAL_PROM_0]], [[LD]] +; CHECK-NEXT: [[RDX:%.*]] = load i32, i32* [[RETVAL]], align 4 +; CHECK-NEXT: [[RDX_INC:%.*]] = add nsw i32 [[RDX]], [[LD]] ; CHECK-NEXT: store i32 [[RDX_INC]], i32* [[RETVAL]], align 4 ; CHECK-NEXT: [[INDVARS_IV_NEXT]] = add nsw i64 [[INDVARS_IV]], 1 ; CHECK-NEXT: [[EXITCOND:%.*]] = icmp ne i64 [[INDVARS_IV_NEXT]], [[N:%.*]] @@ -611,7 +621,8 @@ define i32 @alloca_used_in_maybe_throwing_call_with_same_dests(i32* %data, i64 % ; CHECK-NEXT: catch i8* null ; CHECK-NEXT: br label [[END]] ; CHECK: end: -; CHECK-NEXT: ret i32 [[RDX_INC]] +; CHECK-NEXT: [[I2:%.*]] = load i32, i32* [[RETVAL]], align 4 +; CHECK-NEXT: ret i32 [[I2]] ; ; CHECK-OPAQUE-LABEL: @alloca_used_in_maybe_throwing_call_with_same_dests( ; CHECK-OPAQUE-NEXT: entry: @@ -619,11 +630,11 @@ define i32 @alloca_used_in_maybe_throwing_call_with_same_dests(i32* %data, i64 % ; CHECK-OPAQUE-NEXT: store i32 0, ptr [[RETVAL]], align 4 ; CHECK-OPAQUE-NEXT: br label [[LOOP:%.*]] ; CHECK-OPAQUE: loop: -; CHECK-OPAQUE-NEXT: [[RETVAL_PROM_0:%.*]] = phi i32 [ 0, [[ENTRY:%.*]] ], [ [[RDX_INC:%.*]], [[LOOP]] ] -; CHECK-OPAQUE-NEXT: [[INDVARS_IV:%.*]] = phi i64 [ 0, [[ENTRY]] ], [ [[INDVARS_IV_NEXT:%.*]], [[LOOP]] ] +; CHECK-OPAQUE-NEXT: [[INDVARS_IV:%.*]] = phi i64 [ 0, [[ENTRY:%.*]] ], [ [[INDVARS_IV_NEXT:%.*]], [[LOOP]] ] ; CHECK-OPAQUE-NEXT: [[ARRAYIDX:%.*]] = getelementptr inbounds i32, ptr [[DATA:%.*]], i64 [[INDVARS_IV]] ; CHECK-OPAQUE-NEXT: [[LD:%.*]] = load i32, ptr [[ARRAYIDX]], align 4 -; CHECK-OPAQUE-NEXT: [[RDX_INC]] = add nsw i32 [[RETVAL_PROM_0]], [[LD]] +; CHECK-OPAQUE-NEXT: [[RDX:%.*]] = load i32, ptr [[RETVAL]], align 4 +; CHECK-OPAQUE-NEXT: [[RDX_INC:%.*]] = add nsw i32 [[RDX]], [[LD]] ; CHECK-OPAQUE-NEXT: store i32 [[RDX_INC]], ptr [[RETVAL]], align 4 ; CHECK-OPAQUE-NEXT: [[INDVARS_IV_NEXT]] = add nsw i64 [[INDVARS_IV]], 1 ; CHECK-OPAQUE-NEXT: [[EXITCOND:%.*]] = icmp ne i64 [[INDVARS_IV_NEXT]], [[N:%.*]] @@ -636,7 +647,8 @@ define i32 @alloca_used_in_maybe_throwing_call_with_same_dests(i32* %data, i64 % ; CHECK-OPAQUE-NEXT: catch ptr null ; CHECK-OPAQUE-NEXT: br label [[END]] ; CHECK-OPAQUE: end: -; CHECK-OPAQUE-NEXT: ret i32 [[RDX_INC]] +; CHECK-OPAQUE-NEXT: [[I2:%.*]] = load i32, ptr [[RETVAL]], align 4 +; CHECK-OPAQUE-NEXT: ret i32 [[I2]] ; entry: %retval = alloca i32, align 4 @@ -677,19 +689,23 @@ define [2 x i32] @part_of_alloca_used_in_call(i32* %data, i64 %n) { ; CHECK-NEXT: [[RETVAL:%.*]] = getelementptr inbounds [2 x i32], [2 x i32]* [[RETVAL_FULL]], i64 0, i64 1 ; CHECK-NEXT: br label [[LOOP:%.*]] ; CHECK: loop: -; CHECK-NEXT: [[RETVAL_FULL_PROM_SROA_2_0:%.*]] = phi i32 [ 0, [[ENTRY:%.*]] ], [ [[RDX_INC:%.*]], [[LOOP]] ] -; CHECK-NEXT: [[INDVARS_IV:%.*]] = phi i64 [ 0, [[ENTRY]] ], [ [[INDVARS_IV_NEXT:%.*]], [[LOOP]] ] +; CHECK-NEXT: [[INDVARS_IV:%.*]] = phi i64 [ 0, [[ENTRY:%.*]] ], [ [[INDVARS_IV_NEXT:%.*]], [[LOOP]] ] ; CHECK-NEXT: [[ARRAYIDX:%.*]] = getelementptr inbounds i32, i32* [[DATA:%.*]], i64 [[INDVARS_IV]] ; CHECK-NEXT: [[LD:%.*]] = load i32, i32* [[ARRAYIDX]], align 4 -; CHECK-NEXT: [[RDX_INC]] = add nsw i32 [[RETVAL_FULL_PROM_SROA_2_0]], [[LD]] +; CHECK-NEXT: [[RDX:%.*]] = load i32, i32* [[RETVAL]], align 4 +; CHECK-NEXT: [[RDX_INC:%.*]] = add nsw i32 [[RDX]], [[LD]] ; CHECK-NEXT: store i32 [[RDX_INC]], i32* [[RETVAL]], align 4 ; CHECK-NEXT: [[INDVARS_IV_NEXT]] = add nsw i64 [[INDVARS_IV]], 1 ; CHECK-NEXT: [[EXITCOND:%.*]] = icmp ne i64 [[INDVARS_IV_NEXT]], [[N:%.*]] ; CHECK-NEXT: br i1 [[EXITCOND]], label [[LOOP]], label [[EXIT:%.*]] ; CHECK: exit: ; CHECK-NEXT: [[I0:%.*]] = call i32 @user_of_alloca(i32* [[RETVAL]]) -; CHECK-NEXT: [[I1_FCA_0_INSERT:%.*]] = insertvalue [2 x i32] poison, i32 0, 0 -; CHECK-NEXT: [[I1_FCA_1_INSERT:%.*]] = insertvalue [2 x i32] [[I1_FCA_0_INSERT]], i32 [[RDX_INC]], 1 +; CHECK-NEXT: [[I1_FCA_0_GEP:%.*]] = getelementptr inbounds [2 x i32], [2 x i32]* [[RETVAL_FULL]], i32 0, i32 0 +; CHECK-NEXT: [[I1_FCA_0_LOAD:%.*]] = load i32, i32* [[I1_FCA_0_GEP]], align 4 +; CHECK-NEXT: [[I1_FCA_0_INSERT:%.*]] = insertvalue [2 x i32] poison, i32 [[I1_FCA_0_LOAD]], 0 +; CHECK-NEXT: [[I1_FCA_1_GEP:%.*]] = getelementptr inbounds [2 x i32], [2 x i32]* [[RETVAL_FULL]], i32 0, i32 1 +; CHECK-NEXT: [[I1_FCA_1_LOAD:%.*]] = load i32, i32* [[I1_FCA_1_GEP]], align 4 +; CHECK-NEXT: [[I1_FCA_1_INSERT:%.*]] = insertvalue [2 x i32] [[I1_FCA_0_INSERT]], i32 [[I1_FCA_1_LOAD]], 1 ; CHECK-NEXT: ret [2 x i32] [[I1_FCA_1_INSERT]] ; ; CHECK-OPAQUE-LABEL: @part_of_alloca_used_in_call( @@ -702,19 +718,23 @@ define [2 x i32] @part_of_alloca_used_in_call(i32* %data, i64 %n) { ; CHECK-OPAQUE-NEXT: [[RETVAL:%.*]] = getelementptr inbounds [2 x i32], ptr [[RETVAL_FULL]], i64 0, i64 1 ; CHECK-OPAQUE-NEXT: br label [[LOOP:%.*]] ; CHECK-OPAQUE: loop: -; CHECK-OPAQUE-NEXT: [[RETVAL_FULL_PROM_SROA_2_0:%.*]] = phi i32 [ 0, [[ENTRY:%.*]] ], [ [[RDX_INC:%.*]], [[LOOP]] ] -; CHECK-OPAQUE-NEXT: [[INDVARS_IV:%.*]] = phi i64 [ 0, [[ENTRY]] ], [ [[INDVARS_IV_NEXT:%.*]], [[LOOP]] ] +; CHECK-OPAQUE-NEXT: [[INDVARS_IV:%.*]] = phi i64 [ 0, [[ENTRY:%.*]] ], [ [[INDVARS_IV_NEXT:%.*]], [[LOOP]] ] ; CHECK-OPAQUE-NEXT: [[ARRAYIDX:%.*]] = getelementptr inbounds i32, ptr [[DATA:%.*]], i64 [[INDVARS_IV]] ; CHECK-OPAQUE-NEXT: [[LD:%.*]] = load i32, ptr [[ARRAYIDX]], align 4 -; CHECK-OPAQUE-NEXT: [[RDX_INC]] = add nsw i32 [[RETVAL_FULL_PROM_SROA_2_0]], [[LD]] +; CHECK-OPAQUE-NEXT: [[RDX:%.*]] = load i32, ptr [[RETVAL]], align 4 +; CHECK-OPAQUE-NEXT: [[RDX_INC:%.*]] = add nsw i32 [[RDX]], [[LD]] ; CHECK-OPAQUE-NEXT: store i32 [[RDX_INC]], ptr [[RETVAL]], align 4 ; CHECK-OPAQUE-NEXT: [[INDVARS_IV_NEXT]] = add nsw i64 [[INDVARS_IV]], 1 ; CHECK-OPAQUE-NEXT: [[EXITCOND:%.*]] = icmp ne i64 [[INDVARS_IV_NEXT]], [[N:%.*]] ; CHECK-OPAQUE-NEXT: br i1 [[EXITCOND]], label [[LOOP]], label [[EXIT:%.*]] ; CHECK-OPAQUE: exit: ; CHECK-OPAQUE-NEXT: [[I0:%.*]] = call i32 @user_of_alloca(ptr [[RETVAL]]) -; CHECK-OPAQUE-NEXT: [[I1_FCA_0_INSERT:%.*]] = insertvalue [2 x i32] poison, i32 0, 0 -; CHECK-OPAQUE-NEXT: [[I1_FCA_1_INSERT:%.*]] = insertvalue [2 x i32] [[I1_FCA_0_INSERT]], i32 [[RDX_INC]], 1 +; CHECK-OPAQUE-NEXT: [[I1_FCA_0_GEP:%.*]] = getelementptr inbounds [2 x i32], ptr [[RETVAL_FULL]], i32 0, i32 0 +; CHECK-OPAQUE-NEXT: [[I1_FCA_0_LOAD:%.*]] = load i32, ptr [[I1_FCA_0_GEP]], align 4 +; CHECK-OPAQUE-NEXT: [[I1_FCA_0_INSERT:%.*]] = insertvalue [2 x i32] poison, i32 [[I1_FCA_0_LOAD]], 0 +; CHECK-OPAQUE-NEXT: [[I1_FCA_1_GEP:%.*]] = getelementptr inbounds [2 x i32], ptr [[RETVAL_FULL]], i32 0, i32 1 +; CHECK-OPAQUE-NEXT: [[I1_FCA_1_LOAD:%.*]] = load i32, ptr [[I1_FCA_1_GEP]], align 4 +; CHECK-OPAQUE-NEXT: [[I1_FCA_1_INSERT:%.*]] = insertvalue [2 x i32] [[I1_FCA_0_INSERT]], i32 [[I1_FCA_1_LOAD]], 1 ; CHECK-OPAQUE-NEXT: ret [2 x i32] [[I1_FCA_1_INSERT]] ; entry: @@ -752,19 +772,23 @@ define [2 x i32] @all_parts_of_alloca_used_in_call_with_multiple_args(i32* %data ; CHECK-NEXT: [[RETVAL:%.*]] = getelementptr inbounds [2 x i32], [2 x i32]* [[RETVAL_FULL]], i64 0, i64 1 ; CHECK-NEXT: br label [[LOOP:%.*]] ; CHECK: loop: -; CHECK-NEXT: [[RETVAL_FULL_PROM_SROA_2_0:%.*]] = phi i32 [ 0, [[ENTRY:%.*]] ], [ [[RDX_INC:%.*]], [[LOOP]] ] -; CHECK-NEXT: [[INDVARS_IV:%.*]] = phi i64 [ 0, [[ENTRY]] ], [ [[INDVARS_IV_NEXT:%.*]], [[LOOP]] ] +; CHECK-NEXT: [[INDVARS_IV:%.*]] = phi i64 [ 0, [[ENTRY:%.*]] ], [ [[INDVARS_IV_NEXT:%.*]], [[LOOP]] ] ; CHECK-NEXT: [[ARRAYIDX:%.*]] = getelementptr inbounds i32, i32* [[DATA:%.*]], i64 [[INDVARS_IV]] ; CHECK-NEXT: [[LD:%.*]] = load i32, i32* [[ARRAYIDX]], align 4 -; CHECK-NEXT: [[RDX_INC]] = add nsw i32 [[RETVAL_FULL_PROM_SROA_2_0]], [[LD]] +; CHECK-NEXT: [[RDX:%.*]] = load i32, i32* [[RETVAL]], align 4 +; CHECK-NEXT: [[RDX_INC:%.*]] = add nsw i32 [[RDX]], [[LD]] ; CHECK-NEXT: store i32 [[RDX_INC]], i32* [[RETVAL]], align 4 ; CHECK-NEXT: [[INDVARS_IV_NEXT]] = add nsw i64 [[INDVARS_IV]], 1 ; CHECK-NEXT: [[EXITCOND:%.*]] = icmp ne i64 [[INDVARS_IV_NEXT]], [[N:%.*]] ; CHECK-NEXT: br i1 [[EXITCOND]], label [[LOOP]], label [[EXIT:%.*]] ; CHECK: exit: ; CHECK-NEXT: [[I0:%.*]] = call i32 @user_of_alloca_with_multiple_args(i32* [[RETVAL]], i32* [[RETVAL_BASE]]) -; CHECK-NEXT: [[I1_FCA_0_INSERT:%.*]] = insertvalue [2 x i32] poison, i32 0, 0 -; CHECK-NEXT: [[I1_FCA_1_INSERT:%.*]] = insertvalue [2 x i32] [[I1_FCA_0_INSERT]], i32 [[RDX_INC]], 1 +; CHECK-NEXT: [[I1_FCA_0_GEP:%.*]] = getelementptr inbounds [2 x i32], [2 x i32]* [[RETVAL_FULL]], i32 0, i32 0 +; CHECK-NEXT: [[I1_FCA_0_LOAD:%.*]] = load i32, i32* [[I1_FCA_0_GEP]], align 4 +; CHECK-NEXT: [[I1_FCA_0_INSERT:%.*]] = insertvalue [2 x i32] poison, i32 [[I1_FCA_0_LOAD]], 0 +; CHECK-NEXT: [[I1_FCA_1_GEP:%.*]] = getelementptr inbounds [2 x i32], [2 x i32]* [[RETVAL_FULL]], i32 0, i32 1 +; CHECK-NEXT: [[I1_FCA_1_LOAD:%.*]] = load i32, i32* [[I1_FCA_1_GEP]], align 4 +; CHECK-NEXT: [[I1_FCA_1_INSERT:%.*]] = insertvalue [2 x i32] [[I1_FCA_0_INSERT]], i32 [[I1_FCA_1_LOAD]], 1 ; CHECK-NEXT: ret [2 x i32] [[I1_FCA_1_INSERT]] ; ; CHECK-OPAQUE-LABEL: @all_parts_of_alloca_used_in_call_with_multiple_args( @@ -778,19 +802,23 @@ define [2 x i32] @all_parts_of_alloca_used_in_call_with_multiple_args(i32* %data ; CHECK-OPAQUE-NEXT: [[RETVAL:%.*]] = getelementptr inbounds [2 x i32], ptr [[RETVAL_FULL]], i64 0, i64 1 ; CHECK-OPAQUE-NEXT: br label [[LOOP:%.*]] ; CHECK-OPAQUE: loop: -; CHECK-OPAQUE-NEXT: [[RETVAL_FULL_PROM_SROA_2_0:%.*]] = phi i32 [ 0, [[ENTRY:%.*]] ], [ [[RDX_INC:%.*]], [[LOOP]] ] -; CHECK-OPAQUE-NEXT: [[INDVARS_IV:%.*]] = phi i64 [ 0, [[ENTRY]] ], [ [[INDVARS_IV_NEXT:%.*]], [[LOOP]] ] +; CHECK-OPAQUE-NEXT: [[INDVARS_IV:%.*]] = phi i64 [ 0, [[ENTRY:%.*]] ], [ [[INDVARS_IV_NEXT:%.*]], [[LOOP]] ] ; CHECK-OPAQUE-NEXT: [[ARRAYIDX:%.*]] = getelementptr inbounds i32, ptr [[DATA:%.*]], i64 [[INDVARS_IV]] ; CHECK-OPAQUE-NEXT: [[LD:%.*]] = load i32, ptr [[ARRAYIDX]], align 4 -; CHECK-OPAQUE-NEXT: [[RDX_INC]] = add nsw i32 [[RETVAL_FULL_PROM_SROA_2_0]], [[LD]] +; CHECK-OPAQUE-NEXT: [[RDX:%.*]] = load i32, ptr [[RETVAL]], align 4 +; CHECK-OPAQUE-NEXT: [[RDX_INC:%.*]] = add nsw i32 [[RDX]], [[LD]] ; CHECK-OPAQUE-NEXT: store i32 [[RDX_INC]], ptr [[RETVAL]], align 4 ; CHECK-OPAQUE-NEXT: [[INDVARS_IV_NEXT]] = add nsw i64 [[INDVARS_IV]], 1 ; CHECK-OPAQUE-NEXT: [[EXITCOND:%.*]] = icmp ne i64 [[INDVARS_IV_NEXT]], [[N:%.*]] ; CHECK-OPAQUE-NEXT: br i1 [[EXITCOND]], label [[LOOP]], label [[EXIT:%.*]] ; CHECK-OPAQUE: exit: ; CHECK-OPAQUE-NEXT: [[I0:%.*]] = call i32 @user_of_alloca_with_multiple_args(ptr [[RETVAL]], ptr [[RETVAL_BASE]]) -; CHECK-OPAQUE-NEXT: [[I1_FCA_0_INSERT:%.*]] = insertvalue [2 x i32] poison, i32 0, 0 -; CHECK-OPAQUE-NEXT: [[I1_FCA_1_INSERT:%.*]] = insertvalue [2 x i32] [[I1_FCA_0_INSERT]], i32 [[RDX_INC]], 1 +; CHECK-OPAQUE-NEXT: [[I1_FCA_0_GEP:%.*]] = getelementptr inbounds [2 x i32], ptr [[RETVAL_FULL]], i32 0, i32 0 +; CHECK-OPAQUE-NEXT: [[I1_FCA_0_LOAD:%.*]] = load i32, ptr [[I1_FCA_0_GEP]], align 4 +; CHECK-OPAQUE-NEXT: [[I1_FCA_0_INSERT:%.*]] = insertvalue [2 x i32] poison, i32 [[I1_FCA_0_LOAD]], 0 +; CHECK-OPAQUE-NEXT: [[I1_FCA_1_GEP:%.*]] = getelementptr inbounds [2 x i32], ptr [[RETVAL_FULL]], i32 0, i32 1 +; CHECK-OPAQUE-NEXT: [[I1_FCA_1_LOAD:%.*]] = load i32, ptr [[I1_FCA_1_GEP]], align 4 +; CHECK-OPAQUE-NEXT: [[I1_FCA_1_INSERT:%.*]] = insertvalue [2 x i32] [[I1_FCA_0_INSERT]], i32 [[I1_FCA_1_LOAD]], 1 ; CHECK-OPAQUE-NEXT: ret [2 x i32] [[I1_FCA_1_INSERT]] ; entry: @@ -829,11 +857,11 @@ define [2 x i32] @all_parts_of_alloca_used_in_call_with_multiple_args_with_memcp ; CHECK-NEXT: [[RETVAL:%.*]] = getelementptr inbounds [2 x i32], [2 x i32]* [[RETVAL_FULL]], i64 0, i64 1 ; CHECK-NEXT: br label [[LOOP:%.*]] ; CHECK: loop: -; CHECK-NEXT: [[RETVAL_FULL_PROM_SROA_3_0:%.*]] = phi i32 [ 0, [[ENTRY:%.*]] ], [ [[RDX_INC:%.*]], [[LOOP]] ] -; CHECK-NEXT: [[INDVARS_IV:%.*]] = phi i64 [ 0, [[ENTRY]] ], [ [[INDVARS_IV_NEXT:%.*]], [[LOOP]] ] +; CHECK-NEXT: [[INDVARS_IV:%.*]] = phi i64 [ 0, [[ENTRY:%.*]] ], [ [[INDVARS_IV_NEXT:%.*]], [[LOOP]] ] ; CHECK-NEXT: [[ARRAYIDX:%.*]] = getelementptr inbounds i32, i32* [[DATA:%.*]], i64 [[INDVARS_IV]] ; CHECK-NEXT: [[LD:%.*]] = load i32, i32* [[ARRAYIDX]], align 4 -; CHECK-NEXT: [[RDX_INC]] = add nsw i32 [[RETVAL_FULL_PROM_SROA_3_0]], [[LD]] +; CHECK-NEXT: [[RDX:%.*]] = load i32, i32* [[RETVAL]], align 4 +; CHECK-NEXT: [[RDX_INC:%.*]] = add nsw i32 [[RDX]], [[LD]] ; CHECK-NEXT: store i32 [[RDX_INC]], i32* [[RETVAL]], align 4 ; CHECK-NEXT: [[INDVARS_IV_NEXT]] = add nsw i64 [[INDVARS_IV]], 1 ; CHECK-NEXT: [[EXITCOND:%.*]] = icmp ne i64 [[INDVARS_IV_NEXT]], [[N:%.*]] @@ -841,8 +869,12 @@ define [2 x i32] @all_parts_of_alloca_used_in_call_with_multiple_args_with_memcp ; CHECK: exit: ; CHECK-NEXT: call void @llvm.memcpy.p0i32.p0i32.i32(i32* [[RETVAL_BASE]], i32* [[RETVAL]], i32 4, i1 false) ; CHECK-NEXT: [[I0:%.*]] = call i32 @user_of_alloca_with_multiple_args(i32* [[RETVAL]], i32* [[RETVAL_BASE]]) -; CHECK-NEXT: [[I1_FCA_0_INSERT:%.*]] = insertvalue [2 x i32] poison, i32 [[RDX_INC]], 0 -; CHECK-NEXT: [[I1_FCA_1_INSERT:%.*]] = insertvalue [2 x i32] [[I1_FCA_0_INSERT]], i32 [[RDX_INC]], 1 +; CHECK-NEXT: [[I1_FCA_0_GEP:%.*]] = getelementptr inbounds [2 x i32], [2 x i32]* [[RETVAL_FULL]], i32 0, i32 0 +; CHECK-NEXT: [[I1_FCA_0_LOAD:%.*]] = load i32, i32* [[I1_FCA_0_GEP]], align 4 +; CHECK-NEXT: [[I1_FCA_0_INSERT:%.*]] = insertvalue [2 x i32] poison, i32 [[I1_FCA_0_LOAD]], 0 +; CHECK-NEXT: [[I1_FCA_1_GEP:%.*]] = getelementptr inbounds [2 x i32], [2 x i32]* [[RETVAL_FULL]], i32 0, i32 1 +; CHECK-NEXT: [[I1_FCA_1_LOAD:%.*]] = load i32, i32* [[I1_FCA_1_GEP]], align 4 +; CHECK-NEXT: [[I1_FCA_1_INSERT:%.*]] = insertvalue [2 x i32] [[I1_FCA_0_INSERT]], i32 [[I1_FCA_1_LOAD]], 1 ; CHECK-NEXT: ret [2 x i32] [[I1_FCA_1_INSERT]] ; ; CHECK-OPAQUE-LABEL: @all_parts_of_alloca_used_in_call_with_multiple_args_with_memcpy_before_call( @@ -856,11 +888,11 @@ define [2 x i32] @all_parts_of_alloca_used_in_call_with_multiple_args_with_memcp ; CHECK-OPAQUE-NEXT: [[RETVAL:%.*]] = getelementptr inbounds [2 x i32], ptr [[RETVAL_FULL]], i64 0, i64 1 ; CHECK-OPAQUE-NEXT: br label [[LOOP:%.*]] ; CHECK-OPAQUE: loop: -; CHECK-OPAQUE-NEXT: [[RETVAL_FULL_PROM_SROA_3_0:%.*]] = phi i32 [ 0, [[ENTRY:%.*]] ], [ [[RDX_INC:%.*]], [[LOOP]] ] -; CHECK-OPAQUE-NEXT: [[INDVARS_IV:%.*]] = phi i64 [ 0, [[ENTRY]] ], [ [[INDVARS_IV_NEXT:%.*]], [[LOOP]] ] +; CHECK-OPAQUE-NEXT: [[INDVARS_IV:%.*]] = phi i64 [ 0, [[ENTRY:%.*]] ], [ [[INDVARS_IV_NEXT:%.*]], [[LOOP]] ] ; CHECK-OPAQUE-NEXT: [[ARRAYIDX:%.*]] = getelementptr inbounds i32, ptr [[DATA:%.*]], i64 [[INDVARS_IV]] ; CHECK-OPAQUE-NEXT: [[LD:%.*]] = load i32, ptr [[ARRAYIDX]], align 4 -; CHECK-OPAQUE-NEXT: [[RDX_INC]] = add nsw i32 [[RETVAL_FULL_PROM_SROA_3_0]], [[LD]] +; CHECK-OPAQUE-NEXT: [[RDX:%.*]] = load i32, ptr [[RETVAL]], align 4 +; CHECK-OPAQUE-NEXT: [[RDX_INC:%.*]] = add nsw i32 [[RDX]], [[LD]] ; CHECK-OPAQUE-NEXT: store i32 [[RDX_INC]], ptr [[RETVAL]], align 4 ; CHECK-OPAQUE-NEXT: [[INDVARS_IV_NEXT]] = add nsw i64 [[INDVARS_IV]], 1 ; CHECK-OPAQUE-NEXT: [[EXITCOND:%.*]] = icmp ne i64 [[INDVARS_IV_NEXT]], [[N:%.*]] @@ -868,8 +900,12 @@ define [2 x i32] @all_parts_of_alloca_used_in_call_with_multiple_args_with_memcp ; CHECK-OPAQUE: exit: ; CHECK-OPAQUE-NEXT: call void @llvm.memcpy.p0.p0.i32(ptr [[RETVAL_BASE]], ptr [[RETVAL]], i32 4, i1 false) ; CHECK-OPAQUE-NEXT: [[I0:%.*]] = call i32 @user_of_alloca_with_multiple_args(ptr [[RETVAL]], ptr [[RETVAL_BASE]]) -; CHECK-OPAQUE-NEXT: [[I1_FCA_0_INSERT:%.*]] = insertvalue [2 x i32] poison, i32 [[RDX_INC]], 0 -; CHECK-OPAQUE-NEXT: [[I1_FCA_1_INSERT:%.*]] = insertvalue [2 x i32] [[I1_FCA_0_INSERT]], i32 [[RDX_INC]], 1 +; CHECK-OPAQUE-NEXT: [[I1_FCA_0_GEP:%.*]] = getelementptr inbounds [2 x i32], ptr [[RETVAL_FULL]], i32 0, i32 0 +; CHECK-OPAQUE-NEXT: [[I1_FCA_0_LOAD:%.*]] = load i32, ptr [[I1_FCA_0_GEP]], align 4 +; CHECK-OPAQUE-NEXT: [[I1_FCA_0_INSERT:%.*]] = insertvalue [2 x i32] poison, i32 [[I1_FCA_0_LOAD]], 0 +; CHECK-OPAQUE-NEXT: [[I1_FCA_1_GEP:%.*]] = getelementptr inbounds [2 x i32], ptr [[RETVAL_FULL]], i32 0, i32 1 +; CHECK-OPAQUE-NEXT: [[I1_FCA_1_LOAD:%.*]] = load i32, ptr [[I1_FCA_1_GEP]], align 4 +; CHECK-OPAQUE-NEXT: [[I1_FCA_1_INSERT:%.*]] = insertvalue [2 x i32] [[I1_FCA_0_INSERT]], i32 [[I1_FCA_1_LOAD]], 1 ; CHECK-OPAQUE-NEXT: ret [2 x i32] [[I1_FCA_1_INSERT]] ; entry: @@ -909,11 +945,11 @@ define [2 x i32] @all_parts_of_alloca_used_in_call_with_multiple_args_with_memcp ; CHECK-NEXT: [[RETVAL:%.*]] = getelementptr inbounds [2 x i32], [2 x i32]* [[RETVAL_FULL]], i64 0, i64 1 ; CHECK-NEXT: br label [[LOOP:%.*]] ; CHECK: loop: -; CHECK-NEXT: [[RETVAL_FULL_PROM_SROA_3_0:%.*]] = phi i32 [ 0, [[ENTRY:%.*]] ], [ [[RDX_INC:%.*]], [[LOOP]] ] -; CHECK-NEXT: [[INDVARS_IV:%.*]] = phi i64 [ 0, [[ENTRY]] ], [ [[INDVARS_IV_NEXT:%.*]], [[LOOP]] ] +; CHECK-NEXT: [[INDVARS_IV:%.*]] = phi i64 [ 0, [[ENTRY:%.*]] ], [ [[INDVARS_IV_NEXT:%.*]], [[LOOP]] ] ; CHECK-NEXT: [[ARRAYIDX:%.*]] = getelementptr inbounds i32, i32* [[DATA:%.*]], i64 [[INDVARS_IV]] ; CHECK-NEXT: [[LD:%.*]] = load i32, i32* [[ARRAYIDX]], align 4 -; CHECK-NEXT: [[RDX_INC]] = add nsw i32 [[RETVAL_FULL_PROM_SROA_3_0]], [[LD]] +; CHECK-NEXT: [[RDX:%.*]] = load i32, i32* [[RETVAL]], align 4 +; CHECK-NEXT: [[RDX_INC:%.*]] = add nsw i32 [[RDX]], [[LD]] ; CHECK-NEXT: store i32 [[RDX_INC]], i32* [[RETVAL]], align 4 ; CHECK-NEXT: [[INDVARS_IV_NEXT]] = add nsw i64 [[INDVARS_IV]], 1 ; CHECK-NEXT: [[EXITCOND:%.*]] = icmp ne i64 [[INDVARS_IV_NEXT]], [[N:%.*]] @@ -921,8 +957,12 @@ define [2 x i32] @all_parts_of_alloca_used_in_call_with_multiple_args_with_memcp ; CHECK: exit: ; CHECK-NEXT: [[I0:%.*]] = call i32 @user_of_alloca_with_multiple_args(i32* [[RETVAL]], i32* [[RETVAL_BASE]]) ; CHECK-NEXT: call void @llvm.memcpy.p0i32.p0i32.i32(i32* [[RETVAL_BASE]], i32* [[RETVAL]], i32 4, i1 false) -; CHECK-NEXT: [[I1_FCA_0_INSERT:%.*]] = insertvalue [2 x i32] poison, i32 [[RDX_INC]], 0 -; CHECK-NEXT: [[I1_FCA_1_INSERT:%.*]] = insertvalue [2 x i32] [[I1_FCA_0_INSERT]], i32 [[RDX_INC]], 1 +; CHECK-NEXT: [[I1_FCA_0_GEP:%.*]] = getelementptr inbounds [2 x i32], [2 x i32]* [[RETVAL_FULL]], i32 0, i32 0 +; CHECK-NEXT: [[I1_FCA_0_LOAD:%.*]] = load i32, i32* [[I1_FCA_0_GEP]], align 4 +; CHECK-NEXT: [[I1_FCA_0_INSERT:%.*]] = insertvalue [2 x i32] poison, i32 [[I1_FCA_0_LOAD]], 0 +; CHECK-NEXT: [[I1_FCA_1_GEP:%.*]] = getelementptr inbounds [2 x i32], [2 x i32]* [[RETVAL_FULL]], i32 0, i32 1 +; CHECK-NEXT: [[I1_FCA_1_LOAD:%.*]] = load i32, i32* [[I1_FCA_1_GEP]], align 4 +; CHECK-NEXT: [[I1_FCA_1_INSERT:%.*]] = insertvalue [2 x i32] [[I1_FCA_0_INSERT]], i32 [[I1_FCA_1_LOAD]], 1 ; CHECK-NEXT: ret [2 x i32] [[I1_FCA_1_INSERT]] ; ; CHECK-OPAQUE-LABEL: @all_parts_of_alloca_used_in_call_with_multiple_args_with_memcpy_after_call( @@ -936,11 +976,11 @@ define [2 x i32] @all_parts_of_alloca_used_in_call_with_multiple_args_with_memcp ; CHECK-OPAQUE-NEXT: [[RETVAL:%.*]] = getelementptr inbounds [2 x i32], ptr [[RETVAL_FULL]], i64 0, i64 1 ; CHECK-OPAQUE-NEXT: br label [[LOOP:%.*]] ; CHECK-OPAQUE: loop: -; CHECK-OPAQUE-NEXT: [[RETVAL_FULL_PROM_SROA_3_0:%.*]] = phi i32 [ 0, [[ENTRY:%.*]] ], [ [[RDX_INC:%.*]], [[LOOP]] ] -; CHECK-OPAQUE-NEXT: [[INDVARS_IV:%.*]] = phi i64 [ 0, [[ENTRY]] ], [ [[INDVARS_IV_NEXT:%.*]], [[LOOP]] ] +; CHECK-OPAQUE-NEXT: [[INDVARS_IV:%.*]] = phi i64 [ 0, [[ENTRY:%.*]] ], [ [[INDVARS_IV_NEXT:%.*]], [[LOOP]] ] ; CHECK-OPAQUE-NEXT: [[ARRAYIDX:%.*]] = getelementptr inbounds i32, ptr [[DATA:%.*]], i64 [[INDVARS_IV]] ; CHECK-OPAQUE-NEXT: [[LD:%.*]] = load i32, ptr [[ARRAYIDX]], align 4 -; CHECK-OPAQUE-NEXT: [[RDX_INC]] = add nsw i32 [[RETVAL_FULL_PROM_SROA_3_0]], [[LD]] +; CHECK-OPAQUE-NEXT: [[RDX:%.*]] = load i32, ptr [[RETVAL]], align 4 +; CHECK-OPAQUE-NEXT: [[RDX_INC:%.*]] = add nsw i32 [[RDX]], [[LD]] ; CHECK-OPAQUE-NEXT: store i32 [[RDX_INC]], ptr [[RETVAL]], align 4 ; CHECK-OPAQUE-NEXT: [[INDVARS_IV_NEXT]] = add nsw i64 [[INDVARS_IV]], 1 ; CHECK-OPAQUE-NEXT: [[EXITCOND:%.*]] = icmp ne i64 [[INDVARS_IV_NEXT]], [[N:%.*]] @@ -948,8 +988,12 @@ define [2 x i32] @all_parts_of_alloca_used_in_call_with_multiple_args_with_memcp ; CHECK-OPAQUE: exit: ; CHECK-OPAQUE-NEXT: [[I0:%.*]] = call i32 @user_of_alloca_with_multiple_args(ptr [[RETVAL]], ptr [[RETVAL_BASE]]) ; CHECK-OPAQUE-NEXT: call void @llvm.memcpy.p0.p0.i32(ptr [[RETVAL_BASE]], ptr [[RETVAL]], i32 4, i1 false) -; CHECK-OPAQUE-NEXT: [[I1_FCA_0_INSERT:%.*]] = insertvalue [2 x i32] poison, i32 [[RDX_INC]], 0 -; CHECK-OPAQUE-NEXT: [[I1_FCA_1_INSERT:%.*]] = insertvalue [2 x i32] [[I1_FCA_0_INSERT]], i32 [[RDX_INC]], 1 +; CHECK-OPAQUE-NEXT: [[I1_FCA_0_GEP:%.*]] = getelementptr inbounds [2 x i32], ptr [[RETVAL_FULL]], i32 0, i32 0 +; CHECK-OPAQUE-NEXT: [[I1_FCA_0_LOAD:%.*]] = load i32, ptr [[I1_FCA_0_GEP]], align 4 +; CHECK-OPAQUE-NEXT: [[I1_FCA_0_INSERT:%.*]] = insertvalue [2 x i32] poison, i32 [[I1_FCA_0_LOAD]], 0 +; CHECK-OPAQUE-NEXT: [[I1_FCA_1_GEP:%.*]] = getelementptr inbounds [2 x i32], ptr [[RETVAL_FULL]], i32 0, i32 1 +; CHECK-OPAQUE-NEXT: [[I1_FCA_1_LOAD:%.*]] = load i32, ptr [[I1_FCA_1_GEP]], align 4 +; CHECK-OPAQUE-NEXT: [[I1_FCA_1_INSERT:%.*]] = insertvalue [2 x i32] [[I1_FCA_0_INSERT]], i32 [[I1_FCA_1_LOAD]], 1 ; CHECK-OPAQUE-NEXT: ret [2 x i32] [[I1_FCA_1_INSERT]] ; entry: @@ -988,19 +1032,23 @@ define [2 x i32] @part_of_alloca_used_in_call_with_multiple_args(i32* %data, i64 ; CHECK-NEXT: [[RETVAL:%.*]] = getelementptr inbounds [2 x i32], [2 x i32]* [[RETVAL_FULL]], i64 0, i64 1 ; CHECK-NEXT: br label [[LOOP:%.*]] ; CHECK: loop: -; CHECK-NEXT: [[RETVAL_FULL_PROM_SROA_2_0:%.*]] = phi i32 [ 0, [[ENTRY:%.*]] ], [ [[RDX_INC:%.*]], [[LOOP]] ] -; CHECK-NEXT: [[INDVARS_IV:%.*]] = phi i64 [ 0, [[ENTRY]] ], [ [[INDVARS_IV_NEXT:%.*]], [[LOOP]] ] +; CHECK-NEXT: [[INDVARS_IV:%.*]] = phi i64 [ 0, [[ENTRY:%.*]] ], [ [[INDVARS_IV_NEXT:%.*]], [[LOOP]] ] ; CHECK-NEXT: [[ARRAYIDX:%.*]] = getelementptr inbounds i32, i32* [[DATA:%.*]], i64 [[INDVARS_IV]] ; CHECK-NEXT: [[LD:%.*]] = load i32, i32* [[ARRAYIDX]], align 4 -; CHECK-NEXT: [[RDX_INC]] = add nsw i32 [[RETVAL_FULL_PROM_SROA_2_0]], [[LD]] +; CHECK-NEXT: [[RDX:%.*]] = load i32, i32* [[RETVAL]], align 4 +; CHECK-NEXT: [[RDX_INC:%.*]] = add nsw i32 [[RDX]], [[LD]] ; CHECK-NEXT: store i32 [[RDX_INC]], i32* [[RETVAL]], align 4 ; CHECK-NEXT: [[INDVARS_IV_NEXT]] = add nsw i64 [[INDVARS_IV]], 1 ; CHECK-NEXT: [[EXITCOND:%.*]] = icmp ne i64 [[INDVARS_IV_NEXT]], [[N:%.*]] ; CHECK-NEXT: br i1 [[EXITCOND]], label [[LOOP]], label [[EXIT:%.*]] ; CHECK: exit: ; CHECK-NEXT: [[I0:%.*]] = call i32 @user_of_alloca_with_multiple_args(i32* [[RETVAL]], i32* [[RETVAL]]) -; CHECK-NEXT: [[I1_FCA_0_INSERT:%.*]] = insertvalue [2 x i32] poison, i32 0, 0 -; CHECK-NEXT: [[I1_FCA_1_INSERT:%.*]] = insertvalue [2 x i32] [[I1_FCA_0_INSERT]], i32 [[RDX_INC]], 1 +; CHECK-NEXT: [[I1_FCA_0_GEP:%.*]] = getelementptr inbounds [2 x i32], [2 x i32]* [[RETVAL_FULL]], i32 0, i32 0 +; CHECK-NEXT: [[I1_FCA_0_LOAD:%.*]] = load i32, i32* [[I1_FCA_0_GEP]], align 4 +; CHECK-NEXT: [[I1_FCA_0_INSERT:%.*]] = insertvalue [2 x i32] poison, i32 [[I1_FCA_0_LOAD]], 0 +; CHECK-NEXT: [[I1_FCA_1_GEP:%.*]] = getelementptr inbounds [2 x i32], [2 x i32]* [[RETVAL_FULL]], i32 0, i32 1 +; CHECK-NEXT: [[I1_FCA_1_LOAD:%.*]] = load i32, i32* [[I1_FCA_1_GEP]], align 4 +; CHECK-NEXT: [[I1_FCA_1_INSERT:%.*]] = insertvalue [2 x i32] [[I1_FCA_0_INSERT]], i32 [[I1_FCA_1_LOAD]], 1 ; CHECK-NEXT: ret [2 x i32] [[I1_FCA_1_INSERT]] ; ; CHECK-OPAQUE-LABEL: @part_of_alloca_used_in_call_with_multiple_args( @@ -1013,19 +1061,23 @@ define [2 x i32] @part_of_alloca_used_in_call_with_multiple_args(i32* %data, i64 ; CHECK-OPAQUE-NEXT: [[RETVAL:%.*]] = getelementptr inbounds [2 x i32], ptr [[RETVAL_FULL]], i64 0, i64 1 ; CHECK-OPAQUE-NEXT: br label [[LOOP:%.*]] ; CHECK-OPAQUE: loop: -; CHECK-OPAQUE-NEXT: [[RETVAL_FULL_PROM_SROA_2_0:%.*]] = phi i32 [ 0, [[ENTRY:%.*]] ], [ [[RDX_INC:%.*]], [[LOOP]] ] -; CHECK-OPAQUE-NEXT: [[INDVARS_IV:%.*]] = phi i64 [ 0, [[ENTRY]] ], [ [[INDVARS_IV_NEXT:%.*]], [[LOOP]] ] +; CHECK-OPAQUE-NEXT: [[INDVARS_IV:%.*]] = phi i64 [ 0, [[ENTRY:%.*]] ], [ [[INDVARS_IV_NEXT:%.*]], [[LOOP]] ] ; CHECK-OPAQUE-NEXT: [[ARRAYIDX:%.*]] = getelementptr inbounds i32, ptr [[DATA:%.*]], i64 [[INDVARS_IV]] ; CHECK-OPAQUE-NEXT: [[LD:%.*]] = load i32, ptr [[ARRAYIDX]], align 4 -; CHECK-OPAQUE-NEXT: [[RDX_INC]] = add nsw i32 [[RETVAL_FULL_PROM_SROA_2_0]], [[LD]] +; CHECK-OPAQUE-NEXT: [[RDX:%.*]] = load i32, ptr [[RETVAL]], align 4 +; CHECK-OPAQUE-NEXT: [[RDX_INC:%.*]] = add nsw i32 [[RDX]], [[LD]] ; CHECK-OPAQUE-NEXT: store i32 [[RDX_INC]], ptr [[RETVAL]], align 4 ; CHECK-OPAQUE-NEXT: [[INDVARS_IV_NEXT]] = add nsw i64 [[INDVARS_IV]], 1 ; CHECK-OPAQUE-NEXT: [[EXITCOND:%.*]] = icmp ne i64 [[INDVARS_IV_NEXT]], [[N:%.*]] ; CHECK-OPAQUE-NEXT: br i1 [[EXITCOND]], label [[LOOP]], label [[EXIT:%.*]] ; CHECK-OPAQUE: exit: ; CHECK-OPAQUE-NEXT: [[I0:%.*]] = call i32 @user_of_alloca_with_multiple_args(ptr [[RETVAL]], ptr [[RETVAL]]) -; CHECK-OPAQUE-NEXT: [[I1_FCA_0_INSERT:%.*]] = insertvalue [2 x i32] poison, i32 0, 0 -; CHECK-OPAQUE-NEXT: [[I1_FCA_1_INSERT:%.*]] = insertvalue [2 x i32] [[I1_FCA_0_INSERT]], i32 [[RDX_INC]], 1 +; CHECK-OPAQUE-NEXT: [[I1_FCA_0_GEP:%.*]] = getelementptr inbounds [2 x i32], ptr [[RETVAL_FULL]], i32 0, i32 0 +; CHECK-OPAQUE-NEXT: [[I1_FCA_0_LOAD:%.*]] = load i32, ptr [[I1_FCA_0_GEP]], align 4 +; CHECK-OPAQUE-NEXT: [[I1_FCA_0_INSERT:%.*]] = insertvalue [2 x i32] poison, i32 [[I1_FCA_0_LOAD]], 0 +; CHECK-OPAQUE-NEXT: [[I1_FCA_1_GEP:%.*]] = getelementptr inbounds [2 x i32], ptr [[RETVAL_FULL]], i32 0, i32 1 +; CHECK-OPAQUE-NEXT: [[I1_FCA_1_LOAD:%.*]] = load i32, ptr [[I1_FCA_1_GEP]], align 4 +; CHECK-OPAQUE-NEXT: [[I1_FCA_1_INSERT:%.*]] = insertvalue [2 x i32] [[I1_FCA_0_INSERT]], i32 [[I1_FCA_1_LOAD]], 1 ; CHECK-OPAQUE-NEXT: ret [2 x i32] [[I1_FCA_1_INSERT]] ; entry: @@ -1065,11 +1117,11 @@ define [2 x i32] @all_parts_of_alloca_used_in_calls_with_multiple_args(i32* %dat ; CHECK-NEXT: [[SOME_ANOTHER_ALLOCA:%.*]] = getelementptr inbounds [42 x i32], [42 x i32]* [[SOME_ANOTHER_ALLOCA_FULL]], i64 0, i64 0 ; CHECK-NEXT: br label [[LOOP:%.*]] ; CHECK: loop: -; CHECK-NEXT: [[RETVAL_FULL_PROM_SROA_2_0:%.*]] = phi i32 [ 0, [[ENTRY:%.*]] ], [ [[RDX_INC:%.*]], [[LOOP]] ] -; CHECK-NEXT: [[INDVARS_IV:%.*]] = phi i64 [ 0, [[ENTRY]] ], [ [[INDVARS_IV_NEXT:%.*]], [[LOOP]] ] +; CHECK-NEXT: [[INDVARS_IV:%.*]] = phi i64 [ 0, [[ENTRY:%.*]] ], [ [[INDVARS_IV_NEXT:%.*]], [[LOOP]] ] ; CHECK-NEXT: [[ARRAYIDX:%.*]] = getelementptr inbounds i32, i32* [[DATA:%.*]], i64 [[INDVARS_IV]] ; CHECK-NEXT: [[LD:%.*]] = load i32, i32* [[ARRAYIDX]], align 4 -; CHECK-NEXT: [[RDX_INC]] = add nsw i32 [[RETVAL_FULL_PROM_SROA_2_0]], [[LD]] +; CHECK-NEXT: [[RDX:%.*]] = load i32, i32* [[RETVAL]], align 4 +; CHECK-NEXT: [[RDX_INC:%.*]] = add nsw i32 [[RDX]], [[LD]] ; CHECK-NEXT: store i32 [[RDX_INC]], i32* [[RETVAL]], align 4 ; CHECK-NEXT: [[INDVARS_IV_NEXT]] = add nsw i64 [[INDVARS_IV]], 1 ; CHECK-NEXT: [[EXITCOND:%.*]] = icmp ne i64 [[INDVARS_IV_NEXT]], [[N:%.*]] @@ -1078,8 +1130,12 @@ define [2 x i32] @all_parts_of_alloca_used_in_calls_with_multiple_args(i32* %dat ; CHECK-NEXT: [[I0:%.*]] = call i32 @user_of_alloca_with_multiple_args(i32* [[RETVAL]], i32* [[RETVAL_BASE]]) ; CHECK-NEXT: [[I1:%.*]] = call i32 @user_of_alloca_with_multiple_args(i32* [[RETVAL_BASE]], i32* [[RETVAL]]) ; CHECK-NEXT: [[I2:%.*]] = call i32 @capture_of_alloca(i32* [[SOME_ANOTHER_ALLOCA]]) -; CHECK-NEXT: [[I3_FCA_0_INSERT:%.*]] = insertvalue [2 x i32] poison, i32 0, 0 -; CHECK-NEXT: [[I3_FCA_1_INSERT:%.*]] = insertvalue [2 x i32] [[I3_FCA_0_INSERT]], i32 [[RDX_INC]], 1 +; CHECK-NEXT: [[I3_FCA_0_GEP:%.*]] = getelementptr inbounds [2 x i32], [2 x i32]* [[RETVAL_FULL]], i32 0, i32 0 +; CHECK-NEXT: [[I3_FCA_0_LOAD:%.*]] = load i32, i32* [[I3_FCA_0_GEP]], align 4 +; CHECK-NEXT: [[I3_FCA_0_INSERT:%.*]] = insertvalue [2 x i32] poison, i32 [[I3_FCA_0_LOAD]], 0 +; CHECK-NEXT: [[I3_FCA_1_GEP:%.*]] = getelementptr inbounds [2 x i32], [2 x i32]* [[RETVAL_FULL]], i32 0, i32 1 +; CHECK-NEXT: [[I3_FCA_1_LOAD:%.*]] = load i32, i32* [[I3_FCA_1_GEP]], align 4 +; CHECK-NEXT: [[I3_FCA_1_INSERT:%.*]] = insertvalue [2 x i32] [[I3_FCA_0_INSERT]], i32 [[I3_FCA_1_LOAD]], 1 ; CHECK-NEXT: ret [2 x i32] [[I3_FCA_1_INSERT]] ; ; CHECK-OPAQUE-LABEL: @all_parts_of_alloca_used_in_calls_with_multiple_args( @@ -1095,11 +1151,11 @@ define [2 x i32] @all_parts_of_alloca_used_in_calls_with_multiple_args(i32* %dat ; CHECK-OPAQUE-NEXT: [[SOME_ANOTHER_ALLOCA:%.*]] = getelementptr inbounds [42 x i32], ptr [[SOME_ANOTHER_ALLOCA_FULL]], i64 0, i64 0 ; CHECK-OPAQUE-NEXT: br label [[LOOP:%.*]] ; CHECK-OPAQUE: loop: -; CHECK-OPAQUE-NEXT: [[RETVAL_FULL_PROM_SROA_2_0:%.*]] = phi i32 [ 0, [[ENTRY:%.*]] ], [ [[RDX_INC:%.*]], [[LOOP]] ] -; CHECK-OPAQUE-NEXT: [[INDVARS_IV:%.*]] = phi i64 [ 0, [[ENTRY]] ], [ [[INDVARS_IV_NEXT:%.*]], [[LOOP]] ] +; CHECK-OPAQUE-NEXT: [[INDVARS_IV:%.*]] = phi i64 [ 0, [[ENTRY:%.*]] ], [ [[INDVARS_IV_NEXT:%.*]], [[LOOP]] ] ; CHECK-OPAQUE-NEXT: [[ARRAYIDX:%.*]] = getelementptr inbounds i32, ptr [[DATA:%.*]], i64 [[INDVARS_IV]] ; CHECK-OPAQUE-NEXT: [[LD:%.*]] = load i32, ptr [[ARRAYIDX]], align 4 -; CHECK-OPAQUE-NEXT: [[RDX_INC]] = add nsw i32 [[RETVAL_FULL_PROM_SROA_2_0]], [[LD]] +; CHECK-OPAQUE-NEXT: [[RDX:%.*]] = load i32, ptr [[RETVAL]], align 4 +; CHECK-OPAQUE-NEXT: [[RDX_INC:%.*]] = add nsw i32 [[RDX]], [[LD]] ; CHECK-OPAQUE-NEXT: store i32 [[RDX_INC]], ptr [[RETVAL]], align 4 ; CHECK-OPAQUE-NEXT: [[INDVARS_IV_NEXT]] = add nsw i64 [[INDVARS_IV]], 1 ; CHECK-OPAQUE-NEXT: [[EXITCOND:%.*]] = icmp ne i64 [[INDVARS_IV_NEXT]], [[N:%.*]] @@ -1108,8 +1164,12 @@ define [2 x i32] @all_parts_of_alloca_used_in_calls_with_multiple_args(i32* %dat ; CHECK-OPAQUE-NEXT: [[I0:%.*]] = call i32 @user_of_alloca_with_multiple_args(ptr [[RETVAL]], ptr [[RETVAL_BASE]]) ; CHECK-OPAQUE-NEXT: [[I1:%.*]] = call i32 @user_of_alloca_with_multiple_args(ptr [[RETVAL_BASE]], ptr [[RETVAL]]) ; CHECK-OPAQUE-NEXT: [[I2:%.*]] = call i32 @capture_of_alloca(ptr [[SOME_ANOTHER_ALLOCA]]) -; CHECK-OPAQUE-NEXT: [[I3_FCA_0_INSERT:%.*]] = insertvalue [2 x i32] poison, i32 0, 0 -; CHECK-OPAQUE-NEXT: [[I3_FCA_1_INSERT:%.*]] = insertvalue [2 x i32] [[I3_FCA_0_INSERT]], i32 [[RDX_INC]], 1 +; CHECK-OPAQUE-NEXT: [[I3_FCA_0_GEP:%.*]] = getelementptr inbounds [2 x i32], ptr [[RETVAL_FULL]], i32 0, i32 0 +; CHECK-OPAQUE-NEXT: [[I3_FCA_0_LOAD:%.*]] = load i32, ptr [[I3_FCA_0_GEP]], align 4 +; CHECK-OPAQUE-NEXT: [[I3_FCA_0_INSERT:%.*]] = insertvalue [2 x i32] poison, i32 [[I3_FCA_0_LOAD]], 0 +; CHECK-OPAQUE-NEXT: [[I3_FCA_1_GEP:%.*]] = getelementptr inbounds [2 x i32], ptr [[RETVAL_FULL]], i32 0, i32 1 +; CHECK-OPAQUE-NEXT: [[I3_FCA_1_LOAD:%.*]] = load i32, ptr [[I3_FCA_1_GEP]], align 4 +; CHECK-OPAQUE-NEXT: [[I3_FCA_1_INSERT:%.*]] = insertvalue [2 x i32] [[I3_FCA_0_INSERT]], i32 [[I3_FCA_1_LOAD]], 1 ; CHECK-OPAQUE-NEXT: ret [2 x i32] [[I3_FCA_1_INSERT]] ; entry: @@ -1144,7 +1204,6 @@ define i32 @all_uses_of_alloca_are_calls(i32* %data, i64 %n) { ; CHECK-LABEL: @all_uses_of_alloca_are_calls( ; CHECK-NEXT: entry: ; CHECK-NEXT: [[RETVAL:%.*]] = alloca i32, align 4 -; CHECK-NEXT: [[RETVAL_PROM:%.*]] = alloca i32, align 4 ; CHECK-NEXT: [[TMP0:%.*]] = call i32 @user_of_alloca(i32* [[RETVAL]]) ; CHECK-NEXT: [[TMP1:%.*]] = call i32 @user_of_alloca(i32* [[RETVAL]]) ; CHECK-NEXT: ret i32 0 @@ -1152,7 +1211,6 @@ define i32 @all_uses_of_alloca_are_calls(i32* %data, i64 %n) { ; CHECK-OPAQUE-LABEL: @all_uses_of_alloca_are_calls( ; CHECK-OPAQUE-NEXT: entry: ; CHECK-OPAQUE-NEXT: [[RETVAL:%.*]] = alloca i32, align 4 -; CHECK-OPAQUE-NEXT: [[RETVAL_PROM:%.*]] = alloca i32, align 4 ; CHECK-OPAQUE-NEXT: [[TMP0:%.*]] = call i32 @user_of_alloca(ptr [[RETVAL]]) ; CHECK-OPAQUE-NEXT: [[TMP1:%.*]] = call i32 @user_of_alloca(ptr [[RETVAL]]) ; CHECK-OPAQUE-NEXT: ret i32 0 @@ -1178,7 +1236,8 @@ define i64 @do_schedule_instrs_for_dce_after_fixups() { ; CHECK: if.end: ; CHECK-NEXT: [[ADD_PTR:%.*]] = getelementptr inbounds i32, i32* [[ARRAYDECAY]], i64 1 ; CHECK-NEXT: [[TMP1:%.*]] = call i32 @user_of_alloca(i32* [[ADD_PTR]]) -; CHECK-NEXT: ret i64 0 +; CHECK-NEXT: [[LD:%.*]] = load i64, i64* [[C]], align 4 +; CHECK-NEXT: ret i64 [[LD]] ; ; CHECK-OPAQUE-LABEL: @do_schedule_instrs_for_dce_after_fixups( ; CHECK-OPAQUE-NEXT: entry: @@ -1191,7 +1250,8 @@ define i64 @do_schedule_instrs_for_dce_after_fixups() { ; CHECK-OPAQUE: if.end: ; CHECK-OPAQUE-NEXT: [[ADD_PTR:%.*]] = getelementptr inbounds i32, ptr [[ARRAYDECAY]], i64 1 ; CHECK-OPAQUE-NEXT: [[TMP1:%.*]] = call i32 @user_of_alloca(ptr [[ADD_PTR]]) -; CHECK-OPAQUE-NEXT: ret i64 0 +; CHECK-OPAQUE-NEXT: [[LD:%.*]] = load i64, ptr [[C]], align 4 +; CHECK-OPAQUE-NEXT: ret i64 [[LD]] ; entry: %c = alloca i64, align 2 @@ -1234,13 +1294,15 @@ define i8 @dont_transform_load_only() { ; CHECK-NEXT: entry: ; CHECK-NEXT: [[A:%.*]] = alloca i8, align 1 ; CHECK-NEXT: call void @byte_user_of_alloca(i8* [[A]]) -; CHECK-NEXT: ret i8 undef +; CHECK-NEXT: [[R:%.*]] = load i8, i8* [[A]], align 1 +; CHECK-NEXT: ret i8 [[R]] ; ; CHECK-OPAQUE-LABEL: @dont_transform_load_only( ; CHECK-OPAQUE-NEXT: entry: ; CHECK-OPAQUE-NEXT: [[A:%.*]] = alloca i8, align 1 ; CHECK-OPAQUE-NEXT: call void @byte_user_of_alloca(ptr [[A]]) -; CHECK-OPAQUE-NEXT: ret i8 undef +; CHECK-OPAQUE-NEXT: [[R:%.*]] = load i8, ptr [[A]], align 1 +; CHECK-OPAQUE-NEXT: ret i8 [[R]] ; entry: %a = alloca i8 @@ -1254,14 +1316,16 @@ define i8 @transform_load_and_store() { ; CHECK-NEXT: [[A:%.*]] = alloca i8, align 1 ; CHECK-NEXT: store i8 0, i8* [[A]], align 1 ; CHECK-NEXT: call void @byte_user_of_alloca(i8* [[A]]) -; CHECK-NEXT: ret i8 0 +; CHECK-NEXT: [[R:%.*]] = load i8, i8* [[A]], align 1 +; CHECK-NEXT: ret i8 [[R]] ; ; CHECK-OPAQUE-LABEL: @transform_load_and_store( ; CHECK-OPAQUE-NEXT: entry: ; CHECK-OPAQUE-NEXT: [[A:%.*]] = alloca i8, align 1 ; CHECK-OPAQUE-NEXT: store i8 0, ptr [[A]], align 1 ; CHECK-OPAQUE-NEXT: call void @byte_user_of_alloca(ptr [[A]]) -; CHECK-OPAQUE-NEXT: ret i8 0 +; CHECK-OPAQUE-NEXT: [[R:%.*]] = load i8, ptr [[A]], align 1 +; CHECK-OPAQUE-NEXT: ret i8 [[R]] ; entry: %a = alloca i8 -- 2.7.4