From 8b446ea2ba39e406bcf940ea35d6efb4bb9afe95 Mon Sep 17 00:00:00 2001 From: Mitch Phillips <31459023+hctim@users.noreply.github.com> Date: Fri, 16 Dec 2022 17:54:44 -0800 Subject: [PATCH] Revert "[AAPointerInfo] handle multiple offsets in PHI" This reverts commit 179ed8871101cd197e0a719a3629cd5077b1a999. Reason: This change is dependent on a commit that needs to be rolled back because it broke the ASan buildbot. See https://reviews.llvm.org/rGfc21f2d7bae2e0be630470cc7ca9323ed5859892 for more information. --- llvm/include/llvm/Analysis/CycleAnalysis.h | 44 +++-- llvm/include/llvm/Transforms/IPO/Attributor.h | 33 +--- llvm/lib/Target/AMDGPU/AMDGPUAttributor.cpp | 17 +- .../Transforms/IPO/AttributorAttributes.cpp | 49 ++--- .../CodeGen/AMDGPU/implicitarg-attributes.ll | 30 ---- llvm/test/CodeGen/AMDGPU/llc-pipeline.ll | 10 -- .../multiple-offsets-pointer-info.ll | 169 ------------------ 7 files changed, 37 insertions(+), 315 deletions(-) diff --git a/llvm/include/llvm/Analysis/CycleAnalysis.h b/llvm/include/llvm/Analysis/CycleAnalysis.h index 30bf6856b69b0..539d29eb5e9cc 100644 --- a/llvm/include/llvm/Analysis/CycleAnalysis.h +++ b/llvm/include/llvm/Analysis/CycleAnalysis.h @@ -27,27 +27,6 @@ extern template class GenericCycle; using CycleInfo = GenericCycleInfo; using Cycle = CycleInfo::CycleT; -/// Legacy analysis pass which computes a \ref CycleInfo. -class CycleInfoWrapperPass : public FunctionPass { - Function *F = nullptr; - CycleInfo CI; - -public: - static char ID; - - CycleInfoWrapperPass(); - - CycleInfo &getResult() { return CI; } - const CycleInfo &getResult() const { return CI; } - - bool runOnFunction(Function &F) override; - void getAnalysisUsage(AnalysisUsage &AU) const override; - void releaseMemory() override; - void print(raw_ostream &OS, const Module *M = nullptr) const override; - - // TODO: verify analysis? -}; - /// Analysis pass which computes a \ref CycleInfo. class CycleAnalysis : public AnalysisInfoMixin { friend AnalysisInfoMixin; @@ -57,8 +36,6 @@ class CycleAnalysis : public AnalysisInfoMixin { /// Provide the result typedef for this analysis pass. using Result = CycleInfo; - using LegacyWrapper = CycleInfoWrapperPass; - /// Run the analysis pass over a function and produce a dominator tree. CycleInfo run(Function &F, FunctionAnalysisManager &); @@ -75,6 +52,27 @@ class CycleInfoPrinterPass : public PassInfoMixin { PreservedAnalyses run(Function &F, FunctionAnalysisManager &AM); }; +/// Legacy analysis pass which computes a \ref CycleInfo. +class CycleInfoWrapperPass : public FunctionPass { + Function *F = nullptr; + CycleInfo CI; + +public: + static char ID; + + CycleInfoWrapperPass(); + + CycleInfo &getCycleInfo() { return CI; } + const CycleInfo &getCycleInfo() const { return CI; } + + bool runOnFunction(Function &F) override; + void getAnalysisUsage(AnalysisUsage &AU) const override; + void releaseMemory() override; + void print(raw_ostream &OS, const Module *M = nullptr) const override; + + // TODO: verify analysis? +}; + } // end namespace llvm #endif // LLVM_ANALYSIS_CYCLEANALYSIS_H diff --git a/llvm/include/llvm/Transforms/IPO/Attributor.h b/llvm/include/llvm/Transforms/IPO/Attributor.h index 0a09e72c5da46..9f012208ccd33 100644 --- a/llvm/include/llvm/Transforms/IPO/Attributor.h +++ b/llvm/include/llvm/Transforms/IPO/Attributor.h @@ -1090,47 +1090,22 @@ class SubsumingPositionIterator { iterator end() { return IRPositions.end(); } }; -/// Wrapper for FunctionAnalysisManager. +/// Wrapper for FunctoinAnalysisManager. struct AnalysisGetter { - // The client may be running the old pass manager, in which case, we need to - // map the requested Analysis to its equivalent wrapper in the old pass - // manager. The scheme implemented here does not require every Analysis to be - // updated. Only those new analyses that the client cares about in the old - // pass manager need to expose a LegacyWrapper type, and that wrapper should - // support a getResult() method that matches the new Analysis. - // - // We need SFINAE to check for the LegacyWrapper, but function templates don't - // allow partial specialization, which is needed in this case. So instead, we - // use a constexpr bool to perform the SFINAE, and then use this information - // inside the function template. - template static constexpr bool HasLegacyWrapper = false; - template typename Analysis::Result *getAnalysis(const Function &F) { - if (FAM) - return &FAM->getResult(const_cast(F)); - if constexpr (HasLegacyWrapper) - if (LegacyPass) - return &LegacyPass - ->getAnalysis( - const_cast(F)) - .getResult(); - return nullptr; + if (!FAM || !F.getParent()) + return nullptr; + return &FAM->getResult(const_cast(F)); } AnalysisGetter(FunctionAnalysisManager &FAM) : FAM(&FAM) {} - AnalysisGetter(Pass *P) : LegacyPass(P) {} AnalysisGetter() = default; private: FunctionAnalysisManager *FAM = nullptr; - Pass *LegacyPass = nullptr; }; -template -constexpr bool AnalysisGetter::HasLegacyWrapper< - Analysis, std::void_t> = true; - /// Data structure to hold cached (LLVM-IR) information. /// /// All attributes are given an InformationCache object at creation time to diff --git a/llvm/lib/Target/AMDGPU/AMDGPUAttributor.cpp b/llvm/lib/Target/AMDGPU/AMDGPUAttributor.cpp index 6feceb0b42e61..b332054b4ccb3 100644 --- a/llvm/lib/Target/AMDGPU/AMDGPUAttributor.cpp +++ b/llvm/lib/Target/AMDGPU/AMDGPUAttributor.cpp @@ -13,7 +13,6 @@ #include "AMDGPU.h" #include "GCNSubtarget.h" #include "Utils/AMDGPUBaseInfo.h" -#include "llvm/Analysis/CycleAnalysis.h" #include "llvm/CodeGen/TargetPassConfig.h" #include "llvm/IR/IntrinsicsAMDGPU.h" #include "llvm/IR/IntrinsicsR600.h" @@ -22,10 +21,6 @@ #define DEBUG_TYPE "amdgpu-attributor" -namespace llvm { -void initializeCycleInfoWrapperPassPass(PassRegistry &); -} - using namespace llvm; #define AMDGPU_ATTRIBUTE(Name, Str) Name##_POS, @@ -752,7 +747,7 @@ class AMDGPUAttributor : public ModulePass { bool runOnModule(Module &M) override { SetVector Functions; - AnalysisGetter AG(this); + AnalysisGetter AG; for (Function &F : M) { if (!F.isIntrinsic()) Functions.insert(&F); @@ -787,10 +782,6 @@ class AMDGPUAttributor : public ModulePass { return Change == ChangeStatus::CHANGED; } - void getAnalysisUsage(AnalysisUsage &AU) const override { - AU.addRequired(); - } - StringRef getPassName() const override { return "AMDGPU Attributor"; } TargetMachine *TM; static char ID; @@ -800,8 +791,4 @@ class AMDGPUAttributor : public ModulePass { char AMDGPUAttributor::ID = 0; Pass *llvm::createAMDGPUAttributorPass() { return new AMDGPUAttributor(); } -INITIALIZE_PASS_BEGIN(AMDGPUAttributor, DEBUG_TYPE, "AMDGPU Attributor", false, - false) -INITIALIZE_PASS_DEPENDENCY(CycleInfoWrapperPass); -INITIALIZE_PASS_END(AMDGPUAttributor, DEBUG_TYPE, "AMDGPU Attributor", false, - false) +INITIALIZE_PASS(AMDGPUAttributor, DEBUG_TYPE, "AMDGPU Attributor", false, false) diff --git a/llvm/lib/Transforms/IPO/AttributorAttributes.cpp b/llvm/lib/Transforms/IPO/AttributorAttributes.cpp index 8507d8c1384aa..67edb99b87d4b 100644 --- a/llvm/lib/Transforms/IPO/AttributorAttributes.cpp +++ b/llvm/lib/Transforms/IPO/AttributorAttributes.cpp @@ -28,7 +28,6 @@ #include "llvm/Analysis/AssumeBundleQueries.h" #include "llvm/Analysis/AssumptionCache.h" #include "llvm/Analysis/CaptureTracking.h" -#include "llvm/Analysis/CycleAnalysis.h" #include "llvm/Analysis/InstructionSimplify.h" #include "llvm/Analysis/LazyValueInfo.h" #include "llvm/Analysis/MemoryBuiltins.h" @@ -1443,13 +1442,10 @@ ChangeStatus AAPointerInfoFloating::updateImpl(Attributor &A) { return true; }; - const auto *F = getAnchorScope(); - const auto *CI = - F ? A.getInfoCache().getAnalysisResultForFunction(*F) - : nullptr; const auto *TLI = - F ? A.getInfoCache().getTargetLibraryInfoForFunction(*F) : nullptr; - + getAnchorScope() + ? A.getInfoCache().getTargetLibraryInfoForFunction(*getAnchorScope()) + : nullptr; auto UsePred = [&](const Use &U, bool &Follow) -> bool { Value *CurPtr = U.get(); User *Usr = U.getUser(); @@ -1521,39 +1517,14 @@ ChangeStatus AAPointerInfoFloating::updateImpl(Attributor &A) { return true; } - // Check if the PHI operand can be traced back to AssociatedValue. + // Check if the PHI operand is not dependent on the PHI itself. APInt Offset( DL.getIndexSizeInBits(CurPtr->getType()->getPointerAddressSpace()), 0); Value *CurPtrBase = CurPtr->stripAndAccumulateConstantOffsets( DL, Offset, /* AllowNonInbounds */ true); auto It = OffsetInfoMap.find(CurPtrBase); - if (It == OffsetInfoMap.end()) { - LLVM_DEBUG(dbgs() << "[AAPointerInfo] PHI operand is too complex " - << *CurPtr << " in " << *Usr << "\n"); - UsrOI.setUnknown(); - Follow = true; - return true; - } - - auto mayBeInCycleHeader = [](const CycleInfo *CI, const Instruction *I) { - if (!CI) - return true; - auto *BB = I->getParent(); - auto *C = CI->getCycle(BB); - if (!C) - return false; - return BB == C->getHeader(); - }; - - // Check if the PHI operand is not dependent on the PHI itself. Every - // recurrence is a cyclic net of PHIs in the data flow, and has an - // equivalent Cycle in the control flow. One of those PHIs must be in the - // header of that control flow Cycle. This is independent of the choice of - // Cycles reported by CycleInfo. It is sufficient to check the PHIs in - // every Cycle header; if such a node is marked unknown, this will - // eventually propagate through the whole net of PHIs in the recurrence. - if (mayBeInCycleHeader(CI, cast(Usr))) { + if (It != OffsetInfoMap.end()) { auto BaseOI = It->getSecond(); BaseOI.addToAll(Offset.getZExtValue()); if (IsFirstPHIUser || BaseOI == UsrOI) { @@ -1561,16 +1532,16 @@ ChangeStatus AAPointerInfoFloating::updateImpl(Attributor &A) { << " in " << *Usr << "\n"); return HandlePassthroughUser(Usr, PtrOI, Follow); } - LLVM_DEBUG( dbgs() << "[AAPointerInfo] PHI operand pointer offset mismatch " << *CurPtr << " in " << *Usr << "\n"); - UsrOI.setUnknown(); - Follow = true; - return true; + } else { + LLVM_DEBUG(dbgs() << "[AAPointerInfo] PHI operand is too complex " + << *CurPtr << " in " << *Usr << "\n"); } - UsrOI.merge(PtrOI); + // TODO: Approximate in case we know the direction of the recurrence. + UsrOI.setUnknown(); Follow = true; return true; } diff --git a/llvm/test/CodeGen/AMDGPU/implicitarg-attributes.ll b/llvm/test/CodeGen/AMDGPU/implicitarg-attributes.ll index f4da140aeb01f..0fba6abbc675b 100644 --- a/llvm/test/CodeGen/AMDGPU/implicitarg-attributes.ll +++ b/llvm/test/CodeGen/AMDGPU/implicitarg-attributes.ll @@ -63,36 +63,6 @@ entry: ret void } -; CHECK-NOT: hidden_hostcall_buffer -; CHECK-NOT: hidden_multigrid_sync_arg -; CHECK-LABEL: .name: kernel_3 - -define amdgpu_kernel void @kernel_3(i32 addrspace(1)* %a, i1 %cond) { -entry: - %tmp7 = tail call i8 addrspace(4)* @llvm.amdgcn.implicitarg.ptr() - br i1 %cond, label %old, label %new - -old: ; preds = %entry - %tmp4 = getelementptr i8, i8 addrspace(4)* %tmp7, i64 12 - br label %join - -new: ; preds = %entry - %tmp12 = getelementptr inbounds i8, i8 addrspace(4)* %tmp7, i64 18 - br label %join - -join: ; preds = %new, %old - %.in.in.in = phi i8 addrspace(4)* [ %tmp12, %new ], [ %tmp4, %old ] - %.in.in = bitcast i8 addrspace(4)* %.in.in.in to i16 addrspace(4)* - - ;;; THIS USE of implicitarg_ptr should not produce hostcall metadata - %.in = load i16, i16 addrspace(4)* %.in.in, align 2 - - %idx.ext = sext i16 %.in to i64 - %add.ptr3 = getelementptr inbounds i32, i32 addrspace(1)* %a, i64 %idx.ext - %tmp16 = atomicrmw add i32 addrspace(1)* %add.ptr3, i32 15 syncscope("agent-one-as") monotonic, align 4 - ret void -} - declare i32 @llvm.amdgcn.workitem.id.x() declare align 4 i8 addrspace(4)* @llvm.amdgcn.implicitarg.ptr() diff --git a/llvm/test/CodeGen/AMDGPU/llc-pipeline.ll b/llvm/test/CodeGen/AMDGPU/llc-pipeline.ll index 6710668b9ebb2..bd2040a713d18 100644 --- a/llvm/test/CodeGen/AMDGPU/llc-pipeline.ll +++ b/llvm/test/CodeGen/AMDGPU/llc-pipeline.ll @@ -51,8 +51,6 @@ ; GCN-O0-NEXT: Scalarize Masked Memory Intrinsics ; GCN-O0-NEXT: Expand reduction intrinsics ; GCN-O0-NEXT: AMDGPU Attributor -; GCN-O0-NEXT: FunctionPass Manager -; GCN-O0-NEXT: Cycle Info Analysis ; GCN-O0-NEXT: CallGraph Construction ; GCN-O0-NEXT: Call Graph SCC Pass Manager ; GCN-O0-NEXT: AMDGPU Annotate Kernel Features @@ -227,8 +225,6 @@ ; GCN-O1-NEXT: Natural Loop Information ; GCN-O1-NEXT: TLS Variable Hoist ; GCN-O1-NEXT: AMDGPU Attributor -; GCN-O1-NEXT: FunctionPass Manager -; GCN-O1-NEXT: Cycle Info Analysis ; GCN-O1-NEXT: CallGraph Construction ; GCN-O1-NEXT: Call Graph SCC Pass Manager ; GCN-O1-NEXT: AMDGPU Annotate Kernel Features @@ -513,8 +509,6 @@ ; GCN-O1-OPTS-NEXT: TLS Variable Hoist ; GCN-O1-OPTS-NEXT: Early CSE ; GCN-O1-OPTS-NEXT: AMDGPU Attributor -; GCN-O1-OPTS-NEXT: FunctionPass Manager -; GCN-O1-OPTS-NEXT: Cycle Info Analysis ; GCN-O1-OPTS-NEXT: CallGraph Construction ; GCN-O1-OPTS-NEXT: Call Graph SCC Pass Manager ; GCN-O1-OPTS-NEXT: AMDGPU Annotate Kernel Features @@ -813,8 +807,6 @@ ; GCN-O2-NEXT: TLS Variable Hoist ; GCN-O2-NEXT: Early CSE ; GCN-O2-NEXT: AMDGPU Attributor -; GCN-O2-NEXT: FunctionPass Manager -; GCN-O2-NEXT: Cycle Info Analysis ; GCN-O2-NEXT: CallGraph Construction ; GCN-O2-NEXT: Call Graph SCC Pass Manager ; GCN-O2-NEXT: AMDGPU Annotate Kernel Features @@ -1126,8 +1118,6 @@ ; GCN-O3-NEXT: Optimization Remark Emitter ; GCN-O3-NEXT: Global Value Numbering ; GCN-O3-NEXT: AMDGPU Attributor -; GCN-O3-NEXT: FunctionPass Manager -; GCN-O3-NEXT: Cycle Info Analysis ; GCN-O3-NEXT: CallGraph Construction ; GCN-O3-NEXT: Call Graph SCC Pass Manager ; GCN-O3-NEXT: AMDGPU Annotate Kernel Features diff --git a/llvm/test/Transforms/Attributor/multiple-offsets-pointer-info.ll b/llvm/test/Transforms/Attributor/multiple-offsets-pointer-info.ll index a2915d0c5e953..6669f34468695 100644 --- a/llvm/test/Transforms/Attributor/multiple-offsets-pointer-info.ll +++ b/llvm/test/Transforms/Attributor/multiple-offsets-pointer-info.ll @@ -291,172 +291,6 @@ entry: ret i8 %i } -; FIXME: The whole function is just "ret i8 21". - -define i8 @phi_gep_simplifiable_1(i1 %cnd1, i1 %cnd2) { -; CHECK: Function Attrs: nofree norecurse nosync nounwind willreturn -; CHECK-LABEL: define {{[^@]+}}@phi_gep_simplifiable_1 -; CHECK-SAME: (i1 [[CND1:%.*]], i1 [[CND2:%.*]]) #[[ATTR2]] { -; CHECK-NEXT: entry: -; CHECK-NEXT: [[BYTES:%.*]] = alloca [1024 x i8], align 16 -; CHECK-NEXT: br i1 [[CND1]], label [[THEN:%.*]], label [[ELSE:%.*]] -; CHECK: then: -; CHECK-NEXT: [[GEP23:%.*]] = getelementptr inbounds [1024 x i8], [1024 x i8]* [[BYTES]], i64 0, i64 23 -; CHECK-NEXT: store i8 21, i8* [[GEP23]], align 4 -; CHECK-NEXT: br label [[JOIN:%.*]] -; CHECK: else: -; CHECK-NEXT: [[GEP31:%.*]] = getelementptr inbounds [1024 x i8], [1024 x i8]* [[BYTES]], i64 0, i64 31 -; CHECK-NEXT: store i8 21, i8* [[GEP31]], align 4 -; CHECK-NEXT: br label [[JOIN]] -; CHECK: join: -; CHECK-NEXT: [[PHI_PTR:%.*]] = phi i8* [ [[GEP23]], [[THEN]] ], [ [[GEP31]], [[ELSE]] ] -; CHECK-NEXT: [[GEP29:%.*]] = getelementptr inbounds [1024 x i8], [1024 x i8]* [[BYTES]], i64 0, i64 29 -; CHECK-NEXT: [[I:%.*]] = load i8, i8* [[PHI_PTR]], align 4 -; CHECK-NEXT: ret i8 [[I]] -; -entry: - %Bytes = alloca [1024 x i8], align 16 - br i1 %cnd1, label %then, label %else - -then: - %gep23 = getelementptr inbounds [1024 x i8], [1024 x i8]* %Bytes, i64 0, i64 23 - store i8 21, i8* %gep23, align 4 - br label %join - -else: - %gep31 = getelementptr inbounds [1024 x i8], [1024 x i8]* %Bytes, i64 0, i64 31 - store i8 21, i8* %gep31, align 4 - br label %join - -join: - %phi.ptr = phi i8* [%gep23, %then], [%gep31, %else] - ;; This store is eliminated - %gep29 = getelementptr inbounds [1024 x i8], [1024 x i8]* %Bytes, i64 0, i64 29 - store i8 42, i8* %gep29, align 4 - %i = load i8, i8* %phi.ptr, align 4 - ret i8 %i -} - -; FIXME: The whole function is just "ret i8 42". - -define i8 @phi_gep_simplifiable_2(i1 %cnd1, i1 %cnd2) { -; CHECK: Function Attrs: nofree norecurse nosync nounwind willreturn memory(write) -; CHECK-LABEL: define {{[^@]+}}@phi_gep_simplifiable_2 -; CHECK-SAME: (i1 [[CND1:%.*]], i1 [[CND2:%.*]]) #[[ATTR1]] { -; CHECK-NEXT: entry: -; CHECK-NEXT: [[BYTES:%.*]] = alloca [1024 x i8], align 16 -; CHECK-NEXT: br i1 [[CND1]], label [[THEN:%.*]], label [[ELSE:%.*]] -; CHECK: then: -; CHECK-NEXT: [[GEP23:%.*]] = getelementptr inbounds [1024 x i8], [1024 x i8]* [[BYTES]], i64 0, i64 23 -; CHECK-NEXT: br label [[JOIN:%.*]] -; CHECK: else: -; CHECK-NEXT: [[GEP31:%.*]] = getelementptr inbounds [1024 x i8], [1024 x i8]* [[BYTES]], i64 0, i64 31 -; CHECK-NEXT: br label [[JOIN]] -; CHECK: join: -; CHECK-NEXT: [[PHI_PTR:%.*]] = phi i8* [ [[GEP23]], [[THEN]] ], [ [[GEP31]], [[ELSE]] ] -; CHECK-NEXT: store i8 21, i8* [[PHI_PTR]], align 4 -; CHECK-NEXT: ret i8 42 -; -entry: - %Bytes = alloca [1024 x i8], align 16 - %gep29 = getelementptr inbounds [1024 x i8], [1024 x i8]* %Bytes, i64 0, i64 29 - ;; This store is propagated to the load. - store i8 42, i8* %gep29, align 4 - br i1 %cnd1, label %then, label %else - -then: - %gep23 = getelementptr inbounds [1024 x i8], [1024 x i8]* %Bytes, i64 0, i64 23 - br label %join - -else: - %gep31 = getelementptr inbounds [1024 x i8], [1024 x i8]* %Bytes, i64 0, i64 31 - br label %join - -join: - %phi.ptr = phi i8* [%gep23, %then], [%gep31, %else] - store i8 21, i8* %phi.ptr, align 4 - ;; Replaced with the constant, and both store/load are eliminated. - %i = load i8, i8* %gep29, align 4 - ret i8 %i -} - -define i8 @phi_gep_not_simplifiable_1(i1 %cnd1, i1 %cnd2) { -; CHECK: Function Attrs: nofree norecurse nosync nounwind willreturn -; CHECK-LABEL: define {{[^@]+}}@phi_gep_not_simplifiable_1 -; CHECK-SAME: (i1 [[CND1:%.*]], i1 [[CND2:%.*]]) #[[ATTR2]] { -; CHECK-NEXT: entry: -; CHECK-NEXT: [[BYTES:%.*]] = alloca [1024 x i8], align 16 -; CHECK-NEXT: [[GEP23:%.*]] = getelementptr inbounds [1024 x i8], [1024 x i8]* [[BYTES]], i64 0, i64 23 -; CHECK-NEXT: br i1 [[CND1]], label [[THEN:%.*]], label [[ELSE:%.*]] -; CHECK: then: -; CHECK-NEXT: br label [[JOIN:%.*]] -; CHECK: else: -; CHECK-NEXT: [[GEP31:%.*]] = getelementptr inbounds [1024 x i8], [1024 x i8]* [[BYTES]], i64 0, i64 31 -; CHECK-NEXT: br label [[JOIN]] -; CHECK: join: -; CHECK-NEXT: [[PHI_PTR:%.*]] = phi i8* [ [[GEP23]], [[THEN]] ], [ [[GEP31]], [[ELSE]] ] -; CHECK-NEXT: store i8 42, i8* [[GEP23]], align 4 -; CHECK-NEXT: [[I:%.*]] = load i8, i8* [[PHI_PTR]], align 4 -; CHECK-NEXT: ret i8 [[I]] -; -entry: - %Bytes = alloca [1024 x i8], align 16 - %gep23 = getelementptr inbounds [1024 x i8], [1024 x i8]* %Bytes, i64 0, i64 23 - br i1 %cnd1, label %then, label %else - -then: - br label %join - -else: - %gep31 = getelementptr inbounds [1024 x i8], [1024 x i8]* %Bytes, i64 0, i64 31 - br label %join - -join: - %phi.ptr = phi i8* [%gep23, %then], [%gep31, %else] - ;; This store cannot be eliminated - store i8 42, i8* %gep23, align 4 - %i = load i8, i8* %phi.ptr, align 4 - ret i8 %i -} - -define i8 @phi_gep_not_simplifiable_2(i1 %cnd1, i1 %cnd2) { -; CHECK: Function Attrs: nofree norecurse nosync nounwind willreturn -; CHECK-LABEL: define {{[^@]+}}@phi_gep_not_simplifiable_2 -; CHECK-SAME: (i1 [[CND1:%.*]], i1 [[CND2:%.*]]) #[[ATTR2]] { -; CHECK-NEXT: entry: -; CHECK-NEXT: [[BYTES:%.*]] = alloca [1024 x i8], align 16 -; CHECK-NEXT: [[GEP23:%.*]] = getelementptr inbounds [1024 x i8], [1024 x i8]* [[BYTES]], i64 0, i64 23 -; CHECK-NEXT: br i1 [[CND1]], label [[THEN:%.*]], label [[ELSE:%.*]] -; CHECK: then: -; CHECK-NEXT: br label [[JOIN:%.*]] -; CHECK: else: -; CHECK-NEXT: [[GEP31:%.*]] = getelementptr inbounds [1024 x i8], [1024 x i8]* [[BYTES]], i64 0, i64 31 -; CHECK-NEXT: br label [[JOIN]] -; CHECK: join: -; CHECK-NEXT: [[PHI_PTR:%.*]] = phi i8* [ [[GEP23]], [[THEN]] ], [ [[GEP31]], [[ELSE]] ] -; CHECK-NEXT: store i8 21, i8* [[PHI_PTR]], align 4 -; CHECK-NEXT: [[I:%.*]] = load i8, i8* [[GEP23]], align 4 -; CHECK-NEXT: ret i8 [[I]] -; -entry: - %Bytes = alloca [1024 x i8], align 16 - %gep23 = getelementptr inbounds [1024 x i8], [1024 x i8]* %Bytes, i64 0, i64 23 - br i1 %cnd1, label %then, label %else - -then: - br label %join - -else: - %gep31 = getelementptr inbounds [1024 x i8], [1024 x i8]* %Bytes, i64 0, i64 31 - br label %join - -join: - %phi.ptr = phi i8* [%gep23, %then], [%gep31, %else] - store i8 21, i8* %phi.ptr, align 4 - %i = load i8, i8* %gep23, align 4 - ret i8 %i -} - ; FIXME: This should be simplifiable. See comment inside. define i8 @phi_offsets_fixme(i1 %cnd1, i1 %cnd2) { @@ -506,6 +340,3 @@ join: ; CHECK: attributes #[[ATTR1]] = { nofree norecurse nosync nounwind willreturn memory(write) } ; CHECK: attributes #[[ATTR2]] = { nofree norecurse nosync nounwind willreturn } ;. -;; NOTE: These prefixes are unused and the list is autogenerated. Do not add tests below this line: -; CGSCC: {{.*}} -; TUNIT: {{.*}}