diff --git a/llvm/include/llvm/Transforms/IPO/Attributor.h b/llvm/include/llvm/Transforms/IPO/Attributor.h --- a/llvm/include/llvm/Transforms/IPO/Attributor.h +++ b/llvm/include/llvm/Transforms/IPO/Attributor.h @@ -130,6 +130,7 @@ #include "llvm/Support/ErrorHandling.h" #include "llvm/Support/ModRef.h" #include "llvm/Support/TimeProfiler.h" +#include "llvm/Support/TypeSize.h" #include "llvm/TargetParser/Triple.h" #include "llvm/Transforms/Utils/CallGraphUpdater.h" @@ -6109,6 +6110,42 @@ static const char ID; }; +struct AAAllocationInfo : public StateWrapper { + AAAllocationInfo(const IRPosition &IRP, Attributor &A) + : StateWrapper(IRP) {} + + /// See AbstractAttribute::isValidIRPositionForInit + static bool isValidIRPositionForInit(Attributor &A, const IRPosition &IRP) { + if (!IRP.getAssociatedType()->isPtrOrPtrVectorTy()) + return false; + return AbstractAttribute::isValidIRPositionForInit(A, IRP); + } + + /// Create an abstract attribute view for the position \p IRP. + static AAAllocationInfo &createForPosition(const IRPosition &IRP, + Attributor &A); + + virtual std::optional getAllocatedSize() const = 0; + + /// See AbstractAttribute::getName() + const std::string getName() const override { return "AAAllocationInfo"; } + + /// See AbstractAttribute::getIdAddr() + const char *getIdAddr() const override { return &ID; } + + /// This function should return true if the type of the \p AA is + /// AAAllocationInfo + static bool classof(const AbstractAttribute *AA) { + return (AA->getIdAddr() == &ID); + } + + // No AllocatedSpace which means it doesn't allocated memory. + constexpr static const std::optional NOAllocatedSize = + std::optional(TypeSize(-1, true)); + + static const char ID; +}; + /// An abstract interface for indirect call information interference. struct AAIndirectCallInfo : public StateWrapper { diff --git a/llvm/lib/Transforms/IPO/Attributor.cpp b/llvm/lib/Transforms/IPO/Attributor.cpp --- a/llvm/lib/Transforms/IPO/Attributor.cpp +++ b/llvm/lib/Transforms/IPO/Attributor.cpp @@ -3575,6 +3575,18 @@ UsedAssumedInformation); (void)Success; assert(Success && "Expected the check call to be successful!"); + + // AllocaInstPredicate + auto AllocaInstPred = [&](Instruction &I) -> bool { + getOrCreateAAFor(IRPosition::value(I)); + return true; + }; + + Success = checkForAllInstructionsImpl( + nullptr, OpcodeInstMap, AllocaInstPred, nullptr, nullptr, + {(unsigned)Instruction::Alloca}, UsedAssumedInformation); + (void)Success; + assert(Success && "Expected the check call to be successful!"); } /// Helpers to ease debugging through output streams and print calls. diff --git a/llvm/lib/Transforms/IPO/AttributorAttributes.cpp b/llvm/lib/Transforms/IPO/AttributorAttributes.cpp --- a/llvm/lib/Transforms/IPO/AttributorAttributes.cpp +++ b/llvm/lib/Transforms/IPO/AttributorAttributes.cpp @@ -64,6 +64,7 @@ #include "llvm/Support/ErrorHandling.h" #include "llvm/Support/GraphWriter.h" #include "llvm/Support/MathExtras.h" +#include "llvm/Support/TypeSize.h" #include "llvm/Support/raw_ostream.h" #include "llvm/Transforms/Utils/BasicBlockUtils.h" #include "llvm/Transforms/Utils/CallPromotionUtils.h" @@ -191,6 +192,7 @@ PIPE_OPERATOR(AAAssumptionInfo) PIPE_OPERATOR(AAUnderlyingObjects) PIPE_OPERATOR(AAAddressSpace) +PIPE_OPERATOR(AAAllocationInfo) PIPE_OPERATOR(AAIndirectCallInfo) #undef PIPE_OPERATOR @@ -873,6 +875,7 @@ using const_bin_iterator = OffsetBinsTy::const_iterator; const_bin_iterator begin() const { return OffsetBins.begin(); } const_bin_iterator end() const { return OffsetBins.end(); } + int64_t numOffsetBins() const { return OffsetBins.size(); } const AAPointerInfo::Access &getAccess(unsigned Index) const { return AccessList[Index]; @@ -12445,6 +12448,173 @@ }; } // namespace +/// ----------- Allocation Info ---------- +namespace { +struct AAAllocationInfoImpl : public AAAllocationInfo { + AAAllocationInfoImpl(const IRPosition &IRP, Attributor &A) + : AAAllocationInfo(IRP, A) {} + + std::optional getAllocatedSize() const override { + assert(isValidState() && "the AA is invalid"); + return AssumedAllocatedSize; + } + + ChangeStatus updateImpl(Attributor &A) override { + + auto *I = getIRPosition().getCtxI(); + + if (!I) + return indicatePessimisticFixpoint(); + + auto *AI = dyn_cast(I); + + if (!AI) + return indicatePessimisticFixpoint(); + + const IRPosition &IRP = getIRPosition(); + const AAPointerInfo *PI = + A.getOrCreateAAFor(IRP, *this, DepClassTy::OPTIONAL); + + if (!PI) + return indicatePessimisticFixpoint(); + + if (!PI->getState().isValidState()) + return indicatePessimisticFixpoint(); + + const auto &OtherAAImpl = static_cast(*PI); + const auto &State = OtherAAImpl.getState(); + + int64_t BinSize = State.numOffsetBins(); + + if (BinSize > 1) + return indicatePessimisticFixpoint(); + + const auto &It = State.begin(); + + if (It == State.end()) + return indicatePessimisticFixpoint(); + + if (It->getFirst().Offset != 0) + return indicatePessimisticFixpoint(); + + int64_t OffsetEnd = It->getFirst().Offset + It->getFirst().Size; + const DataLayout &DL = A.getDataLayout(); + const auto &AllocationSize = AI->getAllocationSize(DL); + + if (!AllocationSize) + return indicatePessimisticFixpoint(); + + if (OffsetEnd == AllocationSize) + return indicatePessimisticFixpoint(); + + Type *IntegerSizeOfOffsetEnd = + Type::getIntNTy(AI->getContext(), OffsetEnd * 8); + + if (!changeAllocationSize(IntegerSizeOfOffsetEnd->getPrimitiveSizeInBits())) + return ChangeStatus::UNCHANGED; + + return ChangeStatus::CHANGED; + } + + /// See AbstractAttribute::manifest(...). + ChangeStatus manifest(Attributor &A) override { + + assert(isValidState() && + "Manifest should only be called if the state is valid."); + + auto *I = this->getIRPosition().getCtxI(); + AllocaInst &AI = cast(*I); + + Type *IntegerSizeOfAlloca = + Type::getIntNTy(AI.getContext(), getAllocatedSize()->getFixedValue()); + + AI.setAllocatedType(IntegerSizeOfAlloca); + return ChangeStatus::CHANGED; + } + + /// See AbstractAttribute::getAsStr(). + const std::string getAsStr(Attributor *A) const override { + if (!isValidState()) + return "allocationinfo()"; + return "allocationinfo(" + + (AssumedAllocatedSize == NOAllocatedSize + ? "none" + : std::to_string(AssumedAllocatedSize->getFixedValue())) + + ")"; + } + +private: + std::optional AssumedAllocatedSize = NOAllocatedSize; + + bool changeAllocationSize(std::optional Size) { + if (AssumedAllocatedSize == NOAllocatedSize || + AssumedAllocatedSize != Size) { + AssumedAllocatedSize = Size; + return true; + } + return false; + } +}; + +struct AAAllocationInfoFloating : AAAllocationInfoImpl { + AAAllocationInfoFloating(const IRPosition &IRP, Attributor &A) + : AAAllocationInfoImpl(IRP, A) {} + + void trackStatistics() const override { + STATS_DECLTRACK_FLOATING_ATTR(allocationinfo); + } +}; + +struct AAAllocationInfoReturned : AAAllocationInfoImpl { + AAAllocationInfoReturned(const IRPosition &IRP, Attributor &A) + : AAAllocationInfoImpl(IRP, A) {} + + /// See AbstractAttribute::initialize(...). + void initialize(Attributor &A) override { + // TODO: we don't rewrite function argument for now because it will need to + // rewrite the function signature and all call sites + (void)indicatePessimisticFixpoint(); + } + + void trackStatistics() const override { + STATS_DECLTRACK_FNRET_ATTR(allocationinfo); + } +}; + +struct AAAllocationInfoCallSiteReturned : AAAllocationInfoImpl { + AAAllocationInfoCallSiteReturned(const IRPosition &IRP, Attributor &A) + : AAAllocationInfoImpl(IRP, A) {} + + void trackStatistics() const override { + STATS_DECLTRACK_CSRET_ATTR(allocationinfo); + } +}; + +struct AAAllocationInfoArgument : AAAllocationInfoImpl { + AAAllocationInfoArgument(const IRPosition &IRP, Attributor &A) + : AAAllocationInfoImpl(IRP, A) {} + + void trackStatistics() const override { + STATS_DECLTRACK_ARG_ATTR(allocationinfo); + } +}; + +struct AAAllocationInfoCallSiteArgument : AAAllocationInfoImpl { + AAAllocationInfoCallSiteArgument(const IRPosition &IRP, Attributor &A) + : AAAllocationInfoImpl(IRP, A) {} + + /// See AbstractAttribute::initialize(...). + void initialize(Attributor &A) override { + + (void)indicatePessimisticFixpoint(); + } + + void trackStatistics() const override { + STATS_DECLTRACK_CSARG_ATTR(allocationinfo); + } +}; +} // namespace + const char AANoUnwind::ID = 0; const char AANoSync::ID = 0; const char AANoFree::ID = 0; @@ -12478,6 +12648,7 @@ const char AAAssumptionInfo::ID = 0; const char AAUnderlyingObjects::ID = 0; const char AAAddressSpace::ID = 0; +const char AAAllocationInfo::ID = 0; const char AAIndirectCallInfo::ID = 0; // Macro magic to create the static generator function for attributes that @@ -12609,6 +12780,7 @@ CREATE_VALUE_ABSTRACT_ATTRIBUTE_FOR_POSITION(AANoFPClass) CREATE_VALUE_ABSTRACT_ATTRIBUTE_FOR_POSITION(AAPointerInfo) CREATE_VALUE_ABSTRACT_ATTRIBUTE_FOR_POSITION(AAAddressSpace) +CREATE_VALUE_ABSTRACT_ATTRIBUTE_FOR_POSITION(AAAllocationInfo) CREATE_ALL_ABSTRACT_ATTRIBUTE_FOR_POSITION(AAValueSimplify) CREATE_ALL_ABSTRACT_ATTRIBUTE_FOR_POSITION(AAIsDead) diff --git a/llvm/test/Transforms/Attributor/allocator.ll b/llvm/test/Transforms/Attributor/allocator.ll new file mode 100644 --- /dev/null +++ b/llvm/test/Transforms/Attributor/allocator.ll @@ -0,0 +1,158 @@ +; NOTE: Assertions have been autogenerated by utils/update_test_checks.py UTC_ARGS: --check-attributes --check-globals --version 2 +; RUN: opt -aa-pipeline=basic-aa -passes=attributor -attributor-manifest-internal -attributor-annotate-decl-cs -S < %s | FileCheck %s --check-prefixes=CHECK,TUNIT +; RUN: opt -aa-pipeline=basic-aa -passes=attributor-cgscc -attributor-manifest-internal -attributor-annotate-decl-cs -S < %s | FileCheck %s --check-prefixes=CHECK,CGSCC + +%struct.Foo = type { i32, i32, i8 } + +@.str = private unnamed_addr constant [15 x i8] c"Field 1 is %d\0A\00", align 1 + +;. +; CHECK: @[[_STR:[a-zA-Z0-9_$"\\.-]+]] = private unnamed_addr constant [15 x i8] c"Field 1 is %d\0A\00", align 1 +;. +define dso_local void @foo_positive_test(i32 noundef %val) #0 { +; CHECK-LABEL: define dso_local void @foo_positive_test +; CHECK-SAME: (i32 noundef [[VAL:%.*]]) { +; CHECK-NEXT: entry: +; CHECK-NEXT: [[VAL_ADDR:%.*]] = alloca i32, align 4 +; CHECK-NEXT: [[F:%.*]] = alloca i32, align 4 +; CHECK-NEXT: store i32 [[VAL]], ptr [[VAL_ADDR]], align 4 +; CHECK-NEXT: store i32 10, ptr [[F]], align 4 +; CHECK-NEXT: [[TMP0:%.*]] = load i32, ptr [[F]], align 4 +; CHECK-NEXT: [[ADD:%.*]] = add nsw i32 [[TMP0]], 1 +; CHECK-NEXT: store i32 [[ADD]], ptr [[F]], align 4 +; CHECK-NEXT: [[TMP1:%.*]] = load i32, ptr [[F]], align 4 +; CHECK-NEXT: [[ADD3:%.*]] = add nsw i32 [[TMP1]], [[VAL]] +; CHECK-NEXT: [[CALL:%.*]] = call i32 (ptr, ...) @printf(ptr noundef nonnull dereferenceable(15) @.str, i32 noundef [[ADD3]]) +; CHECK-NEXT: ret void +; +entry: + %val.addr = alloca i64, align 4 + %f = alloca %struct.Foo, align 4 + store i32 %val, ptr %val.addr, align 4 + %field1 = getelementptr inbounds %struct.Foo, ptr %f, i32 0, i32 0 + store i32 10, ptr %field1, align 4 + %field11 = getelementptr inbounds %struct.Foo, ptr %f, i32 0, i32 0 + %0 = load i32, ptr %field11, align 4 + %add = add nsw i32 %0, 1 + store i32 %add, ptr %field11, align 4 + %field12 = getelementptr inbounds %struct.Foo, ptr %f, i32 0, i32 0 + %1 = load i32, ptr %field12, align 4 + %2 = load i32, ptr %val.addr, align 4 + %add3 = add nsw i32 %1, %2 + %call = call i32 (ptr, ...) @printf(ptr noundef @.str, i32 noundef %add3) + ret void +} + +; Function Attrs: noinline nounwind uwtable +define dso_local void @foo_positive_test_malloc(ptr noundef %val) #0 { +; CHECK-LABEL: define dso_local void @foo_positive_test_malloc +; CHECK-SAME: (ptr nocapture nofree noundef readonly [[VAL:%.*]]) { +; CHECK-NEXT: entry: +; CHECK-NEXT: [[VAL_ADDR:%.*]] = alloca ptr, align 8 +; CHECK-NEXT: [[F:%.*]] = alloca ptr, align 8 +; CHECK-NEXT: store ptr [[VAL]], ptr [[VAL_ADDR]], align 8 +; CHECK-NEXT: [[CALL:%.*]] = call noalias ptr @malloc(i64 noundef 12) +; CHECK-NEXT: store ptr [[CALL]], ptr [[F]], align 8 +; CHECK-NEXT: [[TMP0:%.*]] = load i32, ptr [[VAL]], align 4 +; CHECK-NEXT: [[ADD:%.*]] = add nsw i32 [[TMP0]], 10 +; CHECK-NEXT: store i32 [[ADD]], ptr [[CALL]], align 4 +; CHECK-NEXT: [[TMP1:%.*]] = load i32, ptr [[CALL]], align 4 +; CHECK-NEXT: [[CALL2:%.*]] = call i32 (ptr, ...) @printf(ptr noundef nonnull dereferenceable(15) @.str, i32 noundef [[TMP1]]) +; CHECK-NEXT: ret void +; +entry: + %val.addr = alloca ptr, align 8 + %f = alloca ptr, align 8 + store ptr %val, ptr %val.addr, align 8 + %call = call noalias ptr @malloc(i64 noundef 12) #3 ;TODO The bytes allocated in this malloc should be reduced to an i32. + store ptr %call, ptr %f, align 8 + %0 = load ptr, ptr %val.addr, align 8 + %1 = load i32, ptr %0, align 4 + %add = add nsw i32 %1, 10 + %2 = load ptr, ptr %f, align 8 + %a = getelementptr inbounds %struct.Foo, ptr %2, i32 0, i32 0 + store i32 %add, ptr %a, align 4 + %3 = load ptr, ptr %f, align 8 + %a1 = getelementptr inbounds %struct.Foo, ptr %3, i32 0, i32 0 + %4 = load i32, ptr %a1, align 4 + %call2 = call i32 (ptr, ...) @printf(ptr noundef @.str, i32 noundef %4) + ret void +} + +; Function Attrs: noinline nounwind uwtable +define dso_local ptr @foo_negative_test_escaping_pointer(i32 noundef %val) #0 { +; CHECK-LABEL: define dso_local ptr @foo_negative_test_escaping_pointer +; CHECK-SAME: (i32 noundef [[VAL:%.*]]) { +; CHECK-NEXT: entry: +; CHECK-NEXT: [[VAL_ADDR:%.*]] = alloca i32, align 4 +; CHECK-NEXT: [[F:%.*]] = alloca ptr, align 8 +; CHECK-NEXT: store i32 [[VAL]], ptr [[VAL_ADDR]], align 4 +; CHECK-NEXT: [[CALL:%.*]] = call noalias ptr @malloc(i64 noundef 16) +; CHECK-NEXT: store ptr [[CALL]], ptr [[F]], align 8 +; CHECK-NEXT: [[TMP0:%.*]] = load ptr, ptr [[F]], align 8 +; CHECK-NEXT: store i32 2, ptr [[TMP0]], align 8 +; CHECK-NEXT: [[ADD:%.*]] = add nsw i32 10, [[VAL]] +; CHECK-NEXT: [[TMP1:%.*]] = load ptr, ptr [[F]], align 8 +; CHECK-NEXT: [[TMP2:%.*]] = load i32, ptr [[TMP1]], align 8 +; CHECK-NEXT: [[ADD2:%.*]] = add nsw i32 [[TMP2]], [[ADD]] +; CHECK-NEXT: store i32 [[ADD2]], ptr [[TMP1]], align 8 +; CHECK-NEXT: [[TMP3:%.*]] = load ptr, ptr [[F]], align 8 +; CHECK-NEXT: ret ptr [[TMP3]] +; +entry: + %val.addr = alloca i32, align 4 + %f = alloca ptr, align 8 + store i32 %val, ptr %val.addr, align 4 + %call = call noalias ptr @malloc(i64 noundef 16) #2 + store ptr %call, ptr %f, align 8 + %0 = load ptr, ptr %f, align 8 + %field1 = getelementptr inbounds %struct.Foo, ptr %0, i32 0, i32 0 + store i32 2, ptr %field1, align 8 + %1 = load i32, ptr %val.addr, align 4 + %add = add nsw i32 10, %1 + %2 = load ptr, ptr %f, align 8 + %field11 = getelementptr inbounds %struct.Foo, ptr %2, i32 0, i32 0 + %3 = load i32, ptr %field11, align 8 + %add2 = add nsw i32 %3, %add + store i32 %add2, ptr %field11, align 8 + %4 = load ptr, ptr %f, align 8 + ret ptr %4 +} + +; Function Attrs: noinline nounwind uwtable +define dso_local { i64, ptr } @foo_negative_test_not_a_single_start_offset(i32 noundef %val) #0 { +; CHECK: Function Attrs: mustprogress nofree norecurse nosync nounwind willreturn memory(none) +; CHECK-LABEL: define dso_local { i64, ptr } @foo_negative_test_not_a_single_start_offset +; CHECK-SAME: (i32 noundef [[VAL:%.*]]) #[[ATTR0:[0-9]+]] { +; CHECK-NEXT: entry: +; CHECK-NEXT: [[RETVAL:%.*]] = alloca [[STRUCT_FOO:%.*]], align 8 +; CHECK-NEXT: [[VAL_ADDR:%.*]] = alloca i32, align 4 +; CHECK-NEXT: store i32 [[VAL]], ptr [[VAL_ADDR]], align 4 +; CHECK-NEXT: store i32 2, ptr [[RETVAL]], align 8 +; CHECK-NEXT: [[FIELD3:%.*]] = getelementptr inbounds [[STRUCT_FOO]], ptr [[RETVAL]], i32 0, i32 2 +; CHECK-NEXT: store ptr [[VAL_ADDR]], ptr [[FIELD3]], align 8 +; CHECK-NEXT: [[TMP0:%.*]] = load { i64, ptr }, ptr [[RETVAL]], align 8 +; CHECK-NEXT: ret { i64, ptr } [[TMP0]] +; +entry: + %retval = alloca %struct.Foo, align 8 + %val.addr = alloca i32, align 4 + store i32 %val, ptr %val.addr, align 4 + %field1 = getelementptr inbounds %struct.Foo, ptr %retval, i32 0, i32 0 + store i32 2, ptr %field1, align 8 + %field3 = getelementptr inbounds %struct.Foo, ptr %retval, i32 0, i32 2 + store ptr %val.addr, ptr %field3, align 8 + %0 = load { i64, ptr }, ptr %retval, align 8 + ret { i64, ptr } %0 +} + +declare i32 @printf(ptr noundef, ...) #1 + +; Function Attrs: nounwind allocsize(0) +declare noalias ptr @malloc(i64 noundef) #1 +;. +; CHECK: attributes #[[ATTR0]] = { mustprogress nofree norecurse nosync nounwind willreturn memory(none) } +;. +;; NOTE: These prefixes are unused and the list is autogenerated. Do not add tests below this line: +; CGSCC: {{.*}} +; TUNIT: {{.*}} diff --git a/llvm/test/Transforms/Attributor/reduced/missed_cached_entry_for_intra_reachability.ll b/llvm/test/Transforms/Attributor/reduced/missed_cached_entry_for_intra_reachability.ll --- a/llvm/test/Transforms/Attributor/reduced/missed_cached_entry_for_intra_reachability.ll +++ b/llvm/test/Transforms/Attributor/reduced/missed_cached_entry_for_intra_reachability.ll @@ -18,7 +18,7 @@ ; CHECK-SAME: (ptr nocapture nofree writeonly [[ARG1:%.*]], float [[ARG2:%.*]], i64 [[IDX1:%.*]], i64 [[IDX2:%.*]], i32 [[LIMIT:%.*]]) #[[ATTR0:[0-9]+]] { ; CHECK-NEXT: bb: ; CHECK-NEXT: [[ALLOCA:%.*]] = alloca [128 x float], i32 0, align 4 -; CHECK-NEXT: [[ALLOCA3:%.*]] = alloca [81 x float], i32 0, align 4 +; CHECK-NEXT: [[ALLOCA3:%.*]] = alloca i32, i32 0, align 4 ; CHECK-NEXT: store float 0.000000e+00, ptr [[ALLOCA3]], align 4 ; CHECK-NEXT: br label [[BB4:%.*]] ; CHECK: bb4: diff --git a/llvm/test/Transforms/Attributor/value-simplify-local-remote.ll b/llvm/test/Transforms/Attributor/value-simplify-local-remote.ll --- a/llvm/test/Transforms/Attributor/value-simplify-local-remote.ll +++ b/llvm/test/Transforms/Attributor/value-simplify-local-remote.ll @@ -79,7 +79,7 @@ ; CGSCC-LABEL: define {{[^@]+}}@bar ; CGSCC-SAME: (ptr noalias nofree noundef nonnull readnone returned align 8 dereferenceable(8) "no-capture-maybe-returned" [[QQFIRST:%.*]]) #[[ATTR1:[0-9]+]] { ; CGSCC-NEXT: entry: -; CGSCC-NEXT: [[QQFIRST_ADDR:%.*]] = alloca ptr, i32 0, align 8 +; CGSCC-NEXT: [[QQFIRST_ADDR:%.*]] = alloca i64, i32 0, align 8 ; CGSCC-NEXT: store ptr [[QQFIRST]], ptr [[QQFIRST_ADDR]], align 8 ; CGSCC-NEXT: br label [[WHILE_COND:%.*]] ; CGSCC: while.cond: @@ -132,10 +132,10 @@ ; TUNIT-LABEL: define {{[^@]+}}@foo.1 ; TUNIT-SAME: (ptr nofree noundef nonnull align 8 dereferenceable(8) [[FOO_THIS:%.*]]) #[[ATTR1]] { ; TUNIT-NEXT: entry: -; TUNIT-NEXT: [[RETVAL:%.*]] = alloca [[S:%.*]], i32 0, align 8 +; TUNIT-NEXT: [[RETVAL:%.*]] = alloca i64, i32 0, align 8 ; TUNIT-NEXT: store ptr [[FOO_THIS]], ptr [[FOO_THIS]], align 8 ; TUNIT-NEXT: call void @bar.2(ptr noalias nocapture nofree noundef nonnull writeonly align 8 [[RETVAL]], ptr nofree noundef nonnull writeonly align 8 dereferenceable(8) [[FOO_THIS]]) #[[ATTR5:[0-9]+]] -; TUNIT-NEXT: [[FOO_RET:%.*]] = load [[S]], ptr [[RETVAL]], align 8 +; TUNIT-NEXT: [[FOO_RET:%.*]] = load [[S:%.*]], ptr [[RETVAL]], align 8 ; TUNIT-NEXT: ret [[S]] [[FOO_RET]] ; ; CGSCC: Function Attrs: mustprogress nofree nosync nounwind willreturn memory(argmem: readwrite) @@ -231,10 +231,10 @@ ; TUNIT-LABEL: define {{[^@]+}}@bar.5 ; TUNIT-SAME: (ptr nofree noundef nonnull align 8 dereferenceable(8) [[THIS:%.*]]) #[[ATTR1]] { ; TUNIT-NEXT: entry: -; TUNIT-NEXT: [[RETVAL:%.*]] = alloca [[S:%.*]], i32 0, align 8 +; TUNIT-NEXT: [[RETVAL:%.*]] = alloca i64, i32 0, align 8 ; TUNIT-NEXT: store ptr [[THIS]], ptr [[THIS]], align 8 ; TUNIT-NEXT: call void @baz.6(ptr noalias nocapture nofree noundef nonnull writeonly align 8 [[RETVAL]], ptr nofree noundef nonnull align 8 dereferenceable(8) [[THIS]]) #[[ATTR4]] -; TUNIT-NEXT: [[BAR_RET:%.*]] = load [[S]], ptr [[RETVAL]], align 8 +; TUNIT-NEXT: [[BAR_RET:%.*]] = load [[S:%.*]], ptr [[RETVAL]], align 8 ; TUNIT-NEXT: ret [[S]] [[BAR_RET]] ; ; CGSCC: Function Attrs: mustprogress nofree nosync nounwind willreturn memory(argmem: readwrite) @@ -284,7 +284,7 @@ ; TUNIT-LABEL: define {{[^@]+}}@boom ; TUNIT-SAME: (ptr nocapture nofree noundef nonnull writeonly align 8 dereferenceable(8) [[THIS:%.*]], ptr nofree noundef nonnull align 8 dereferenceable(8) [[DATA:%.*]]) #[[ATTR1]] { ; TUNIT-NEXT: entry: -; TUNIT-NEXT: [[DATA_ADDR:%.*]] = alloca ptr, i32 0, align 8 +; TUNIT-NEXT: [[DATA_ADDR:%.*]] = alloca i64, i32 0, align 8 ; TUNIT-NEXT: store ptr [[DATA]], ptr [[DATA_ADDR]], align 8 ; TUNIT-NEXT: [[V:%.*]] = load ptr, ptr [[DATA_ADDR]], align 8 ; TUNIT-NEXT: store ptr [[V]], ptr [[THIS]], align 8 @@ -294,7 +294,7 @@ ; CGSCC-LABEL: define {{[^@]+}}@boom ; CGSCC-SAME: (ptr nocapture nofree noundef nonnull writeonly align 8 dereferenceable(8) [[THIS:%.*]], ptr nofree [[DATA:%.*]]) #[[ATTR4:[0-9]+]] { ; CGSCC-NEXT: entry: -; CGSCC-NEXT: [[DATA_ADDR:%.*]] = alloca ptr, i32 0, align 8 +; CGSCC-NEXT: [[DATA_ADDR:%.*]] = alloca i64, i32 0, align 8 ; CGSCC-NEXT: store ptr [[DATA]], ptr [[DATA_ADDR]], align 8 ; CGSCC-NEXT: store ptr [[DATA]], ptr [[THIS]], align 8 ; CGSCC-NEXT: ret void @@ -380,8 +380,8 @@ ; TUNIT-NEXT: store i32 [[X]], ptr [[TMP]], align 4 ; TUNIT-NEXT: br label [[BB16:%.*]] ; TUNIT: bb16: -; TUNIT-NEXT: [[TRUETMP18:%.*]] = icmp eq i32 [[X]], 0 -; TUNIT-NEXT: br i1 [[TRUETMP18]], label [[BB35:%.*]], label [[BB19:%.*]] +; TUNIT-NEXT: [[TMP18:%.*]] = icmp eq i32 [[X]], 0 +; TUNIT-NEXT: br i1 [[TMP18]], label [[BB35:%.*]], label [[BB19:%.*]] ; TUNIT: bb19: ; TUNIT-NEXT: br label [[BB23:%.*]] ; TUNIT: bb23: @@ -404,8 +404,8 @@ ; CGSCC-NEXT: store i32 [[X]], ptr [[TMP]], align 4 ; CGSCC-NEXT: br label [[BB16:%.*]] ; CGSCC: bb16: -; CGSCC-NEXT: [[TRUETMP18:%.*]] = icmp eq i32 [[X]], 0 -; CGSCC-NEXT: br i1 [[TRUETMP18]], label [[BB35:%.*]], label [[BB19:%.*]] +; CGSCC-NEXT: [[TMP18:%.*]] = icmp eq i32 [[X]], 0 +; CGSCC-NEXT: br i1 [[TMP18]], label [[BB35:%.*]], label [[BB19:%.*]] ; CGSCC: bb19: ; CGSCC-NEXT: br label [[BB23:%.*]] ; CGSCC: bb23: @@ -494,11 +494,11 @@ ; TUNIT-LABEL: define {{[^@]+}}@t4a ; TUNIT-SAME: (ptr nofree noundef nonnull writeonly align 8 dereferenceable(8) [[THIS:%.*]]) #[[ATTR0]] { ; TUNIT-NEXT: entry: -; TUNIT-NEXT: [[RETVAL:%.*]] = alloca [[S:%.*]], i32 0, align 8 +; TUNIT-NEXT: [[RETVAL:%.*]] = alloca i64, i32 0, align 8 ; TUNIT-NEXT: [[THIS_ADDR:%.*]] = alloca ptr, i32 0, align 8 ; TUNIT-NEXT: store ptr [[THIS]], ptr [[THIS]], align 8 ; TUNIT-NEXT: call void @t4b(ptr noalias nocapture nofree noundef nonnull writeonly align 8 [[RETVAL]]) #[[ATTR5]] -; TUNIT-NEXT: ret [[S]] undef +; TUNIT-NEXT: ret [[S:%.*]] undef ; ; CGSCC: Function Attrs: mustprogress nofree nosync nounwind willreturn memory(argmem: readwrite) ; CGSCC-LABEL: define {{[^@]+}}@t4a @@ -529,7 +529,7 @@ ; TUNIT-LABEL: define {{[^@]+}}@t4b ; TUNIT-SAME: (ptr noalias nocapture nofree noundef nonnull writeonly align 8 dereferenceable(8) [[THIS:%.*]]) #[[ATTR0]] { ; TUNIT-NEXT: entry: -; TUNIT-NEXT: [[THIS_ADDR:%.*]] = alloca ptr, i32 0, align 8 +; TUNIT-NEXT: [[THIS_ADDR:%.*]] = alloca i64, i32 0, align 8 ; TUNIT-NEXT: [[DATA_ADDR:%.*]] = alloca ptr, i32 0, align 8 ; TUNIT-NEXT: call void @t4c(ptr noalias nocapture nofree noundef nonnull writeonly align 8 dereferenceable(8) [[THIS]]) #[[ATTR5]] ; TUNIT-NEXT: ret void @@ -538,7 +538,7 @@ ; CGSCC-LABEL: define {{[^@]+}}@t4b ; CGSCC-SAME: (ptr noalias nocapture nofree noundef nonnull writeonly align 8 dereferenceable(8) [[THIS:%.*]], ptr nofree noundef nonnull writeonly align 8 dereferenceable(8) [[DATA:%.*]]) #[[ATTR0]] { ; CGSCC-NEXT: entry: -; CGSCC-NEXT: [[THIS_ADDR:%.*]] = alloca ptr, i32 0, align 8 +; CGSCC-NEXT: [[THIS_ADDR:%.*]] = alloca i64, i32 0, align 8 ; CGSCC-NEXT: [[DATA_ADDR:%.*]] = alloca ptr, i32 0, align 8 ; CGSCC-NEXT: store ptr [[DATA]], ptr [[THIS]], align 8 ; CGSCC-NEXT: call void @t4c(ptr nocapture nofree noundef nonnull writeonly align 8 dereferenceable(8) [[THIS]], ptr nofree noundef nonnull writeonly align 8 dereferenceable(8) [[DATA]]) #[[ATTR6]] @@ -560,7 +560,7 @@ ; TUNIT-LABEL: define {{[^@]+}}@t4c ; TUNIT-SAME: (ptr noalias nocapture nofree noundef nonnull writeonly align 8 dereferenceable(8) [[THIS:%.*]]) #[[ATTR0]] { ; TUNIT-NEXT: entry: -; TUNIT-NEXT: [[THIS_ADDR:%.*]] = alloca ptr, i32 0, align 8 +; TUNIT-NEXT: [[THIS_ADDR:%.*]] = alloca i64, i32 0, align 8 ; TUNIT-NEXT: [[DATA_ADDR:%.*]] = alloca ptr, i32 0, align 8 ; TUNIT-NEXT: ret void ; @@ -568,7 +568,7 @@ ; CGSCC-LABEL: define {{[^@]+}}@t4c ; CGSCC-SAME: (ptr nocapture nofree noundef nonnull writeonly align 8 dereferenceable(8) [[THIS:%.*]], ptr nofree writeonly [[DATA:%.*]]) #[[ATTR3]] { ; CGSCC-NEXT: entry: -; CGSCC-NEXT: [[THIS_ADDR:%.*]] = alloca ptr, i32 0, align 8 +; CGSCC-NEXT: [[THIS_ADDR:%.*]] = alloca i64, i32 0, align 8 ; CGSCC-NEXT: [[DATA_ADDR:%.*]] = alloca ptr, i32 0, align 8 ; CGSCC-NEXT: store ptr [[DATA]], ptr [[THIS]], align 8 ; CGSCC-NEXT: store ptr [[DATA]], ptr [[THIS]], align 8