[llvm] [Attributor] Fix Load/Store offsets in case of multiple access bins when an allocation size is changed. (PR #72029)
Vidush Singhal via llvm-commits
llvm-commits at lists.llvm.org
Thu May 30 10:24:46 PDT 2024
https://github.com/vidsinghal updated https://github.com/llvm/llvm-project/pull/72029
>From 9f303a458d364b71db39f519ad784b94c5f654d1 Mon Sep 17 00:00:00 2001
From: vidsinghal <vidush.sl at gmail.com>
Date: Sun, 5 Nov 2023 22:30:42 -0500
Subject: [PATCH] [Attributor] Fix Load/Store Offsets if multiple bins are
present for a pointer allocation.
---
llvm/include/llvm/Transforms/IPO/Attributor.h | 30 +-
.../Transforms/IPO/AttributorAttributes.cpp | 297 +++++++++++++--
.../DotCfg/print-changed-dot-cfg.ll | 1 +
.../DotCfg/print-changed-dot-cfg.mir | 13 +-
.../X86/min-legal-vector-width.ll | 84 ++---
.../Attributor/ArgumentPromotion/array.ll | 12 +-
.../Attributor/ArgumentPromotion/byval.ll | 8 +-
.../Attributor/ArgumentPromotion/crash.ll | 4 +-
.../live_called_from_dead.ll | 4 +-
.../live_called_from_dead_2.ll | 4 +-
.../nonzero-address-spaces.ll | 2 +-
.../Attributor/IPConstantProp/pthreads.ll | 4 +-
llvm/test/Transforms/Attributor/allocator.ll | 153 +++++---
.../Attributor/call-simplify-pointer-info.ll | 56 ++-
llvm/test/Transforms/Attributor/callbacks.ll | 28 +-
.../Transforms/Attributor/heap_to_stack.ll | 2 +-
.../Attributor/heap_to_stack_gpu.ll | 2 +-
llvm/test/Transforms/Attributor/liveness.ll | 8 +-
.../multiple-offsets-pointer-info.ll | 344 ++++++++++++------
llvm/test/Transforms/Attributor/noalias.ll | 6 +-
.../test/Transforms/Attributor/nocapture-2.ll | 20 +-
llvm/test/Transforms/Attributor/nodelete.ll | 4 +-
llvm/test/Transforms/Attributor/nofpclass.ll | 50 ++-
.../Transforms/Attributor/pointer-info.ll | 6 +-
.../Attributor/value-simplify-local-remote.ll | 47 ++-
.../value-simplify-pointer-info-vec.ll | 14 +-
.../Attributor/value-simplify-pointer-info.ll | 165 +++++----
llvm/test/Transforms/Attributor/wrapper.ll | 3 +-
.../Transforms/OpenMP/parallel_deletion.ll | 51 ++-
.../OpenMP/parallel_region_merging.ll | 35 +-
30 files changed, 1036 insertions(+), 421 deletions(-)
diff --git a/llvm/include/llvm/Transforms/IPO/Attributor.h b/llvm/include/llvm/Transforms/IPO/Attributor.h
index 30c51250af61c..257a0d3e7679b 100644
--- a/llvm/include/llvm/Transforms/IPO/Attributor.h
+++ b/llvm/include/llvm/Transforms/IPO/Attributor.h
@@ -1711,6 +1711,13 @@ struct Attributor {
/// Return the internal information cache.
InformationCache &getInfoCache() { return InfoCache; }
+ /// Return to be changed values
+
+ const SmallMapVector<Value *, PointerIntPair<Value *, 1, bool>, 32> &
+ getToBeChangedValues() {
+ return ToBeChangedValues;
+ }
+
/// Return true if this is a module pass, false otherwise.
bool isModulePass() const { return Configuration.IsModulePass; }
@@ -1858,12 +1865,18 @@ struct Attributor {
return changeUseAfterManifest(
CB->getArgOperandUse(IRP.getCallSiteArgNo()), NV);
}
+
Value &V = IRP.getAssociatedValue();
auto &Entry = ToBeChangedValues[&V];
Value *CurNV = get<0>(Entry);
if (CurNV && (CurNV->stripPointerCasts() == NV.stripPointerCasts() ||
isa<UndefValue>(CurNV)))
return false;
+
+ if (CurNV != NULL) {
+ dbgs() << "IRP: " << *IRP.getCtxI() << " NV: " << NV
+ << " CurNV: " << *CurNV << "\n";
+ }
assert((!CurNV || CurNV == &NV || isa<UndefValue>(NV)) &&
"Value replacement was registered twice with different values!");
Entry = {&NV, ChangeDroppable};
@@ -5143,9 +5156,7 @@ struct DenormalFPMathState : public AbstractState {
return Mode != Other.Mode || ModeF32 != Other.ModeF32;
}
- bool isValid() const {
- return Mode.isValid() && ModeF32.isValid();
- }
+ bool isValid() const { return Mode.isValid() && ModeF32.isValid(); }
static DenormalMode::DenormalModeKind
unionDenormalKind(DenormalMode::DenormalModeKind Callee,
@@ -5185,9 +5196,7 @@ struct DenormalFPMathState : public AbstractState {
// state.
DenormalState getAssumed() const { return Known; }
- bool isValidState() const override {
- return Known.isValid();
- }
+ bool isValidState() const override { return Known.isValid(); }
/// Return true if there are no dynamic components to the denormal mode worth
/// specializing.
@@ -5198,9 +5207,7 @@ struct DenormalFPMathState : public AbstractState {
Known.ModeF32.Output != DenormalMode::Dynamic;
}
- bool isAtFixpoint() const override {
- return IsAtFixedpoint;
- }
+ bool isAtFixpoint() const override { return IsAtFixedpoint; }
ChangeStatus indicateFixpoint() {
bool Changed = !IsAtFixedpoint;
@@ -6122,6 +6129,8 @@ struct AAPointerInfo : public AbstractAttribute {
virtual const_bin_iterator begin() const = 0;
virtual const_bin_iterator end() const = 0;
virtual int64_t numOffsetBins() const = 0;
+ virtual void dumpState(raw_ostream &O) const = 0;
+ virtual const Access &getBinAccess(unsigned Index) const = 0;
/// Call \p CB on all accesses that might interfere with \p Range and return
/// true if all such accesses were known and the callback returned true for
@@ -6293,6 +6302,9 @@ struct AAAllocationInfo : public StateWrapper<BooleanState, AbstractAttribute> {
virtual std::optional<TypeSize> getAllocatedSize() const = 0;
+ using NewOffsetsTy = DenseMap<AA::RangeTy, AA::RangeTy>;
+ virtual const NewOffsetsTy &getNewOffsets() const = 0;
+
/// See AbstractAttribute::getName()
const std::string getName() const override { return "AAAllocationInfo"; }
diff --git a/llvm/lib/Transforms/IPO/AttributorAttributes.cpp b/llvm/lib/Transforms/IPO/AttributorAttributes.cpp
index 1b3bf3c732ed0..efeb9c2c610ae 100644
--- a/llvm/lib/Transforms/IPO/AttributorAttributes.cpp
+++ b/llvm/lib/Transforms/IPO/AttributorAttributes.cpp
@@ -11,6 +11,8 @@
//
//===----------------------------------------------------------------------===//
+#include "llvm/ADT/DenseMap.h"
+#include "llvm/Support/Debug.h"
#include "llvm/Transforms/IPO/Attributor.h"
#include "llvm/ADT/APInt.h"
@@ -72,9 +74,13 @@
#include "llvm/Transforms/Utils/Local.h"
#include "llvm/Transforms/Utils/ValueMapper.h"
#include <cassert>
+#include <climits>
+#include <cstdint>
#include <numeric>
#include <optional>
+#include <set>
#include <string>
+#include <utility>
using namespace llvm;
@@ -419,7 +425,8 @@ struct AAReturnedFromReturnedValues : public BaseType {
/// See AbstractAttribute::updateImpl(...).
ChangeStatus updateImpl(Attributor &A) override {
StateType S(StateType::getBestState(this->getState()));
- clampReturnedValueStates<AAType, StateType, IRAttributeKind, RecurseForSelectAndPHI>(
+ clampReturnedValueStates<AAType, StateType, IRAttributeKind,
+ RecurseForSelectAndPHI>(
A, *this, S,
PropagateCallBaseContext ? this->getCallBaseContext() : nullptr);
// TODO: If we know we visited all returned values, thus no are assumed
@@ -1083,6 +1090,10 @@ struct AAPointerInfoImpl
return State::numOffsetBins();
}
+ virtual const Access &getBinAccess(unsigned Index) const override {
+ return getAccess(Index);
+ }
+
bool forallInterferingAccesses(
AA::RangeTy Range,
function_ref<bool(const AAPointerInfo::Access &, bool)> CB)
@@ -1429,7 +1440,7 @@ struct AAPointerInfoImpl
void trackPointerInfoStatistics(const IRPosition &IRP) const {}
/// Dump the state into \p O.
- void dumpState(raw_ostream &O) {
+ virtual void dumpState(raw_ostream &O) const override {
for (auto &It : OffsetBins) {
O << "[" << It.first.Offset << "-" << It.first.Offset + It.first.Size
<< "] : " << It.getSecond().size() << "\n";
@@ -6975,10 +6986,9 @@ ChangeStatus AAHeapToStackFunction::updateImpl(Attributor &A) {
if (AI.LibraryFunctionId != LibFunc___kmpc_alloc_shared) {
Instruction *CtxI = isa<InvokeInst>(AI.CB) ? AI.CB : AI.CB->getNextNode();
if (!Explorer || !Explorer->findInContextOf(UniqueFree, CtxI)) {
- LLVM_DEBUG(
- dbgs()
- << "[H2S] unique free call might not be executed with the allocation "
- << *UniqueFree << "\n");
+ LLVM_DEBUG(dbgs() << "[H2S] unique free call might not be executed "
+ "with the allocation "
+ << *UniqueFree << "\n");
return false;
}
}
@@ -10431,11 +10441,12 @@ struct AANoFPClassFloating : public AANoFPClassImpl {
struct AANoFPClassReturned final
: AAReturnedFromReturnedValues<AANoFPClass, AANoFPClassImpl,
- AANoFPClassImpl::StateType, false, Attribute::None, false> {
+ AANoFPClassImpl::StateType, false,
+ Attribute::None, false> {
AANoFPClassReturned(const IRPosition &IRP, Attributor &A)
: AAReturnedFromReturnedValues<AANoFPClass, AANoFPClassImpl,
- AANoFPClassImpl::StateType, false, Attribute::None, false>(
- IRP, A) {}
+ AANoFPClassImpl::StateType, false,
+ Attribute::None, false>(IRP, A) {}
/// See AbstractAttribute::trackStatistics()
void trackStatistics() const override {
@@ -12692,6 +12703,11 @@ struct AAAllocationInfoImpl : public AAAllocationInfo {
return AssumedAllocatedSize;
}
+ const NewOffsetsTy &getNewOffsets() const override {
+ assert(isValidState() && "the AA is invalid");
+ return NewComputedOffsets;
+ }
+
std::optional<TypeSize> findInitialAllocationSize(Instruction *I,
const DataLayout &DL) {
@@ -12741,37 +12757,47 @@ struct AAAllocationInfoImpl : public AAAllocationInfo {
if (*AllocationSize == 0)
return indicatePessimisticFixpoint();
- int64_t BinSize = PI->numOffsetBins();
+ int64_t NumBins = PI->numOffsetBins();
- // TODO: implement for multiple bins
- if (BinSize > 1)
- return indicatePessimisticFixpoint();
-
- if (BinSize == 0) {
+ if (NumBins == 0) {
auto NewAllocationSize = std::optional<TypeSize>(TypeSize(0, false));
if (!changeAllocationSize(NewAllocationSize))
return ChangeStatus::UNCHANGED;
return ChangeStatus::CHANGED;
}
- // TODO: refactor this to be part of multiple bin case
- const auto &It = PI->begin();
+ // For each access bin
+ // Compute its new start Offset and store the results in a new map
+ // (NewOffsetBins).
+ unsigned long PrevBinEndOffset = 0;
+ bool ChangedOffsets = false;
- // TODO: handle if Offset is not zero
- if (It->first.Offset != 0)
- return indicatePessimisticFixpoint();
+ for (AAPointerInfo::OffsetBinsTy::const_iterator It = PI->begin();
+ It != PI->end(); It++) {
+ const AA::RangeTy &OldRange = It->getFirst();
- uint64_t SizeOfBin = It->first.Offset + It->first.Size;
+ if (OldRange.offsetOrSizeAreUnknown())
+ continue;
- if (SizeOfBin >= *AllocationSize)
- return indicatePessimisticFixpoint();
+ unsigned long NewStartOffset = PrevBinEndOffset;
+ unsigned long NewEndOffset = NewStartOffset + OldRange.Size;
+ PrevBinEndOffset = NewEndOffset;
+
+ ChangedOffsets |= setNewOffsets(OldRange, OldRange.Offset, NewStartOffset,
+ OldRange.Size);
+ }
+ // Set the new size of the allocation, the new size of the Allocation should
+ // be the size of NewEndOffset * 8, in bits.
auto NewAllocationSize =
- std::optional<TypeSize>(TypeSize(SizeOfBin * 8, false));
+ std::optional<TypeSize>(TypeSize(PrevBinEndOffset * 8, false));
if (!changeAllocationSize(NewAllocationSize))
return ChangeStatus::UNCHANGED;
+ if (!ChangedOffsets)
+ return ChangeStatus::UNCHANGED;
+
return ChangeStatus::CHANGED;
}
@@ -12781,31 +12807,55 @@ struct AAAllocationInfoImpl : public AAAllocationInfo {
assert(isValidState() &&
"Manifest should only be called if the state is valid.");
- Instruction *I = getIRPosition().getCtxI();
+ bool Changed = false;
+ const IRPosition &IRP = getIRPosition();
+ Instruction *I = IRP.getCtxI();
+
+ //check if simplified values exist
+ SmallVector<AA::ValueAndContext> Values;
+ bool UsedAssumedInformation = false;
+ if (A.getAssumedSimplifiedValues(IRP, *this, Values, AA::AnyScope, UsedAssumedInformation)) {
+
+ bool HasSimplifiedValue = false;
+ for (auto &ValAndContext : Values){
+ //is any simplified values exists other than the original instruction, we should
+ // not modify this alloca.
+ if(ValAndContext.getValue() && ValAndContext.getValue() != I){
+ HasSimplifiedValue = true;
+ break;
+ }
+ }
+
+ if (HasSimplifiedValue)
+ return ChangeStatus::UNCHANGED;
+ }
- auto FixedAllocatedSizeInBits = getAllocatedSize()->getFixedValue();
+ unsigned long FixedAllocatedSizeInBits =
+ getAllocatedSize()->getFixedValue();
unsigned long NumBytesToAllocate = (FixedAllocatedSizeInBits + 7) / 8;
-
switch (I->getOpcode()) {
// TODO: add case for malloc like calls
case Instruction::Alloca: {
-
+
AllocaInst *AI = cast<AllocaInst>(I);
+ const DataLayout &DL = A.getDataLayout();
+ auto OriginalAllocationSize = AI->getAllocationSizeInBits(DL);
+ if (OriginalAllocationSize == FixedAllocatedSizeInBits){
+ return ChangeStatus::UNCHANGED;
+ }
+
Type *CharType = Type::getInt8Ty(I->getContext());
- auto *NumBytesToValue =
- ConstantInt::get(I->getContext(), APInt(32, NumBytesToAllocate));
+ Type *CharArrayType = ArrayType::get(CharType, NumBytesToAllocate);
- BasicBlock::iterator insertPt = AI->getIterator();
- insertPt = std::next(insertPt);
- AllocaInst *NewAllocaInst =
- new AllocaInst(CharType, AI->getAddressSpace(), NumBytesToValue,
- AI->getAlign(), AI->getName(), insertPt);
+ BasicBlock::iterator InsertPt = AI->getIterator();
+ InsertPt = std::next(InsertPt);
+ AllocaInst *NewAllocaInst = new AllocaInst(
+ CharArrayType, AI->getAddressSpace(), AI->getName(), InsertPt);
- if (A.changeAfterManifest(IRPosition::inst(*AI), *NewAllocaInst))
- return ChangeStatus::CHANGED;
+ Changed |= A.changeAfterManifest(IRPosition::inst(*AI), *NewAllocaInst);
break;
}
@@ -12813,7 +12863,143 @@ struct AAAllocationInfoImpl : public AAAllocationInfo {
break;
}
- return ChangeStatus::UNCHANGED;
+ const AAPointerInfo *PI =
+ A.getOrCreateAAFor<AAPointerInfo>(IRP, *this, DepClassTy::REQUIRED);
+
+ if (!PI)
+ return ChangeStatus::UNCHANGED;
+
+ if (!PI->getState().isValidState())
+ return ChangeStatus::UNCHANGED;
+
+ const auto &NewOffsetsMap = getNewOffsets();
+
+ // Store a map where each instruction maps to a set of bins accessed by that
+ // instruction.
+ DenseMap<Instruction *, DenseMap<AA::RangeTy, AA::RangeTy>>
+ AccessedInstructionsToBinsMap;
+ for (AAPointerInfo::OffsetBinsTy::const_iterator It = PI->begin();
+ It != PI->end(); It++) {
+
+ const auto &OldOffsetRange = It->getFirst();
+
+ if (OldOffsetRange.offsetOrSizeAreUnknown())
+ continue;
+
+ // If the OldOffsetRange is not in the map, offsets for that bin did not
+ // change We should just continue and skip changing the offsets in that
+ // case
+ if (!NewOffsetsMap.contains(OldOffsetRange))
+ continue;
+
+ const auto &NewOffsetRange = NewOffsetsMap.lookup(OldOffsetRange);
+
+ for (const auto AccIndex : It->getSecond()) {
+ const auto &AccessInstruction = PI->getBinAccess(AccIndex);
+ Instruction *LocalInst = AccessInstruction.getLocalInst();
+ DenseMap<AA::RangeTy, AA::RangeTy> &NewBinsForInstruction =
+ AccessedInstructionsToBinsMap.getOrInsertDefault(LocalInst);
+ NewBinsForInstruction.insert(
+ std::make_pair(OldOffsetRange, NewOffsetRange));
+ }
+ }
+
+ for (auto &It : AccessedInstructionsToBinsMap) {
+
+ Instruction *LocalInst = It.first;
+
+ // If there a potential values that replace the accessed instruction, we
+ // should use those instead.
+ SmallVector<AA::ValueAndContext> Vals;
+
+ if (A.getAssumedSimplifiedValues(IRPosition::inst(*LocalInst), *this, Vals, AA::AnyScope, UsedAssumedInformation)) {
+
+ bool HasSimplifiedValue = false;
+ for (auto &ValAndContext : Vals){
+ //don't modify load if any simplified value exists
+ if(ValAndContext.getValue() && ValAndContext.getValue() != LocalInst){
+ HasSimplifiedValue = true;
+ break;
+ }
+ }
+
+ if (HasSimplifiedValue)
+ continue;
+
+ }
+
+ // Get a hold of a map, mapping old to new bins
+ DenseMap<AA::RangeTy, AA::RangeTy> &OldToNewBins = It.second;
+
+ int64_t MinOffset = INT_MAX;
+ int64_t MinOffsetOld = INT_MAX;
+ // It should be asserted that the new bins and old bins form a continous
+ // range?
+ for (auto &It2 : OldToNewBins) {
+
+ auto &OldRange = It2.getFirst();
+ auto &NewRange = It2.getSecond();
+
+ if (NewRange.Offset < MinOffset) {
+ MinOffset = NewRange.Offset;
+ MinOffsetOld = OldRange.Offset;
+ }
+ }
+
+ // The number of bytes to shift the allocation by
+ int64_t ShiftValue = MinOffset - MinOffsetOld;
+
+ switch (LocalInst->getOpcode()) {
+ case Instruction::Load: {
+ LoadInst *OldLoadInst = cast<LoadInst>(LocalInst);
+ Value *PointerOperand = OldLoadInst->getPointerOperand();
+ Type *PointeeTy = OldLoadInst->getPointerOperandType();
+
+ IntegerType *Int64TyInteger =
+ IntegerType::get(LocalInst->getContext(), 64);
+
+ Value *IndexList[1] = {ConstantInt::get(Int64TyInteger, ShiftValue)};
+ Value *GepToNewAddress = GetElementPtrInst::Create(
+ PointeeTy, PointerOperand, IndexList, "NewGep", OldLoadInst);
+
+ LoadInst *NewLoadInst = new LoadInst(
+ OldLoadInst->getType(), GepToNewAddress, OldLoadInst->getName(),
+ false, OldLoadInst->getAlign(), OldLoadInst);
+
+ Changed |=
+ A.changeAfterManifest(IRPosition::inst(*OldLoadInst), *NewLoadInst);
+
+ A.deleteAfterManifest(*OldLoadInst);
+ break;
+ }
+ case Instruction::Store: {
+ StoreInst *OldStoreInst = cast<StoreInst>(LocalInst);
+ Value *PointerOperand = OldStoreInst->getPointerOperand();
+ Type *PointeeTy = OldStoreInst->getPointerOperandType();
+
+ IntegerType *Int64TyInteger =
+ IntegerType::get(LocalInst->getContext(), 64);
+
+ Value *IndexList[1] = {ConstantInt::get(Int64TyInteger, ShiftValue)};
+ Value *GepToNewAddress = GetElementPtrInst::Create(
+ PointeeTy, PointerOperand, IndexList, "NewGep", OldStoreInst);
+
+ StoreInst *NewStoreInst =
+ new StoreInst(OldStoreInst->getValueOperand(), GepToNewAddress,
+ false, OldStoreInst->getAlign(), OldStoreInst);
+
+ Changed |= A.changeAfterManifest(IRPosition::inst(*OldStoreInst),
+ *NewStoreInst);
+
+ A.deleteAfterManifest(*OldStoreInst);
+ break;
+ }
+ }
+ }
+
+ if (!Changed)
+ return ChangeStatus::UNCHANGED;
+ return ChangeStatus::CHANGED;
}
/// See AbstractAttribute::getAsStr().
@@ -12827,8 +13013,28 @@ struct AAAllocationInfoImpl : public AAAllocationInfo {
")";
}
+ void dumpNewOffsetBins(raw_ostream &O) {
+
+ O << "Printing Map from [OldOffsetsRange] : [NewOffsetsRange] if the "
+ "offsets changed."
+ << "\n";
+ const auto &NewOffsetsMap = getNewOffsets();
+ for (auto It = NewOffsetsMap.begin(); It != NewOffsetsMap.end(); It++) {
+
+ const auto &OldRange = It->getFirst();
+ const auto &NewRange = It->getSecond();
+
+ O << "[" << OldRange.Offset << "," << OldRange.Offset + OldRange.Size
+ << "] : ";
+ O << "[" << NewRange.Offset << "," << NewRange.Offset + NewRange.Size
+ << "]";
+ O << "\n";
+ }
+ }
+
private:
std::optional<TypeSize> AssumedAllocatedSize = HasNoAllocationSize;
+ NewOffsetsTy NewComputedOffsets;
// Maintain the computed allocation size of the object.
// Returns (bool) weather the size of the allocation was modified or not.
@@ -12840,6 +13046,21 @@ struct AAAllocationInfoImpl : public AAAllocationInfo {
}
return false;
}
+
+ // Maps an old byte range to its new Offset range in the new allocation.
+ // Returns (bool) weather the old byte range's offsets changed or not.
+ bool setNewOffsets(const AA::RangeTy &OldRange, int64_t OldOffset,
+ int64_t NewComputedOffset, int64_t Size) {
+
+ if (OldOffset == NewComputedOffset)
+ return false;
+
+ AA::RangeTy &NewRange = NewComputedOffsets.getOrInsertDefault(OldRange);
+ NewRange.Offset = NewComputedOffset;
+ NewRange.Size = Size;
+
+ return true;
+ }
};
struct AAAllocationInfoFloating : AAAllocationInfoImpl {
diff --git a/llvm/test/Other/ChangePrinters/DotCfg/print-changed-dot-cfg.ll b/llvm/test/Other/ChangePrinters/DotCfg/print-changed-dot-cfg.ll
index a3d5c60fe932d..21e243ea8b6ae 100644
--- a/llvm/test/Other/ChangePrinters/DotCfg/print-changed-dot-cfg.ll
+++ b/llvm/test/Other/ChangePrinters/DotCfg/print-changed-dot-cfg.ll
@@ -1,3 +1,4 @@
+; NOTE: Assertions have been autogenerated by utils/update_test_checks.py UTC_ARGS: --version 5
; Simple checks of -print-changed=dot-cfg
;
; Note that (mostly) only the banners are checked.
diff --git a/llvm/test/Other/ChangePrinters/DotCfg/print-changed-dot-cfg.mir b/llvm/test/Other/ChangePrinters/DotCfg/print-changed-dot-cfg.mir
index 40603630c6134..d77e6017c61b3 100644
--- a/llvm/test/Other/ChangePrinters/DotCfg/print-changed-dot-cfg.mir
+++ b/llvm/test/Other/ChangePrinters/DotCfg/print-changed-dot-cfg.mir
@@ -1,3 +1,4 @@
+# NOTE: Assertions have been autogenerated by utils/update_test_checks.py UTC_ARGS: --version 5
# REQUIRES: x86-registered-target
# Simple functionality check.
# RUN: rm -rf %t && mkdir -p %t
@@ -8,17 +9,17 @@
name: g
body: |
bb.0.entry:
- %0:gr32 = MOV32ri 5
- $eax = COPY %0
- RET 0, $eax
+ %0:gr32 = MOV32ri 5
+ $eax = COPY %0
+ RET 0, $eax
...
---
name: f
body: |
bb.0.entry:
- %0:gr32 = MOV32ri 7
- $eax = COPY %0
- RET 0, $eax
+ %0:gr32 = MOV32ri 7
+ $eax = COPY %0
+ RET 0, $eax
...
diff --git a/llvm/test/Transforms/Attributor/ArgumentPromotion/X86/min-legal-vector-width.ll b/llvm/test/Transforms/Attributor/ArgumentPromotion/X86/min-legal-vector-width.ll
index f0bcf68b6444b..821904c41e233 100644
--- a/llvm/test/Transforms/Attributor/ArgumentPromotion/X86/min-legal-vector-width.ll
+++ b/llvm/test/Transforms/Attributor/ArgumentPromotion/X86/min-legal-vector-width.ll
@@ -31,10 +31,10 @@ define void @avx512_legal512_prefer512_call_avx512_legal512_prefer512(ptr %arg)
; TUNIT-LABEL: define {{[^@]+}}@avx512_legal512_prefer512_call_avx512_legal512_prefer512
; TUNIT-SAME: (ptr nocapture nofree writeonly [[ARG:%.*]]) #[[ATTR0]] {
; TUNIT-NEXT: bb:
-; TUNIT-NEXT: [[TMP:%.*]] = alloca <8 x i64>, align 32
+; TUNIT-NEXT: [[TMP1:%.*]] = alloca [96 x i8], align 1
; TUNIT-NEXT: [[TMP2:%.*]] = alloca <8 x i64>, align 32
-; TUNIT-NEXT: call void @llvm.memset.p0.i64(ptr noalias nocapture nofree noundef nonnull writeonly align 32 dereferenceable(64) [[TMP]], i8 noundef 0, i64 noundef 32, i1 noundef false) #[[ATTR5:[0-9]+]]
-; TUNIT-NEXT: [[TMP0:%.*]] = load <8 x i64>, ptr [[TMP]], align 64
+; TUNIT-NEXT: call void @llvm.memset.p0.i64(ptr noalias nocapture nofree noundef nonnull writeonly align 32 dereferenceable(64) [[TMP1]], i8 noundef 0, i64 noundef 32, i1 noundef false) #[[ATTR5:[0-9]+]]
+; TUNIT-NEXT: [[TMP0:%.*]] = load <8 x i64>, ptr [[TMP1]], align 64
; TUNIT-NEXT: call fastcc void @callee_avx512_legal512_prefer512_call_avx512_legal512_prefer512(ptr noalias nocapture nofree noundef nonnull writeonly align 64 dereferenceable(64) [[TMP2]], <8 x i64> [[TMP0]]) #[[ATTR6:[0-9]+]]
; TUNIT-NEXT: [[TMP4:%.*]] = load <8 x i64>, ptr [[TMP2]], align 64
; TUNIT-NEXT: store <8 x i64> [[TMP4]], ptr [[ARG]], align 2
@@ -44,10 +44,10 @@ define void @avx512_legal512_prefer512_call_avx512_legal512_prefer512(ptr %arg)
; CGSCC-LABEL: define {{[^@]+}}@avx512_legal512_prefer512_call_avx512_legal512_prefer512
; CGSCC-SAME: (ptr nocapture nofree noundef nonnull writeonly align 2 dereferenceable(64) [[ARG:%.*]]) #[[ATTR0]] {
; CGSCC-NEXT: bb:
-; CGSCC-NEXT: [[TMP:%.*]] = alloca <8 x i64>, align 32
+; CGSCC-NEXT: [[TMP1:%.*]] = alloca [96 x i8], align 1
; CGSCC-NEXT: [[TMP2:%.*]] = alloca <8 x i64>, align 32
-; CGSCC-NEXT: call void @llvm.memset.p0.i64(ptr noalias nocapture nofree noundef nonnull writeonly align 64 dereferenceable(64) [[TMP]], i8 noundef 0, i64 noundef 32, i1 noundef false) #[[ATTR5:[0-9]+]]
-; CGSCC-NEXT: [[TMP0:%.*]] = load <8 x i64>, ptr [[TMP]], align 64
+; CGSCC-NEXT: call void @llvm.memset.p0.i64(ptr noalias nocapture nofree noundef nonnull writeonly align 64 dereferenceable(64) [[TMP1]], i8 noundef 0, i64 noundef 32, i1 noundef false) #[[ATTR5:[0-9]+]]
+; CGSCC-NEXT: [[TMP0:%.*]] = load <8 x i64>, ptr [[TMP1]], align 64
; CGSCC-NEXT: call fastcc void @callee_avx512_legal512_prefer512_call_avx512_legal512_prefer512(ptr noalias nocapture nofree noundef nonnull writeonly align 64 dereferenceable(64) [[TMP2]], <8 x i64> [[TMP0]]) #[[ATTR6:[0-9]+]]
; CGSCC-NEXT: [[TMP4:%.*]] = load <8 x i64>, ptr [[TMP2]], align 64
; CGSCC-NEXT: store <8 x i64> [[TMP4]], ptr [[ARG]], align 2
@@ -88,10 +88,10 @@ define void @avx512_legal512_prefer256_call_avx512_legal512_prefer256(ptr %arg)
; TUNIT-LABEL: define {{[^@]+}}@avx512_legal512_prefer256_call_avx512_legal512_prefer256
; TUNIT-SAME: (ptr nocapture nofree writeonly [[ARG:%.*]]) #[[ATTR1]] {
; TUNIT-NEXT: bb:
-; TUNIT-NEXT: [[TMP:%.*]] = alloca <8 x i64>, align 32
+; TUNIT-NEXT: [[TMP1:%.*]] = alloca [96 x i8], align 1
; TUNIT-NEXT: [[TMP2:%.*]] = alloca <8 x i64>, align 32
-; TUNIT-NEXT: call void @llvm.memset.p0.i64(ptr noalias nocapture nofree noundef nonnull writeonly align 32 dereferenceable(64) [[TMP]], i8 noundef 0, i64 noundef 32, i1 noundef false) #[[ATTR5]]
-; TUNIT-NEXT: [[TMP0:%.*]] = load <8 x i64>, ptr [[TMP]], align 64
+; TUNIT-NEXT: call void @llvm.memset.p0.i64(ptr noalias nocapture nofree noundef nonnull writeonly align 32 dereferenceable(64) [[TMP1]], i8 noundef 0, i64 noundef 32, i1 noundef false) #[[ATTR5]]
+; TUNIT-NEXT: [[TMP0:%.*]] = load <8 x i64>, ptr [[TMP1]], align 64
; TUNIT-NEXT: call fastcc void @callee_avx512_legal512_prefer256_call_avx512_legal512_prefer256(ptr noalias nocapture nofree noundef nonnull writeonly align 64 dereferenceable(64) [[TMP2]], <8 x i64> [[TMP0]]) #[[ATTR6]]
; TUNIT-NEXT: [[TMP4:%.*]] = load <8 x i64>, ptr [[TMP2]], align 64
; TUNIT-NEXT: store <8 x i64> [[TMP4]], ptr [[ARG]], align 2
@@ -101,10 +101,10 @@ define void @avx512_legal512_prefer256_call_avx512_legal512_prefer256(ptr %arg)
; CGSCC-LABEL: define {{[^@]+}}@avx512_legal512_prefer256_call_avx512_legal512_prefer256
; CGSCC-SAME: (ptr nocapture nofree noundef nonnull writeonly align 2 dereferenceable(64) [[ARG:%.*]]) #[[ATTR1]] {
; CGSCC-NEXT: bb:
-; CGSCC-NEXT: [[TMP:%.*]] = alloca <8 x i64>, align 32
+; CGSCC-NEXT: [[TMP1:%.*]] = alloca [96 x i8], align 1
; CGSCC-NEXT: [[TMP2:%.*]] = alloca <8 x i64>, align 32
-; CGSCC-NEXT: call void @llvm.memset.p0.i64(ptr noalias nocapture nofree noundef nonnull writeonly align 64 dereferenceable(64) [[TMP]], i8 noundef 0, i64 noundef 32, i1 noundef false) #[[ATTR5]]
-; CGSCC-NEXT: [[TMP0:%.*]] = load <8 x i64>, ptr [[TMP]], align 64
+; CGSCC-NEXT: call void @llvm.memset.p0.i64(ptr noalias nocapture nofree noundef nonnull writeonly align 64 dereferenceable(64) [[TMP1]], i8 noundef 0, i64 noundef 32, i1 noundef false) #[[ATTR5]]
+; CGSCC-NEXT: [[TMP0:%.*]] = load <8 x i64>, ptr [[TMP1]], align 64
; CGSCC-NEXT: call fastcc void @callee_avx512_legal512_prefer256_call_avx512_legal512_prefer256(ptr noalias nocapture nofree noundef nonnull writeonly align 64 dereferenceable(64) [[TMP2]], <8 x i64> [[TMP0]]) #[[ATTR6]]
; CGSCC-NEXT: [[TMP4:%.*]] = load <8 x i64>, ptr [[TMP2]], align 64
; CGSCC-NEXT: store <8 x i64> [[TMP4]], ptr [[ARG]], align 2
@@ -145,10 +145,10 @@ define void @avx512_legal512_prefer512_call_avx512_legal512_prefer256(ptr %arg)
; TUNIT-LABEL: define {{[^@]+}}@avx512_legal512_prefer512_call_avx512_legal512_prefer256
; TUNIT-SAME: (ptr nocapture nofree writeonly [[ARG:%.*]]) #[[ATTR0]] {
; TUNIT-NEXT: bb:
-; TUNIT-NEXT: [[TMP:%.*]] = alloca <8 x i64>, align 32
+; TUNIT-NEXT: [[TMP1:%.*]] = alloca [96 x i8], align 1
; TUNIT-NEXT: [[TMP2:%.*]] = alloca <8 x i64>, align 32
-; TUNIT-NEXT: call void @llvm.memset.p0.i64(ptr noalias nocapture nofree noundef nonnull writeonly align 32 dereferenceable(64) [[TMP]], i8 noundef 0, i64 noundef 32, i1 noundef false) #[[ATTR5]]
-; TUNIT-NEXT: [[TMP0:%.*]] = load <8 x i64>, ptr [[TMP]], align 64
+; TUNIT-NEXT: call void @llvm.memset.p0.i64(ptr noalias nocapture nofree noundef nonnull writeonly align 32 dereferenceable(64) [[TMP1]], i8 noundef 0, i64 noundef 32, i1 noundef false) #[[ATTR5]]
+; TUNIT-NEXT: [[TMP0:%.*]] = load <8 x i64>, ptr [[TMP1]], align 64
; TUNIT-NEXT: call fastcc void @callee_avx512_legal512_prefer512_call_avx512_legal512_prefer256(ptr noalias nocapture nofree noundef nonnull writeonly align 64 dereferenceable(64) [[TMP2]], <8 x i64> [[TMP0]]) #[[ATTR6]]
; TUNIT-NEXT: [[TMP4:%.*]] = load <8 x i64>, ptr [[TMP2]], align 64
; TUNIT-NEXT: store <8 x i64> [[TMP4]], ptr [[ARG]], align 2
@@ -158,10 +158,10 @@ define void @avx512_legal512_prefer512_call_avx512_legal512_prefer256(ptr %arg)
; CGSCC-LABEL: define {{[^@]+}}@avx512_legal512_prefer512_call_avx512_legal512_prefer256
; CGSCC-SAME: (ptr nocapture nofree noundef nonnull writeonly align 2 dereferenceable(64) [[ARG:%.*]]) #[[ATTR0]] {
; CGSCC-NEXT: bb:
-; CGSCC-NEXT: [[TMP:%.*]] = alloca <8 x i64>, align 32
+; CGSCC-NEXT: [[TMP1:%.*]] = alloca [96 x i8], align 1
; CGSCC-NEXT: [[TMP2:%.*]] = alloca <8 x i64>, align 32
-; CGSCC-NEXT: call void @llvm.memset.p0.i64(ptr noalias nocapture nofree noundef nonnull writeonly align 64 dereferenceable(64) [[TMP]], i8 noundef 0, i64 noundef 32, i1 noundef false) #[[ATTR5]]
-; CGSCC-NEXT: [[TMP0:%.*]] = load <8 x i64>, ptr [[TMP]], align 64
+; CGSCC-NEXT: call void @llvm.memset.p0.i64(ptr noalias nocapture nofree noundef nonnull writeonly align 64 dereferenceable(64) [[TMP1]], i8 noundef 0, i64 noundef 32, i1 noundef false) #[[ATTR5]]
+; CGSCC-NEXT: [[TMP0:%.*]] = load <8 x i64>, ptr [[TMP1]], align 64
; CGSCC-NEXT: call fastcc void @callee_avx512_legal512_prefer512_call_avx512_legal512_prefer256(ptr noalias nocapture nofree noundef nonnull writeonly align 64 dereferenceable(64) [[TMP2]], <8 x i64> [[TMP0]]) #[[ATTR6]]
; CGSCC-NEXT: [[TMP4:%.*]] = load <8 x i64>, ptr [[TMP2]], align 64
; CGSCC-NEXT: store <8 x i64> [[TMP4]], ptr [[ARG]], align 2
@@ -202,10 +202,10 @@ define void @avx512_legal512_prefer256_call_avx512_legal512_prefer512(ptr %arg)
; TUNIT-LABEL: define {{[^@]+}}@avx512_legal512_prefer256_call_avx512_legal512_prefer512
; TUNIT-SAME: (ptr nocapture nofree writeonly [[ARG:%.*]]) #[[ATTR1]] {
; TUNIT-NEXT: bb:
-; TUNIT-NEXT: [[TMP:%.*]] = alloca <8 x i64>, align 32
+; TUNIT-NEXT: [[TMP1:%.*]] = alloca [96 x i8], align 1
; TUNIT-NEXT: [[TMP2:%.*]] = alloca <8 x i64>, align 32
-; TUNIT-NEXT: call void @llvm.memset.p0.i64(ptr noalias nocapture nofree noundef nonnull writeonly align 32 dereferenceable(64) [[TMP]], i8 noundef 0, i64 noundef 32, i1 noundef false) #[[ATTR5]]
-; TUNIT-NEXT: [[TMP0:%.*]] = load <8 x i64>, ptr [[TMP]], align 64
+; TUNIT-NEXT: call void @llvm.memset.p0.i64(ptr noalias nocapture nofree noundef nonnull writeonly align 32 dereferenceable(64) [[TMP1]], i8 noundef 0, i64 noundef 32, i1 noundef false) #[[ATTR5]]
+; TUNIT-NEXT: [[TMP0:%.*]] = load <8 x i64>, ptr [[TMP1]], align 64
; TUNIT-NEXT: call fastcc void @callee_avx512_legal512_prefer256_call_avx512_legal512_prefer512(ptr noalias nocapture nofree noundef nonnull writeonly align 64 dereferenceable(64) [[TMP2]], <8 x i64> [[TMP0]]) #[[ATTR6]]
; TUNIT-NEXT: [[TMP4:%.*]] = load <8 x i64>, ptr [[TMP2]], align 64
; TUNIT-NEXT: store <8 x i64> [[TMP4]], ptr [[ARG]], align 2
@@ -215,10 +215,10 @@ define void @avx512_legal512_prefer256_call_avx512_legal512_prefer512(ptr %arg)
; CGSCC-LABEL: define {{[^@]+}}@avx512_legal512_prefer256_call_avx512_legal512_prefer512
; CGSCC-SAME: (ptr nocapture nofree noundef nonnull writeonly align 2 dereferenceable(64) [[ARG:%.*]]) #[[ATTR1]] {
; CGSCC-NEXT: bb:
-; CGSCC-NEXT: [[TMP:%.*]] = alloca <8 x i64>, align 32
+; CGSCC-NEXT: [[TMP1:%.*]] = alloca [96 x i8], align 1
; CGSCC-NEXT: [[TMP2:%.*]] = alloca <8 x i64>, align 32
-; CGSCC-NEXT: call void @llvm.memset.p0.i64(ptr noalias nocapture nofree noundef nonnull writeonly align 64 dereferenceable(64) [[TMP]], i8 noundef 0, i64 noundef 32, i1 noundef false) #[[ATTR5]]
-; CGSCC-NEXT: [[TMP0:%.*]] = load <8 x i64>, ptr [[TMP]], align 64
+; CGSCC-NEXT: call void @llvm.memset.p0.i64(ptr noalias nocapture nofree noundef nonnull writeonly align 64 dereferenceable(64) [[TMP1]], i8 noundef 0, i64 noundef 32, i1 noundef false) #[[ATTR5]]
+; CGSCC-NEXT: [[TMP0:%.*]] = load <8 x i64>, ptr [[TMP1]], align 64
; CGSCC-NEXT: call fastcc void @callee_avx512_legal512_prefer256_call_avx512_legal512_prefer512(ptr noalias nocapture nofree noundef nonnull writeonly align 64 dereferenceable(64) [[TMP2]], <8 x i64> [[TMP0]]) #[[ATTR6]]
; CGSCC-NEXT: [[TMP4:%.*]] = load <8 x i64>, ptr [[TMP2]], align 64
; CGSCC-NEXT: store <8 x i64> [[TMP4]], ptr [[ARG]], align 2
@@ -257,10 +257,10 @@ define void @avx512_legal256_prefer256_call_avx512_legal512_prefer256(ptr %arg)
; TUNIT-LABEL: define {{[^@]+}}@avx512_legal256_prefer256_call_avx512_legal512_prefer256
; TUNIT-SAME: (ptr nocapture nofree writeonly [[ARG:%.*]]) #[[ATTR2:[0-9]+]] {
; TUNIT-NEXT: bb:
-; TUNIT-NEXT: [[TMP:%.*]] = alloca <8 x i64>, align 32
+; TUNIT-NEXT: [[TMP1:%.*]] = alloca [96 x i8], align 1
; TUNIT-NEXT: [[TMP2:%.*]] = alloca <8 x i64>, align 32
-; TUNIT-NEXT: call void @llvm.memset.p0.i64(ptr noalias nocapture nofree noundef nonnull writeonly align 32 dereferenceable(64) [[TMP]], i8 noundef 0, i64 noundef 32, i1 noundef false) #[[ATTR5]]
-; TUNIT-NEXT: call fastcc void @callee_avx512_legal256_prefer256_call_avx512_legal512_prefer256(ptr noalias nocapture nofree noundef nonnull writeonly align 64 dereferenceable(64) [[TMP2]], ptr noalias nocapture nofree noundef nonnull readonly align 64 dereferenceable(64) [[TMP]]) #[[ATTR6]]
+; TUNIT-NEXT: call void @llvm.memset.p0.i64(ptr noalias nocapture nofree noundef nonnull writeonly align 32 dereferenceable(64) [[TMP1]], i8 noundef 0, i64 noundef 32, i1 noundef false) #[[ATTR5]]
+; TUNIT-NEXT: call fastcc void @callee_avx512_legal256_prefer256_call_avx512_legal512_prefer256(ptr noalias nocapture nofree noundef nonnull writeonly align 64 dereferenceable(64) [[TMP2]], ptr noalias nocapture nofree noundef nonnull readonly align 64 dereferenceable(64) [[TMP1]]) #[[ATTR6]]
; TUNIT-NEXT: [[TMP4:%.*]] = load <8 x i64>, ptr [[TMP2]], align 64
; TUNIT-NEXT: store <8 x i64> [[TMP4]], ptr [[ARG]], align 2
; TUNIT-NEXT: ret void
@@ -310,10 +310,10 @@ define void @avx512_legal512_prefer256_call_avx512_legal256_prefer256(ptr %arg)
; TUNIT-LABEL: define {{[^@]+}}@avx512_legal512_prefer256_call_avx512_legal256_prefer256
; TUNIT-SAME: (ptr nocapture nofree writeonly [[ARG:%.*]]) #[[ATTR1]] {
; TUNIT-NEXT: bb:
-; TUNIT-NEXT: [[TMP:%.*]] = alloca <8 x i64>, align 32
+; TUNIT-NEXT: [[TMP1:%.*]] = alloca [96 x i8], align 1
; TUNIT-NEXT: [[TMP2:%.*]] = alloca <8 x i64>, align 32
-; TUNIT-NEXT: call void @llvm.memset.p0.i64(ptr noalias nocapture nofree noundef nonnull writeonly align 32 dereferenceable(64) [[TMP]], i8 noundef 0, i64 noundef 32, i1 noundef false) #[[ATTR5]]
-; TUNIT-NEXT: call fastcc void @callee_avx512_legal512_prefer256_call_avx512_legal256_prefer256(ptr noalias nocapture nofree noundef nonnull writeonly align 64 dereferenceable(64) [[TMP2]], ptr noalias nocapture nofree noundef nonnull readonly align 64 dereferenceable(64) [[TMP]]) #[[ATTR6]]
+; TUNIT-NEXT: call void @llvm.memset.p0.i64(ptr noalias nocapture nofree noundef nonnull writeonly align 32 dereferenceable(64) [[TMP1]], i8 noundef 0, i64 noundef 32, i1 noundef false) #[[ATTR5]]
+; TUNIT-NEXT: call fastcc void @callee_avx512_legal512_prefer256_call_avx512_legal256_prefer256(ptr noalias nocapture nofree noundef nonnull writeonly align 64 dereferenceable(64) [[TMP2]], ptr noalias nocapture nofree noundef nonnull readonly align 64 dereferenceable(64) [[TMP1]]) #[[ATTR6]]
; TUNIT-NEXT: [[TMP4:%.*]] = load <8 x i64>, ptr [[TMP2]], align 64
; TUNIT-NEXT: store <8 x i64> [[TMP4]], ptr [[ARG]], align 2
; TUNIT-NEXT: ret void
@@ -365,10 +365,10 @@ define void @avx2_legal256_prefer256_call_avx2_legal512_prefer256(ptr %arg) #4 {
; TUNIT-LABEL: define {{[^@]+}}@avx2_legal256_prefer256_call_avx2_legal512_prefer256
; TUNIT-SAME: (ptr nocapture nofree writeonly [[ARG:%.*]]) #[[ATTR3]] {
; TUNIT-NEXT: bb:
-; TUNIT-NEXT: [[TMP:%.*]] = alloca <8 x i64>, align 32
+; TUNIT-NEXT: [[TMP1:%.*]] = alloca [96 x i8], align 1
; TUNIT-NEXT: [[TMP2:%.*]] = alloca <8 x i64>, align 32
-; TUNIT-NEXT: call void @llvm.memset.p0.i64(ptr noalias nocapture nofree noundef nonnull writeonly align 32 dereferenceable(64) [[TMP]], i8 noundef 0, i64 noundef 32, i1 noundef false) #[[ATTR5]]
-; TUNIT-NEXT: [[TMP0:%.*]] = load <8 x i64>, ptr [[TMP]], align 64
+; TUNIT-NEXT: call void @llvm.memset.p0.i64(ptr noalias nocapture nofree noundef nonnull writeonly align 32 dereferenceable(64) [[TMP1]], i8 noundef 0, i64 noundef 32, i1 noundef false) #[[ATTR5]]
+; TUNIT-NEXT: [[TMP0:%.*]] = load <8 x i64>, ptr [[TMP1]], align 64
; TUNIT-NEXT: call fastcc void @callee_avx2_legal256_prefer256_call_avx2_legal512_prefer256(ptr noalias nocapture nofree noundef nonnull writeonly align 64 dereferenceable(64) [[TMP2]], <8 x i64> [[TMP0]]) #[[ATTR6]]
; TUNIT-NEXT: [[TMP4:%.*]] = load <8 x i64>, ptr [[TMP2]], align 64
; TUNIT-NEXT: store <8 x i64> [[TMP4]], ptr [[ARG]], align 2
@@ -378,10 +378,10 @@ define void @avx2_legal256_prefer256_call_avx2_legal512_prefer256(ptr %arg) #4 {
; CGSCC-LABEL: define {{[^@]+}}@avx2_legal256_prefer256_call_avx2_legal512_prefer256
; CGSCC-SAME: (ptr nocapture nofree noundef nonnull writeonly align 2 dereferenceable(64) [[ARG:%.*]]) #[[ATTR3]] {
; CGSCC-NEXT: bb:
-; CGSCC-NEXT: [[TMP:%.*]] = alloca <8 x i64>, align 32
+; CGSCC-NEXT: [[TMP1:%.*]] = alloca [96 x i8], align 1
; CGSCC-NEXT: [[TMP2:%.*]] = alloca <8 x i64>, align 32
-; CGSCC-NEXT: call void @llvm.memset.p0.i64(ptr noalias nocapture nofree noundef nonnull writeonly align 64 dereferenceable(64) [[TMP]], i8 noundef 0, i64 noundef 32, i1 noundef false) #[[ATTR5]]
-; CGSCC-NEXT: [[TMP0:%.*]] = load <8 x i64>, ptr [[TMP]], align 64
+; CGSCC-NEXT: call void @llvm.memset.p0.i64(ptr noalias nocapture nofree noundef nonnull writeonly align 64 dereferenceable(64) [[TMP1]], i8 noundef 0, i64 noundef 32, i1 noundef false) #[[ATTR5]]
+; CGSCC-NEXT: [[TMP0:%.*]] = load <8 x i64>, ptr [[TMP1]], align 64
; CGSCC-NEXT: call fastcc void @callee_avx2_legal256_prefer256_call_avx2_legal512_prefer256(ptr noalias nocapture nofree noundef nonnull writeonly align 64 dereferenceable(64) [[TMP2]], <8 x i64> [[TMP0]]) #[[ATTR6]]
; CGSCC-NEXT: [[TMP4:%.*]] = load <8 x i64>, ptr [[TMP2]], align 64
; CGSCC-NEXT: store <8 x i64> [[TMP4]], ptr [[ARG]], align 2
@@ -422,10 +422,10 @@ define void @avx2_legal512_prefer256_call_avx2_legal256_prefer256(ptr %arg) #3 {
; TUNIT-LABEL: define {{[^@]+}}@avx2_legal512_prefer256_call_avx2_legal256_prefer256
; TUNIT-SAME: (ptr nocapture nofree writeonly [[ARG:%.*]]) #[[ATTR3]] {
; TUNIT-NEXT: bb:
-; TUNIT-NEXT: [[TMP:%.*]] = alloca <8 x i64>, align 32
+; TUNIT-NEXT: [[TMP1:%.*]] = alloca [96 x i8], align 1
; TUNIT-NEXT: [[TMP2:%.*]] = alloca <8 x i64>, align 32
-; TUNIT-NEXT: call void @llvm.memset.p0.i64(ptr noalias nocapture nofree noundef nonnull writeonly align 32 dereferenceable(64) [[TMP]], i8 noundef 0, i64 noundef 32, i1 noundef false) #[[ATTR5]]
-; TUNIT-NEXT: [[TMP0:%.*]] = load <8 x i64>, ptr [[TMP]], align 64
+; TUNIT-NEXT: call void @llvm.memset.p0.i64(ptr noalias nocapture nofree noundef nonnull writeonly align 32 dereferenceable(64) [[TMP1]], i8 noundef 0, i64 noundef 32, i1 noundef false) #[[ATTR5]]
+; TUNIT-NEXT: [[TMP0:%.*]] = load <8 x i64>, ptr [[TMP1]], align 64
; TUNIT-NEXT: call fastcc void @callee_avx2_legal512_prefer256_call_avx2_legal256_prefer256(ptr noalias nocapture nofree noundef nonnull writeonly align 64 dereferenceable(64) [[TMP2]], <8 x i64> [[TMP0]]) #[[ATTR6]]
; TUNIT-NEXT: [[TMP4:%.*]] = load <8 x i64>, ptr [[TMP2]], align 64
; TUNIT-NEXT: store <8 x i64> [[TMP4]], ptr [[ARG]], align 2
@@ -435,10 +435,10 @@ define void @avx2_legal512_prefer256_call_avx2_legal256_prefer256(ptr %arg) #3 {
; CGSCC-LABEL: define {{[^@]+}}@avx2_legal512_prefer256_call_avx2_legal256_prefer256
; CGSCC-SAME: (ptr nocapture nofree noundef nonnull writeonly align 2 dereferenceable(64) [[ARG:%.*]]) #[[ATTR3]] {
; CGSCC-NEXT: bb:
-; CGSCC-NEXT: [[TMP:%.*]] = alloca <8 x i64>, align 32
+; CGSCC-NEXT: [[TMP1:%.*]] = alloca [96 x i8], align 1
; CGSCC-NEXT: [[TMP2:%.*]] = alloca <8 x i64>, align 32
-; CGSCC-NEXT: call void @llvm.memset.p0.i64(ptr noalias nocapture nofree noundef nonnull writeonly align 64 dereferenceable(64) [[TMP]], i8 noundef 0, i64 noundef 32, i1 noundef false) #[[ATTR5]]
-; CGSCC-NEXT: [[TMP0:%.*]] = load <8 x i64>, ptr [[TMP]], align 64
+; CGSCC-NEXT: call void @llvm.memset.p0.i64(ptr noalias nocapture nofree noundef nonnull writeonly align 64 dereferenceable(64) [[TMP1]], i8 noundef 0, i64 noundef 32, i1 noundef false) #[[ATTR5]]
+; CGSCC-NEXT: [[TMP0:%.*]] = load <8 x i64>, ptr [[TMP1]], align 64
; CGSCC-NEXT: call fastcc void @callee_avx2_legal512_prefer256_call_avx2_legal256_prefer256(ptr noalias nocapture nofree noundef nonnull writeonly align 64 dereferenceable(64) [[TMP2]], <8 x i64> [[TMP0]]) #[[ATTR6]]
; CGSCC-NEXT: [[TMP4:%.*]] = load <8 x i64>, ptr [[TMP2]], align 64
; CGSCC-NEXT: store <8 x i64> [[TMP4]], ptr [[ARG]], align 2
diff --git a/llvm/test/Transforms/Attributor/ArgumentPromotion/array.ll b/llvm/test/Transforms/Attributor/ArgumentPromotion/array.ll
index a52bbfbe1a346..b0e5eb6e805a2 100644
--- a/llvm/test/Transforms/Attributor/ArgumentPromotion/array.ll
+++ b/llvm/test/Transforms/Attributor/ArgumentPromotion/array.ll
@@ -9,12 +9,12 @@ declare void @use(ptr nocapture readonly %arg)
define void @caller() {
; TUNIT-LABEL: define {{[^@]+}}@caller() {
; TUNIT-NEXT: entry:
-; TUNIT-NEXT: [[LEFT:%.*]] = alloca [3 x i32], align 4
-; TUNIT-NEXT: [[TMP0:%.*]] = load i32, ptr [[LEFT]], align 4
-; TUNIT-NEXT: [[LEFT_B4:%.*]] = getelementptr i8, ptr [[LEFT]], i64 4
-; TUNIT-NEXT: [[TMP1:%.*]] = load i32, ptr [[LEFT_B4]], align 4
-; TUNIT-NEXT: [[LEFT_B8:%.*]] = getelementptr i8, ptr [[LEFT]], i64 8
-; TUNIT-NEXT: [[TMP2:%.*]] = load i32, ptr [[LEFT_B8]], align 4
+; TUNIT-NEXT: [[LEFT1:%.*]] = alloca [0 x i8], align 1
+; TUNIT-NEXT: [[TMP0:%.*]] = load i32, ptr [[LEFT1]], align 4
+; TUNIT-NEXT: [[LEFT1_B4:%.*]] = getelementptr i8, ptr [[LEFT1]], i64 4
+; TUNIT-NEXT: [[TMP1:%.*]] = load i32, ptr [[LEFT1_B4]], align 4
+; TUNIT-NEXT: [[LEFT1_B8:%.*]] = getelementptr i8, ptr [[LEFT1]], i64 8
+; TUNIT-NEXT: [[TMP2:%.*]] = load i32, ptr [[LEFT1_B8]], align 4
; TUNIT-NEXT: call void @callee(i32 [[TMP0]], i32 [[TMP1]], i32 [[TMP2]])
; TUNIT-NEXT: ret void
;
diff --git a/llvm/test/Transforms/Attributor/ArgumentPromotion/byval.ll b/llvm/test/Transforms/Attributor/ArgumentPromotion/byval.ll
index 621c6cf94313e..516b80b1e237b 100644
--- a/llvm/test/Transforms/Attributor/ArgumentPromotion/byval.ll
+++ b/llvm/test/Transforms/Attributor/ArgumentPromotion/byval.ll
@@ -59,12 +59,12 @@ define i32 @main() nounwind {
; TUNIT-NEXT: store i32 1, ptr [[S]], align 32
; TUNIT-NEXT: [[VAL4:%.*]] = getelementptr [[STRUCT_SS]], ptr [[S]], i32 0, i32 1
; TUNIT-NEXT: [[TMP0:%.*]] = load i32, ptr [[S]], align 8
-; TUNIT-NEXT: [[S_B41:%.*]] = getelementptr i8, ptr [[S]], i64 4
-; TUNIT-NEXT: [[TMP1:%.*]] = load i64, ptr [[S_B41]], align 8
+; TUNIT-NEXT: [[S_B4:%.*]] = getelementptr i8, ptr [[S]], i64 4
+; TUNIT-NEXT: [[TMP1:%.*]] = load i64, ptr [[S_B4]], align 8
; TUNIT-NEXT: [[C0:%.*]] = call i32 @f(i32 [[TMP0]], i64 [[TMP1]]) #[[ATTR1:[0-9]+]]
; TUNIT-NEXT: [[TMP2:%.*]] = load i32, ptr [[S]], align 32
-; TUNIT-NEXT: [[S_B4:%.*]] = getelementptr i8, ptr [[S]], i64 4
-; TUNIT-NEXT: [[TMP3:%.*]] = load i64, ptr [[S_B4]], align 32
+; TUNIT-NEXT: [[S_B41:%.*]] = getelementptr i8, ptr [[S]], i64 4
+; TUNIT-NEXT: [[TMP3:%.*]] = load i64, ptr [[S_B41]], align 32
; TUNIT-NEXT: [[C1:%.*]] = call i32 @g(i32 [[TMP2]], i64 [[TMP3]]) #[[ATTR1]]
; TUNIT-NEXT: [[A:%.*]] = add i32 [[C0]], [[C1]]
; TUNIT-NEXT: ret i32 [[A]]
diff --git a/llvm/test/Transforms/Attributor/ArgumentPromotion/crash.ll b/llvm/test/Transforms/Attributor/ArgumentPromotion/crash.ll
index 595cb37c6c93e..ccb29d2889706 100644
--- a/llvm/test/Transforms/Attributor/ArgumentPromotion/crash.ll
+++ b/llvm/test/Transforms/Attributor/ArgumentPromotion/crash.ll
@@ -107,9 +107,9 @@ define i32 @test_inf_promote_caller(i32 %arg) {
; CGSCC-SAME: (i32 [[ARG:%.*]]) #[[ATTR3:[0-9]+]] {
; CGSCC-NEXT: bb:
; CGSCC-NEXT: [[TMP:%.*]] = alloca [[S:%.*]], align 8
-; CGSCC-NEXT: [[TMP3:%.*]] = alloca i8, i32 0, align 8
+; CGSCC-NEXT: [[TMP3:%.*]] = alloca [0 x i8], align 1
; CGSCC-NEXT: [[TMP1:%.*]] = alloca [[S]], align 8
-; CGSCC-NEXT: [[TMP14:%.*]] = alloca i8, i32 0, align 8
+; CGSCC-NEXT: [[TMP14:%.*]] = alloca [0 x i8], align 1
; CGSCC-NEXT: ret i32 0
;
bb:
diff --git a/llvm/test/Transforms/Attributor/ArgumentPromotion/live_called_from_dead.ll b/llvm/test/Transforms/Attributor/ArgumentPromotion/live_called_from_dead.ll
index 2df81d6cb1832..f4b73e2b80409 100644
--- a/llvm/test/Transforms/Attributor/ArgumentPromotion/live_called_from_dead.ll
+++ b/llvm/test/Transforms/Attributor/ArgumentPromotion/live_called_from_dead.ll
@@ -37,8 +37,8 @@ define internal i32 @caller(ptr %B) {
; CGSCC-LABEL: define {{[^@]+}}@caller
; CGSCC-SAME: () #[[ATTR0]] {
; CGSCC-NEXT: [[A:%.*]] = alloca i32, align 4
-; CGSCC-NEXT: [[A2:%.*]] = alloca i8, i32 0, align 4
-; CGSCC-NEXT: [[A1:%.*]] = alloca i8, i32 0, align 4
+; CGSCC-NEXT: [[A2:%.*]] = alloca [0 x i8], align 1
+; CGSCC-NEXT: [[A1:%.*]] = alloca [0 x i8], align 1
; CGSCC-NEXT: ret i32 0
;
%A = alloca i32
diff --git a/llvm/test/Transforms/Attributor/ArgumentPromotion/live_called_from_dead_2.ll b/llvm/test/Transforms/Attributor/ArgumentPromotion/live_called_from_dead_2.ll
index 7c28de24beea2..9e0b5e3450680 100644
--- a/llvm/test/Transforms/Attributor/ArgumentPromotion/live_called_from_dead_2.ll
+++ b/llvm/test/Transforms/Attributor/ArgumentPromotion/live_called_from_dead_2.ll
@@ -54,8 +54,8 @@ define internal i32 @caller(ptr %B) {
; CGSCC-LABEL: define {{[^@]+}}@caller
; CGSCC-SAME: (ptr noalias nocapture nofree noundef nonnull writeonly align 4 dereferenceable(4) [[B:%.*]]) #[[ATTR0]] {
; CGSCC-NEXT: [[A:%.*]] = alloca i32, align 4
-; CGSCC-NEXT: [[A2:%.*]] = alloca i8, i32 0, align 4
-; CGSCC-NEXT: [[A1:%.*]] = alloca i8, i32 0, align 4
+; CGSCC-NEXT: [[A2:%.*]] = alloca [0 x i8], align 1
+; CGSCC-NEXT: [[A1:%.*]] = alloca [0 x i8], align 1
; CGSCC-NEXT: [[C:%.*]] = call i32 @test(ptr noalias nocapture nofree noundef nonnull writeonly align 4 dereferenceable(4) [[B]]) #[[ATTR2:[0-9]+]]
; CGSCC-NEXT: ret i32 0
;
diff --git a/llvm/test/Transforms/Attributor/ArgumentPromotion/nonzero-address-spaces.ll b/llvm/test/Transforms/Attributor/ArgumentPromotion/nonzero-address-spaces.ll
index b588a399e5bd9..ef74a88d30d1d 100644
--- a/llvm/test/Transforms/Attributor/ArgumentPromotion/nonzero-address-spaces.ll
+++ b/llvm/test/Transforms/Attributor/ArgumentPromotion/nonzero-address-spaces.ll
@@ -30,7 +30,7 @@ define internal i32 @foo(ptr) {
; CHECK-SAME: () addrspace(1) #[[ATTR0:[0-9]+]] {
; CHECK-NEXT: entry:
; CHECK-NEXT: [[RETVAL:%.*]] = alloca i32, align 4
-; CHECK-NEXT: [[RETVAL1:%.*]] = alloca i8, i32 0, align 4
+; CHECK-NEXT: [[RETVAL1:%.*]] = alloca [0 x i8], align 1
; CHECK-NEXT: call addrspace(0) void asm sideeffect "ldr r0, [r0] \0Abx lr \0A", ""()
; CHECK-NEXT: unreachable
;
diff --git a/llvm/test/Transforms/Attributor/IPConstantProp/pthreads.ll b/llvm/test/Transforms/Attributor/IPConstantProp/pthreads.ll
index 490894d129023..af2d1ef1eabba 100644
--- a/llvm/test/Transforms/Attributor/IPConstantProp/pthreads.ll
+++ b/llvm/test/Transforms/Attributor/IPConstantProp/pthreads.ll
@@ -34,8 +34,8 @@ target datalayout = "e-m:e-i64:64-f80:128-n8:16:32:64-S128"
define dso_local i32 @main() {
; TUNIT-LABEL: define {{[^@]+}}@main() {
; TUNIT-NEXT: entry:
-; TUNIT-NEXT: [[ALLOC11:%.*]] = alloca i8, i32 0, align 8
-; TUNIT-NEXT: [[ALLOC22:%.*]] = alloca i8, i32 0, align 8
+; TUNIT-NEXT: [[ALLOC11:%.*]] = alloca [0 x i8], align 1
+; TUNIT-NEXT: [[ALLOC22:%.*]] = alloca [0 x i8], align 1
; TUNIT-NEXT: [[THREAD:%.*]] = alloca i64, align 8
; TUNIT-NEXT: [[CALL:%.*]] = call i32 @pthread_create(ptr noundef nonnull align 8 dereferenceable(8) [[THREAD]], ptr noundef align 4294967296 null, ptr noundef nonnull @foo, ptr nofree readnone align 4294967296 undef)
; TUNIT-NEXT: [[CALL1:%.*]] = call i32 @pthread_create(ptr noundef nonnull align 8 dereferenceable(8) [[THREAD]], ptr noundef align 4294967296 null, ptr noundef nonnull @bar, ptr noalias nocapture nofree nonnull readnone align 8 dereferenceable(8) undef)
diff --git a/llvm/test/Transforms/Attributor/allocator.ll b/llvm/test/Transforms/Attributor/allocator.ll
index f2d9ecd1d8fa4..1c6cd32a539c5 100644
--- a/llvm/test/Transforms/Attributor/allocator.ll
+++ b/llvm/test/Transforms/Attributor/allocator.ll
@@ -13,8 +13,8 @@ define dso_local void @positive_alloca_1(i32 noundef %val) #0 {
; CHECK-LABEL: define dso_local void @positive_alloca_1
; CHECK-SAME: (i32 noundef [[VAL:%.*]]) {
; CHECK-NEXT: entry:
-; CHECK-NEXT: [[VAL_ADDR1:%.*]] = alloca i8, i32 4, align 4
-; CHECK-NEXT: [[F2:%.*]] = alloca i8, i32 4, align 4
+; CHECK-NEXT: [[VAL_ADDR1:%.*]] = alloca [4 x i8], align 1
+; CHECK-NEXT: [[F2:%.*]] = alloca [4 x i8], align 1
; CHECK-NEXT: store i32 [[VAL]], ptr [[VAL_ADDR1]], align 4
; CHECK-NEXT: store i32 10, ptr [[F2]], align 4
; CHECK-NEXT: [[TMP0:%.*]] = load i32, ptr [[F2]], align 4
@@ -164,37 +164,54 @@ entry:
;TODO: The allocation can be reduced here.
;However, the offsets (load/store etc.) Need to be changed.
; Function Attrs: noinline nounwind uwtable
-define dso_local { i64, ptr } @positive_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 } @positive_test_not_a_single_start_offset
-; CHECK-SAME: (i32 noundef [[VAL:%.*]]) #[[ATTR0:[0-9]+]] {
+define dso_local void @positive_test_not_a_single_start_offset(i32 noundef %val) #0 {
+; CHECK-LABEL: define dso_local void @positive_test_not_a_single_start_offset
+; CHECK-SAME: (i32 noundef [[VAL:%.*]]) {
; CHECK-NEXT: entry:
-; CHECK-NEXT: [[RETVAL:%.*]] = alloca [[STRUCT_FOO:%.*]], align 8
; CHECK-NEXT: [[VAL_ADDR:%.*]] = alloca i32, align 4
+; CHECK-NEXT: [[F1:%.*]] = alloca [5 x i8], align 1
; 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]]
+; CHECK-NEXT: [[MUL:%.*]] = mul nsw i32 2, [[VAL]]
+; CHECK-NEXT: store i32 [[MUL]], ptr [[F1]], align 4
+; CHECK-NEXT: [[TMP0:%.*]] = load i32, ptr [[F1]], align 4
+; CHECK-NEXT: [[CALL:%.*]] = call i32 (ptr, ...) @printf(ptr noundef nonnull dereferenceable(17) @.str, i32 noundef [[TMP0]])
+; CHECK-NEXT: [[C:%.*]] = getelementptr inbounds [[STRUCT_FOO:%.*]], ptr [[F1]], i32 0, i32 2
+; CHECK-NEXT: [[CONV1:%.*]] = trunc i32 [[TMP0]] to i8
+; CHECK-NEXT: [[NEWGEP:%.*]] = getelementptr ptr, ptr [[C]], i64 -4
+; CHECK-NEXT: store i8 [[CONV1]], ptr [[NEWGEP]], align 4
+; CHECK-NEXT: [[C2:%.*]] = getelementptr inbounds [[STRUCT_FOO]], ptr [[F1]], i32 0, i32 2
+; CHECK-NEXT: [[NEWGEP2:%.*]] = getelementptr ptr, ptr [[C2]], i64 -4
+; CHECK-NEXT: [[TMP1:%.*]] = load i8, ptr [[NEWGEP2]], align 4
+; CHECK-NEXT: [[CONV:%.*]] = sext i8 [[TMP1]] to i32
+; CHECK-NEXT: [[CALL3:%.*]] = call i32 (ptr, ...) @printf(ptr noundef nonnull dereferenceable(17) @.str, i32 noundef [[CONV]])
+; CHECK-NEXT: ret void
;
entry:
- %retval = alloca %struct.Foo, align 8
%val.addr = alloca i32, align 4
+ %f = alloca %struct.Foo, 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
+ %0 = load i32, ptr %val.addr, align 4
+ %mul = mul nsw i32 2, %0
+ %a = getelementptr inbounds %struct.Foo, ptr %f, i32 0, i32 0
+ store i32 %mul, ptr %a, align 4
+ %a1 = getelementptr inbounds %struct.Foo, ptr %f, i32 0, i32 0
+ %1 = load i32, ptr %a1, align 4
+ %call = call i32 (ptr, ...) @printf(ptr noundef @.str, i32 noundef %1)
+ %c = getelementptr inbounds %struct.Foo, ptr %f, i32 0, i32 2
+ %conv1 = trunc i32 %1 to i8
+ store i8 %conv1, ptr %c, align 4
+ %c2 = getelementptr inbounds %struct.Foo, ptr %f, i32 0, i32 2
+ %2 = load i8, ptr %c2, align 4
+ %conv = sext i8 %2 to i32
+ %call3 = call i32 (ptr, ...) @printf(ptr noundef @.str, i32 noundef %conv)
+ ret void
}
; Function Attrs: noinline nounwind uwtable
define dso_local void @positive_test_reduce_array_allocation_1() {
; CHECK-LABEL: define dso_local void @positive_test_reduce_array_allocation_1() {
; CHECK-NEXT: entry:
-; CHECK-NEXT: [[ARRAY1:%.*]] = alloca i8, i32 4, align 8
+; CHECK-NEXT: [[ARRAY1:%.*]] = alloca [4 x i8], align 1
; CHECK-NEXT: store i32 0, ptr [[ARRAY1]], align 8
; CHECK-NEXT: [[TMP0:%.*]] = load i32, ptr [[ARRAY1]], align 8
; CHECK-NEXT: [[TMP1:%.*]] = add i32 [[TMP0]], 2
@@ -275,37 +292,37 @@ entry:
define dso_local void @positive_test_reduce_array_allocation_2() #0 {
; CHECK-LABEL: define dso_local void @positive_test_reduce_array_allocation_2() {
; CHECK-NEXT: entry:
-; CHECK-NEXT: [[ARRAY:%.*]] = alloca ptr, align 8
-; CHECK-NEXT: [[I:%.*]] = alloca i32, align 4
+; CHECK-NEXT: [[ARRAY1:%.*]] = alloca ptr, align 8
+; CHECK-NEXT: [[I2:%.*]] = alloca i32, align 4
; CHECK-NEXT: [[CALL:%.*]] = call noalias ptr @malloc(i64 noundef 40000)
-; CHECK-NEXT: store ptr [[CALL]], ptr [[ARRAY]], align 8
-; CHECK-NEXT: store i32 0, ptr [[I]], align 4
+; CHECK-NEXT: store ptr [[CALL]], ptr [[ARRAY1]], align 8
+; CHECK-NEXT: store i32 0, ptr [[I2]], align 4
; CHECK-NEXT: br label [[FOR_COND:%.*]]
; CHECK: for.cond:
-; CHECK-NEXT: [[TMP0:%.*]] = load i32, ptr [[I]], align 4
+; CHECK-NEXT: [[TMP0:%.*]] = load i32, ptr [[I2]], align 4
; CHECK-NEXT: [[CMP:%.*]] = icmp slt i32 [[TMP0]], 10000
; CHECK-NEXT: br i1 [[CMP]], label [[FOR_BODY:%.*]], label [[FOR_END:%.*]]
; CHECK: for.body:
-; CHECK-NEXT: [[TMP1:%.*]] = load i32, ptr [[I]], align 4
-; CHECK-NEXT: [[TMP2:%.*]] = load i32, ptr [[I]], align 4
+; CHECK-NEXT: [[TMP1:%.*]] = load i32, ptr [[I2]], align 4
+; CHECK-NEXT: [[TMP2:%.*]] = load i32, ptr [[I2]], align 4
; CHECK-NEXT: [[IDXPROM:%.*]] = sext i32 [[TMP2]] to i64
; CHECK-NEXT: [[ARRAYIDX:%.*]] = getelementptr inbounds i32, ptr [[CALL]], i64 [[IDXPROM]]
; CHECK-NEXT: store i32 [[TMP1]], ptr [[ARRAYIDX]], align 4
; CHECK-NEXT: br label [[FOR_INC:%.*]]
; CHECK: for.inc:
-; CHECK-NEXT: [[TMP3:%.*]] = load i32, ptr [[I]], align 4
+; CHECK-NEXT: [[TMP3:%.*]] = load i32, ptr [[I2]], align 4
; CHECK-NEXT: [[ADD:%.*]] = add nsw i32 [[TMP3]], 2
-; CHECK-NEXT: store i32 [[ADD]], ptr [[I]], align 4
+; CHECK-NEXT: store i32 [[ADD]], ptr [[I2]], align 4
; CHECK-NEXT: br label [[FOR_COND]]
; CHECK: for.end:
-; CHECK-NEXT: store i32 0, ptr [[I]], align 4
+; CHECK-NEXT: store i32 0, ptr [[I2]], align 4
; CHECK-NEXT: br label [[FOR_COND1:%.*]]
; CHECK: for.cond1:
-; CHECK-NEXT: [[TMP4:%.*]] = load i32, ptr [[I]], align 4
+; CHECK-NEXT: [[TMP4:%.*]] = load i32, ptr [[I2]], align 4
; CHECK-NEXT: [[CMP2:%.*]] = icmp slt i32 [[TMP4]], 10000
; CHECK-NEXT: br i1 [[CMP2]], label [[FOR_BODY3:%.*]], label [[FOR_END9:%.*]]
; CHECK: for.body3:
-; CHECK-NEXT: [[TMP5:%.*]] = load i32, ptr [[I]], align 4
+; CHECK-NEXT: [[TMP5:%.*]] = load i32, ptr [[I2]], align 4
; CHECK-NEXT: [[IDXPROM4:%.*]] = sext i32 [[TMP5]] to i64
; CHECK-NEXT: [[ARRAYIDX5:%.*]] = getelementptr inbounds i32, ptr [[CALL]], i64 [[IDXPROM4]]
; CHECK-NEXT: [[TMP6:%.*]] = load i32, ptr [[ARRAYIDX5]], align 4
@@ -313,28 +330,28 @@ define dso_local void @positive_test_reduce_array_allocation_2() #0 {
; CHECK-NEXT: store i32 [[ADD6]], ptr [[ARRAYIDX5]], align 4
; CHECK-NEXT: br label [[FOR_INC7:%.*]]
; CHECK: for.inc7:
-; CHECK-NEXT: [[TMP7:%.*]] = load i32, ptr [[I]], align 4
+; CHECK-NEXT: [[TMP7:%.*]] = load i32, ptr [[I2]], align 4
; CHECK-NEXT: [[ADD8:%.*]] = add nsw i32 [[TMP7]], 2
-; CHECK-NEXT: store i32 [[ADD8]], ptr [[I]], align 4
+; CHECK-NEXT: store i32 [[ADD8]], ptr [[I2]], align 4
; CHECK-NEXT: br label [[FOR_COND1]]
; CHECK: for.end9:
-; CHECK-NEXT: store i32 0, ptr [[I]], align 4
+; CHECK-NEXT: store i32 0, ptr [[I2]], align 4
; CHECK-NEXT: br label [[FOR_COND10:%.*]]
; CHECK: for.cond10:
-; CHECK-NEXT: [[TMP8:%.*]] = load i32, ptr [[I]], align 4
+; CHECK-NEXT: [[TMP8:%.*]] = load i32, ptr [[I2]], align 4
; CHECK-NEXT: [[CMP11:%.*]] = icmp slt i32 [[TMP8]], 10000
; CHECK-NEXT: br i1 [[CMP11]], label [[FOR_BODY12:%.*]], label [[FOR_END18:%.*]]
; CHECK: for.body12:
-; CHECK-NEXT: [[TMP9:%.*]] = load i32, ptr [[I]], align 4
+; CHECK-NEXT: [[TMP9:%.*]] = load i32, ptr [[I2]], align 4
; CHECK-NEXT: [[IDXPROM13:%.*]] = sext i32 [[TMP9]] to i64
; CHECK-NEXT: [[ARRAYIDX14:%.*]] = getelementptr inbounds i32, ptr [[CALL]], i64 [[IDXPROM13]]
; CHECK-NEXT: [[TMP10:%.*]] = load i32, ptr [[ARRAYIDX14]], align 4
; CHECK-NEXT: [[CALL15:%.*]] = call i32 (ptr, ...) @printf(ptr noundef nonnull dereferenceable(17) @.str, i32 noundef [[TMP10]])
; CHECK-NEXT: br label [[FOR_INC16:%.*]]
; CHECK: for.inc16:
-; CHECK-NEXT: [[TMP11:%.*]] = load i32, ptr [[I]], align 4
+; CHECK-NEXT: [[TMP11:%.*]] = load i32, ptr [[I2]], align 4
; CHECK-NEXT: [[ADD17:%.*]] = add nsw i32 [[TMP11]], 2
-; CHECK-NEXT: store i32 [[ADD17]], ptr [[I]], align 4
+; CHECK-NEXT: store i32 [[ADD17]], ptr [[I2]], align 4
; CHECK-NEXT: br label [[FOR_COND10]]
; CHECK: for.end18:
; CHECK-NEXT: ret void
@@ -426,7 +443,7 @@ define dso_local void @pthread_test(){
; TUNIT-NEXT: [[ARG1:%.*]] = alloca i8, align 8
; TUNIT-NEXT: [[THREAD:%.*]] = alloca i64, align 8
; TUNIT-NEXT: [[CALL1:%.*]] = call i32 @pthread_create(ptr noundef nonnull align 8 dereferenceable(8) [[THREAD]], ptr noundef align 4294967296 null, ptr noundef nonnull @pthread_allocation_should_remain_same, ptr noundef nonnull align 8 dereferenceable(1) [[ARG1]])
-; TUNIT-NEXT: [[F1:%.*]] = alloca i8, i32 4, align 4
+; TUNIT-NEXT: [[F1:%.*]] = alloca [4 x i8], align 1
; TUNIT-NEXT: [[CALL2:%.*]] = call i32 @pthread_create(ptr noundef nonnull align 8 dereferenceable(8) [[THREAD]], ptr noundef align 4294967296 null, ptr noundef nonnull @pthread_allocation_should_be_reduced, ptr noalias nocapture nofree nonnull readnone align 4 dereferenceable(12) undef)
; TUNIT-NEXT: [[F2:%.*]] = alloca [[STRUCT_FOO:%.*]], align 4
; TUNIT-NEXT: [[CALL3:%.*]] = call i32 @pthread_create(ptr noundef nonnull align 8 dereferenceable(8) [[THREAD]], ptr noundef align 4294967296 null, ptr noundef nonnull @pthread_check_captured_pointer, ptr noundef nonnull align 4 dereferenceable(12) [[F2]])
@@ -499,6 +516,58 @@ entry:
ret void
}
+define dso_local void @alloca_array_multi_offset(){
+; CHECK: Function Attrs: nofree norecurse nosync nounwind memory(none)
+; CHECK-LABEL: define dso_local void @alloca_array_multi_offset
+; CHECK-SAME: () #[[ATTR0:[0-9]+]] {
+; CHECK-NEXT: entry:
+; CHECK-NEXT: [[I:%.*]] = alloca i32, align 4
+; CHECK-NEXT: store i32 0, ptr [[I]], align 4
+; CHECK-NEXT: br label [[FOR_COND:%.*]]
+; CHECK: for.cond:
+; CHECK-NEXT: [[TMP0:%.*]] = load i32, ptr [[I]], align 4
+; CHECK-NEXT: [[CMP:%.*]] = icmp slt i32 [[TMP0]], 10
+; CHECK-NEXT: br i1 [[CMP]], label [[FOR_BODY:%.*]], label [[FOR_END:%.*]]
+; CHECK: for.body:
+; CHECK-NEXT: br label [[FOR_INC:%.*]]
+; CHECK: for.inc:
+; CHECK-NEXT: [[TMP1:%.*]] = load i32, ptr [[I]], align 4
+; CHECK-NEXT: [[ADD:%.*]] = add nsw i32 [[TMP1]], 2
+; CHECK-NEXT: store i32 [[ADD]], ptr [[I]], align 4
+; CHECK-NEXT: br label [[FOR_COND]]
+; CHECK: for.end:
+; CHECK-NEXT: ret void
+;
+entry:
+ %arr = alloca i8, i32 10, align 4
+ %i = alloca i32, align 4
+ store i32 0, ptr %i, align 4
+ br label %for.cond
+
+for.cond:
+ %0 = load i32, ptr %i, align 4
+ %cmp = icmp slt i32 %0, 10
+ br i1 %cmp, label %for.body, label %for.end
+
+for.body:
+ %1 = load i32, ptr %i, align 4
+ %2 = load ptr, ptr %arr, align 8
+ %3 = load i32, ptr %i, align 4
+ %arrayidx = getelementptr inbounds i32, ptr %2, i32 %3
+ store i32 %1, ptr %arrayidx, align 4
+ br label %for.inc
+
+for.inc:
+ %4 = load i32, ptr %i, align 4
+ %add = add nsw i32 %4, 2
+ store i32 %add, ptr %i, align 4
+ br label %for.cond
+
+for.end:
+ ret void
+
+}
+
declare external void @external_call(ptr)
@@ -511,9 +580,9 @@ declare i32 @printf(ptr noundef, ...) #1
; Function Attrs: nounwind allocsize(0)
declare noalias ptr @malloc(i64 noundef) #1
;.
-; TUNIT: attributes #[[ATTR0]] = { mustprogress nofree norecurse nosync nounwind willreturn memory(none) }
+; TUNIT: attributes #[[ATTR0]] = { nofree norecurse nosync nounwind memory(none) }
;.
-; CGSCC: attributes #[[ATTR0]] = { mustprogress nofree norecurse nosync nounwind willreturn memory(none) }
+; CGSCC: attributes #[[ATTR0]] = { nofree norecurse nosync nounwind memory(none) }
;.
; TUNIT: [[META0:![0-9]+]] = !{[[META1:![0-9]+]]}
; TUNIT: [[META1]] = !{i64 2, i64 3, i1 false}
diff --git a/llvm/test/Transforms/Attributor/call-simplify-pointer-info.ll b/llvm/test/Transforms/Attributor/call-simplify-pointer-info.ll
index 5bb795911ce40..f2d660f12fbaa 100644
--- a/llvm/test/Transforms/Attributor/call-simplify-pointer-info.ll
+++ b/llvm/test/Transforms/Attributor/call-simplify-pointer-info.ll
@@ -36,8 +36,10 @@ define i8 @call_simplifiable_1() {
; TUNIT-LABEL: define {{[^@]+}}@call_simplifiable_1
; TUNIT-SAME: () #[[ATTR0:[0-9]+]] {
; TUNIT-NEXT: entry:
-; TUNIT-NEXT: [[BYTES:%.*]] = alloca [1024 x i8], align 16
-; TUNIT-NEXT: [[I0:%.*]] = getelementptr inbounds [1024 x i8], ptr [[BYTES]], i64 0, i64 2
+; TUNIT-NEXT: [[BYTES1:%.*]] = alloca [1 x i8], align 1
+; TUNIT-NEXT: [[I0:%.*]] = getelementptr inbounds [1024 x i8], ptr [[BYTES1]], i64 0, i64 2
+; TUNIT-NEXT: [[NEWGEP:%.*]] = getelementptr ptr, ptr [[I0]], i64 -2
+; TUNIT-NEXT: store i8 2, ptr [[NEWGEP]], align 2
; TUNIT-NEXT: ret i8 2
;
; CGSCC: Function Attrs: mustprogress nofree nosync nounwind willreturn memory(none)
@@ -93,9 +95,13 @@ define i8 @call_simplifiable_2() {
; TUNIT-LABEL: define {{[^@]+}}@call_simplifiable_2
; TUNIT-SAME: () #[[ATTR0]] {
; TUNIT-NEXT: entry:
-; TUNIT-NEXT: [[BYTES:%.*]] = alloca [1024 x i8], align 16
-; TUNIT-NEXT: [[I0:%.*]] = getelementptr inbounds [1024 x i8], ptr [[BYTES]], i64 0, i64 2
-; TUNIT-NEXT: [[I1:%.*]] = getelementptr inbounds [1024 x i8], ptr [[BYTES]], i64 0, i64 3
+; TUNIT-NEXT: [[BYTES1:%.*]] = alloca [2 x i8], align 1
+; TUNIT-NEXT: [[I0:%.*]] = getelementptr inbounds [1024 x i8], ptr [[BYTES1]], i64 0, i64 2
+; TUNIT-NEXT: [[NEWGEP:%.*]] = getelementptr ptr, ptr [[I0]], i64 -2
+; TUNIT-NEXT: store i8 2, ptr [[NEWGEP]], align 2
+; TUNIT-NEXT: [[I1:%.*]] = getelementptr inbounds [1024 x i8], ptr [[BYTES1]], i64 0, i64 3
+; TUNIT-NEXT: [[NEWGEP2:%.*]] = getelementptr ptr, ptr [[I1]], i64 -2
+; TUNIT-NEXT: store i8 3, ptr [[NEWGEP2]], align 1
; TUNIT-NEXT: ret i8 4
;
; CGSCC: Function Attrs: mustprogress nofree nosync nounwind willreturn memory(none)
@@ -125,8 +131,10 @@ define i8 @call_simplifiable_3() {
; TUNIT-LABEL: define {{[^@]+}}@call_simplifiable_3
; TUNIT-SAME: () #[[ATTR0]] {
; TUNIT-NEXT: entry:
-; TUNIT-NEXT: [[BYTES:%.*]] = alloca [1024 x i8], align 16
-; TUNIT-NEXT: [[I2:%.*]] = getelementptr inbounds [1024 x i8], ptr [[BYTES]], i64 0, i64 2
+; TUNIT-NEXT: [[BYTES1:%.*]] = alloca [1 x i8], align 1
+; TUNIT-NEXT: [[I2:%.*]] = getelementptr inbounds [1024 x i8], ptr [[BYTES1]], i64 0, i64 2
+; TUNIT-NEXT: [[NEWGEP:%.*]] = getelementptr ptr, ptr [[I2]], i64 -2
+; TUNIT-NEXT: store i8 2, ptr [[NEWGEP]], align 2
; TUNIT-NEXT: ret i8 2
;
; CGSCC: Function Attrs: mustprogress nofree nosync nounwind willreturn memory(none)
@@ -198,12 +206,16 @@ define i8 @call_partially_simplifiable_1() {
; TUNIT-LABEL: define {{[^@]+}}@call_partially_simplifiable_1
; TUNIT-SAME: () #[[ATTR0]] {
; TUNIT-NEXT: entry:
-; TUNIT-NEXT: [[BYTES:%.*]] = alloca [1024 x i8], align 16
-; TUNIT-NEXT: [[I2:%.*]] = getelementptr inbounds [1024 x i8], ptr [[BYTES]], i64 0, i64 2
-; TUNIT-NEXT: store i8 2, ptr [[I2]], align 2
-; TUNIT-NEXT: [[I3:%.*]] = getelementptr inbounds [1024 x i8], ptr [[BYTES]], i64 0, i64 3
-; TUNIT-NEXT: store i8 3, ptr [[I3]], align 1
-; TUNIT-NEXT: [[I4:%.*]] = getelementptr inbounds [1024 x i8], ptr [[BYTES]], i64 0, i64 4
+; TUNIT-NEXT: [[BYTES1:%.*]] = alloca [3 x i8], align 1
+; TUNIT-NEXT: [[I2:%.*]] = getelementptr inbounds [1024 x i8], ptr [[BYTES1]], i64 0, i64 2
+; TUNIT-NEXT: [[NEWGEP:%.*]] = getelementptr ptr, ptr [[I2]], i64 -2
+; TUNIT-NEXT: store i8 2, ptr [[NEWGEP]], align 2
+; TUNIT-NEXT: [[I3:%.*]] = getelementptr inbounds [1024 x i8], ptr [[BYTES1]], i64 0, i64 3
+; TUNIT-NEXT: [[NEWGEP3:%.*]] = getelementptr ptr, ptr [[I3]], i64 -1
+; TUNIT-NEXT: store i8 3, ptr [[NEWGEP3]], align 1
+; TUNIT-NEXT: [[I4:%.*]] = getelementptr inbounds [1024 x i8], ptr [[BYTES1]], i64 0, i64 4
+; TUNIT-NEXT: [[NEWGEP2:%.*]] = getelementptr ptr, ptr [[I4]], i64 -3
+; TUNIT-NEXT: store i8 4, ptr [[NEWGEP2]], align 4
; TUNIT-NEXT: [[R:%.*]] = call i8 @sum_two_different_loads(ptr nocapture nofree noundef nonnull readonly align 2 dereferenceable(1022) [[I2]], ptr nocapture nofree noundef nonnull readonly dereferenceable(1021) [[I3]]) #[[ATTR3]]
; TUNIT-NEXT: ret i8 [[R]]
;
@@ -239,13 +251,17 @@ define i8 @call_partially_simplifiable_2(i1 %cond) {
; TUNIT-LABEL: define {{[^@]+}}@call_partially_simplifiable_2
; TUNIT-SAME: (i1 [[COND:%.*]]) #[[ATTR2:[0-9]+]] {
; TUNIT-NEXT: entry:
-; TUNIT-NEXT: [[BYTES:%.*]] = alloca [1024 x i8], align 16
-; TUNIT-NEXT: [[I51:%.*]] = getelementptr inbounds [1024 x i8], ptr [[BYTES]], i64 0, i64 51
-; TUNIT-NEXT: [[I52:%.*]] = getelementptr inbounds [1024 x i8], ptr [[BYTES]], i64 0, i64 52
-; TUNIT-NEXT: store i8 2, ptr [[I52]], align 4
-; TUNIT-NEXT: [[I53:%.*]] = getelementptr inbounds [1024 x i8], ptr [[BYTES]], i64 0, i64 53
-; TUNIT-NEXT: store i8 3, ptr [[I53]], align 1
-; TUNIT-NEXT: [[I54:%.*]] = getelementptr inbounds [1024 x i8], ptr [[BYTES]], i64 0, i64 54
+; TUNIT-NEXT: [[BYTES1:%.*]] = alloca [4 x i8], align 1
+; TUNIT-NEXT: [[I51:%.*]] = getelementptr inbounds [1024 x i8], ptr [[BYTES1]], i64 0, i64 51
+; TUNIT-NEXT: [[I52:%.*]] = getelementptr inbounds [1024 x i8], ptr [[BYTES1]], i64 0, i64 52
+; TUNIT-NEXT: [[NEWGEP:%.*]] = getelementptr ptr, ptr [[I52]], i64 -52
+; TUNIT-NEXT: store i8 2, ptr [[NEWGEP]], align 4
+; TUNIT-NEXT: [[I53:%.*]] = getelementptr inbounds [1024 x i8], ptr [[BYTES1]], i64 0, i64 53
+; TUNIT-NEXT: [[NEWGEP3:%.*]] = getelementptr ptr, ptr [[I53]], i64 -50
+; TUNIT-NEXT: store i8 3, ptr [[NEWGEP3]], align 1
+; TUNIT-NEXT: [[I54:%.*]] = getelementptr inbounds [1024 x i8], ptr [[BYTES1]], i64 0, i64 54
+; TUNIT-NEXT: [[NEWGEP2:%.*]] = getelementptr ptr, ptr [[I54]], i64 -53
+; TUNIT-NEXT: store i8 4, ptr [[NEWGEP2]], align 2
; TUNIT-NEXT: [[SEL:%.*]] = select i1 [[COND]], ptr [[I51]], ptr [[I52]]
; TUNIT-NEXT: [[R:%.*]] = call i8 @sum_two_different_loads(ptr nocapture nofree nonnull readonly dereferenceable(972) [[SEL]], ptr nocapture nofree noundef nonnull readonly dereferenceable(971) [[I53]]) #[[ATTR3]]
; TUNIT-NEXT: ret i8 [[R]]
diff --git a/llvm/test/Transforms/Attributor/callbacks.ll b/llvm/test/Transforms/Attributor/callbacks.ll
index dd5cbbc9e271e..af5c8a3a6c5d9 100644
--- a/llvm/test/Transforms/Attributor/callbacks.ll
+++ b/llvm/test/Transforms/Attributor/callbacks.ll
@@ -92,10 +92,10 @@ define void @t1_caller(ptr noalias %a) {
; TUNIT-NEXT: entry:
; TUNIT-NEXT: [[B:%.*]] = alloca i32, align 32
; TUNIT-NEXT: [[C:%.*]] = alloca ptr, align 64
-; TUNIT-NEXT: [[PTR:%.*]] = alloca i32, align 128
+; TUNIT-NEXT: [[PTR1:%.*]] = alloca [0 x i8], align 1
; TUNIT-NEXT: store i32 42, ptr [[B]], align 32
; TUNIT-NEXT: store ptr [[B]], ptr [[C]], align 64
-; TUNIT-NEXT: call void (ptr, ptr, ptr, ...) @t1_callback_broker(ptr noundef align 4294967296 null, ptr noalias nocapture noundef nonnull align 128 dereferenceable(4) [[PTR]], ptr nocapture noundef nonnull @t1_callback_callee, ptr nocapture align 256 [[A]], i64 undef, ptr noalias nocapture nofree noundef nonnull readonly align 64 dereferenceable(8) [[C]])
+; TUNIT-NEXT: call void (ptr, ptr, ptr, ...) @t1_callback_broker(ptr noundef align 4294967296 null, ptr noalias nocapture noundef nonnull align 128 dereferenceable(4) [[PTR1]], ptr nocapture noundef nonnull @t1_callback_callee, ptr nocapture align 256 [[A]], i64 undef, ptr noalias nocapture nofree noundef nonnull readonly align 64 dereferenceable(8) [[C]])
; TUNIT-NEXT: ret void
;
; CGSCC-LABEL: define {{[^@]+}}@t1_caller
@@ -103,10 +103,10 @@ define void @t1_caller(ptr noalias %a) {
; CGSCC-NEXT: entry:
; CGSCC-NEXT: [[B:%.*]] = alloca i32, align 32
; CGSCC-NEXT: [[C:%.*]] = alloca ptr, align 64
-; CGSCC-NEXT: [[PTR:%.*]] = alloca i32, align 128
+; CGSCC-NEXT: [[PTR1:%.*]] = alloca [0 x i8], align 1
; CGSCC-NEXT: store i32 42, ptr [[B]], align 32
; CGSCC-NEXT: store ptr [[B]], ptr [[C]], align 64
-; CGSCC-NEXT: call void (ptr, ptr, ptr, ...) @t1_callback_broker(ptr noundef align 4294967296 null, ptr noalias nocapture noundef nonnull align 128 dereferenceable(4) [[PTR]], ptr nocapture noundef nonnull @t1_callback_callee, ptr nocapture align 256 [[A]], i64 noundef 99, ptr noalias nocapture nofree noundef nonnull readonly align 64 dereferenceable(8) [[C]])
+; CGSCC-NEXT: call void (ptr, ptr, ptr, ...) @t1_callback_broker(ptr noundef align 4294967296 null, ptr noalias nocapture noundef nonnull align 128 dereferenceable(4) [[PTR1]], ptr nocapture noundef nonnull @t1_callback_callee, ptr nocapture align 256 [[A]], i64 noundef 99, ptr noalias nocapture nofree noundef nonnull readonly align 64 dereferenceable(8) [[C]])
; CGSCC-NEXT: ret void
;
entry:
@@ -165,10 +165,10 @@ define void @t2_caller(ptr noalias %a) {
; TUNIT-NEXT: entry:
; TUNIT-NEXT: [[B:%.*]] = alloca i32, align 32
; TUNIT-NEXT: [[C:%.*]] = alloca ptr, align 64
-; TUNIT-NEXT: [[PTR:%.*]] = alloca i32, align 128
+; TUNIT-NEXT: [[PTR1:%.*]] = alloca [0 x i8], align 1
; TUNIT-NEXT: store i32 42, ptr [[B]], align 32
; TUNIT-NEXT: store ptr [[B]], ptr [[C]], align 64
-; TUNIT-NEXT: call void (ptr, ptr, ptr, ...) @t2_callback_broker(ptr noundef align 4294967296 null, ptr noalias nocapture noundef nonnull align 128 dereferenceable(4) [[PTR]], ptr nocapture noundef nonnull @t2_callback_callee, ptr nocapture align 256 [[A]], i64 undef, ptr noalias nocapture nofree noundef nonnull readonly align 64 dereferenceable(8) [[C]])
+; TUNIT-NEXT: call void (ptr, ptr, ptr, ...) @t2_callback_broker(ptr noundef align 4294967296 null, ptr noalias nocapture noundef nonnull align 128 dereferenceable(4) [[PTR1]], ptr nocapture noundef nonnull @t2_callback_callee, ptr nocapture align 256 [[A]], i64 undef, ptr noalias nocapture nofree noundef nonnull readonly align 64 dereferenceable(8) [[C]])
; TUNIT-NEXT: ret void
;
; CGSCC-LABEL: define {{[^@]+}}@t2_caller
@@ -176,10 +176,10 @@ define void @t2_caller(ptr noalias %a) {
; CGSCC-NEXT: entry:
; CGSCC-NEXT: [[B:%.*]] = alloca i32, align 32
; CGSCC-NEXT: [[C:%.*]] = alloca ptr, align 64
-; CGSCC-NEXT: [[PTR:%.*]] = alloca i32, align 128
+; CGSCC-NEXT: [[PTR1:%.*]] = alloca [0 x i8], align 1
; CGSCC-NEXT: store i32 42, ptr [[B]], align 32
; CGSCC-NEXT: store ptr [[B]], ptr [[C]], align 64
-; CGSCC-NEXT: call void (ptr, ptr, ptr, ...) @t2_callback_broker(ptr noundef align 4294967296 null, ptr noalias nocapture noundef nonnull align 128 dereferenceable(4) [[PTR]], ptr nocapture noundef nonnull @t2_callback_callee, ptr nocapture align 256 [[A]], i64 noundef 99, ptr noalias nocapture nofree noundef nonnull readonly align 64 dereferenceable(8) [[C]])
+; CGSCC-NEXT: call void (ptr, ptr, ptr, ...) @t2_callback_broker(ptr noundef align 4294967296 null, ptr noalias nocapture noundef nonnull align 128 dereferenceable(4) [[PTR1]], ptr nocapture noundef nonnull @t2_callback_callee, ptr nocapture align 256 [[A]], i64 noundef 99, ptr noalias nocapture nofree noundef nonnull readonly align 64 dereferenceable(8) [[C]])
; CGSCC-NEXT: ret void
;
entry:
@@ -238,11 +238,11 @@ define void @t3_caller(ptr noalias %a) {
; TUNIT-NEXT: entry:
; TUNIT-NEXT: [[B:%.*]] = alloca i32, align 32
; TUNIT-NEXT: [[C:%.*]] = alloca ptr, align 64
-; TUNIT-NEXT: [[PTR:%.*]] = alloca i32, align 128
+; TUNIT-NEXT: [[PTR1:%.*]] = alloca [0 x i8], align 1
; TUNIT-NEXT: store i32 42, ptr [[B]], align 32
; TUNIT-NEXT: store ptr [[B]], ptr [[C]], align 64
-; TUNIT-NEXT: call void (ptr, ptr, ptr, ...) @t3_callback_broker(ptr noundef align 4294967296 null, ptr noalias nocapture noundef nonnull align 128 dereferenceable(4) [[PTR]], ptr nocapture noundef nonnull @t3_callback_callee, ptr nocapture align 256 [[A]], i64 undef, ptr noalias nocapture nofree noundef nonnull readonly align 64 dereferenceable(8) [[C]])
-; TUNIT-NEXT: call void (ptr, ptr, ptr, ...) @t3_callback_broker(ptr noundef align 4294967296 null, ptr noalias nocapture noundef nonnull align 128 dereferenceable(4) [[PTR]], ptr nocapture noundef nonnull @t3_callback_callee, ptr nocapture align 256 [[A]], i64 undef, ptr noalias nocapture nofree noundef nonnull readonly align 64 dereferenceable(8) [[C]])
+; TUNIT-NEXT: call void (ptr, ptr, ptr, ...) @t3_callback_broker(ptr noundef align 4294967296 null, ptr noalias nocapture noundef nonnull align 128 dereferenceable(4) [[PTR1]], ptr nocapture noundef nonnull @t3_callback_callee, ptr nocapture align 256 [[A]], i64 undef, ptr noalias nocapture nofree noundef nonnull readonly align 64 dereferenceable(8) [[C]])
+; TUNIT-NEXT: call void (ptr, ptr, ptr, ...) @t3_callback_broker(ptr noundef align 4294967296 null, ptr noalias nocapture noundef nonnull align 128 dereferenceable(4) [[PTR1]], ptr nocapture noundef nonnull @t3_callback_callee, ptr nocapture align 256 [[A]], i64 undef, ptr noalias nocapture nofree noundef nonnull readonly align 64 dereferenceable(8) [[C]])
; TUNIT-NEXT: ret void
;
; CGSCC-LABEL: define {{[^@]+}}@t3_caller
@@ -250,11 +250,11 @@ define void @t3_caller(ptr noalias %a) {
; CGSCC-NEXT: entry:
; CGSCC-NEXT: [[B:%.*]] = alloca i32, align 32
; CGSCC-NEXT: [[C:%.*]] = alloca ptr, align 64
-; CGSCC-NEXT: [[PTR:%.*]] = alloca i32, align 128
+; CGSCC-NEXT: [[PTR1:%.*]] = alloca [0 x i8], align 1
; CGSCC-NEXT: store i32 42, ptr [[B]], align 32
; CGSCC-NEXT: store ptr [[B]], ptr [[C]], align 64
-; CGSCC-NEXT: call void (ptr, ptr, ptr, ...) @t3_callback_broker(ptr noundef align 4294967296 null, ptr noalias nocapture noundef nonnull align 128 dereferenceable(4) [[PTR]], ptr nocapture noundef nonnull @t3_callback_callee, ptr nocapture align 256 [[A]], i64 noundef 99, ptr noalias nocapture nofree noundef nonnull readonly align 64 dereferenceable(8) [[C]])
-; CGSCC-NEXT: call void (ptr, ptr, ptr, ...) @t3_callback_broker(ptr noundef align 4294967296 null, ptr noalias nocapture noundef nonnull align 128 dereferenceable(4) [[PTR]], ptr nocapture noundef nonnull @t3_callback_callee, ptr nocapture align 256 [[A]], i64 noundef 99, ptr noalias nocapture nofree noundef nonnull readonly align 64 dereferenceable(8) [[C]])
+; CGSCC-NEXT: call void (ptr, ptr, ptr, ...) @t3_callback_broker(ptr noundef align 4294967296 null, ptr noalias nocapture noundef nonnull align 128 dereferenceable(4) [[PTR1]], ptr nocapture noundef nonnull @t3_callback_callee, ptr nocapture align 256 [[A]], i64 noundef 99, ptr noalias nocapture nofree noundef nonnull readonly align 64 dereferenceable(8) [[C]])
+; CGSCC-NEXT: call void (ptr, ptr, ptr, ...) @t3_callback_broker(ptr noundef align 4294967296 null, ptr noalias nocapture noundef nonnull align 128 dereferenceable(4) [[PTR1]], ptr nocapture noundef nonnull @t3_callback_callee, ptr nocapture align 256 [[A]], i64 noundef 99, ptr noalias nocapture nofree noundef nonnull readonly align 64 dereferenceable(8) [[C]])
; CGSCC-NEXT: ret void
;
entry:
diff --git a/llvm/test/Transforms/Attributor/heap_to_stack.ll b/llvm/test/Transforms/Attributor/heap_to_stack.ll
index 33ac066e43d09..961253a85287f 100644
--- a/llvm/test/Transforms/Attributor/heap_to_stack.ll
+++ b/llvm/test/Transforms/Attributor/heap_to_stack.ll
@@ -503,7 +503,7 @@ define i32 @malloc_in_loop(i32 %arg) {
; CHECK-NEXT: bb:
; CHECK-NEXT: [[I:%.*]] = alloca i32, align 4
; CHECK-NEXT: [[I1:%.*]] = alloca ptr, align 8
-; CHECK-NEXT: [[I11:%.*]] = alloca i8, i32 0, align 8
+; CHECK-NEXT: [[I11:%.*]] = alloca [0 x i8], align 1
; CHECK-NEXT: store i32 [[ARG]], ptr [[I]], align 4
; CHECK-NEXT: br label [[BB2:%.*]]
; CHECK: bb2:
diff --git a/llvm/test/Transforms/Attributor/heap_to_stack_gpu.ll b/llvm/test/Transforms/Attributor/heap_to_stack_gpu.ll
index 2a5b3e94291a2..5d73055f7394d 100644
--- a/llvm/test/Transforms/Attributor/heap_to_stack_gpu.ll
+++ b/llvm/test/Transforms/Attributor/heap_to_stack_gpu.ll
@@ -453,7 +453,7 @@ define i32 @malloc_in_loop(i32 %arg) {
; CHECK-NEXT: bb:
; CHECK-NEXT: [[I:%.*]] = alloca i32, align 4
; CHECK-NEXT: [[I1:%.*]] = alloca ptr, align 8
-; CHECK-NEXT: [[I11:%.*]] = alloca i8, i32 0, align 8
+; CHECK-NEXT: [[I11:%.*]] = alloca [0 x i8], align 1
; CHECK-NEXT: store i32 [[ARG]], ptr [[I]], align 4
; CHECK-NEXT: br label [[BB2:%.*]]
; CHECK: bb2:
diff --git a/llvm/test/Transforms/Attributor/liveness.ll b/llvm/test/Transforms/Attributor/liveness.ll
index f17bd5795a174..9eb79f8a46723 100644
--- a/llvm/test/Transforms/Attributor/liveness.ll
+++ b/llvm/test/Transforms/Attributor/liveness.ll
@@ -2587,8 +2587,8 @@ define void @bad_gep() {
; TUNIT-LABEL: define {{[^@]+}}@bad_gep
; TUNIT-SAME: () #[[ATTR13]] {
; TUNIT-NEXT: entry:
-; TUNIT-NEXT: [[N1:%.*]] = alloca i8, i32 0, align 1
-; TUNIT-NEXT: [[M2:%.*]] = alloca i8, i32 0, align 1
+; TUNIT-NEXT: [[N1:%.*]] = alloca [0 x i8], align 1
+; TUNIT-NEXT: [[M2:%.*]] = alloca [0 x i8], align 1
; TUNIT-NEXT: call void @llvm.lifetime.start.p0(i64 noundef 1, ptr noalias nocapture nofree noundef nonnull dereferenceable(1) [[N1]]) #[[ATTR18:[0-9]+]]
; TUNIT-NEXT: br label [[EXIT:%.*]]
; TUNIT: while.body:
@@ -2605,8 +2605,8 @@ define void @bad_gep() {
; CGSCC-LABEL: define {{[^@]+}}@bad_gep
; CGSCC-SAME: () #[[ATTR6]] {
; CGSCC-NEXT: entry:
-; CGSCC-NEXT: [[N1:%.*]] = alloca i8, i32 0, align 1
-; CGSCC-NEXT: [[M2:%.*]] = alloca i8, i32 0, align 1
+; CGSCC-NEXT: [[N1:%.*]] = alloca [0 x i8], align 1
+; CGSCC-NEXT: [[M2:%.*]] = alloca [0 x i8], align 1
; CGSCC-NEXT: call void @llvm.lifetime.start.p0(i64 noundef 1, ptr noalias nocapture nofree noundef nonnull dereferenceable(1) [[N1]]) #[[ATTR21:[0-9]+]]
; CGSCC-NEXT: br label [[EXIT:%.*]]
; CGSCC: while.body:
diff --git a/llvm/test/Transforms/Attributor/multiple-offsets-pointer-info.ll b/llvm/test/Transforms/Attributor/multiple-offsets-pointer-info.ll
index c6945d65acb29..a120524026378 100644
--- a/llvm/test/Transforms/Attributor/multiple-offsets-pointer-info.ll
+++ b/llvm/test/Transforms/Attributor/multiple-offsets-pointer-info.ll
@@ -1,6 +1,6 @@
; NOTE: Assertions have been autogenerated by utils/update_test_checks.py UTC_ARGS: --function-signature --check-attributes --check-globals
-; 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
+; 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.T = type { i32, [10 x [20 x i8]] }
@@ -50,20 +50,26 @@ define i8 @select_offsets_simplifiable_2(i1 %cnd1, i1 %cnd2) {
; CHECK-LABEL: define {{[^@]+}}@select_offsets_simplifiable_2
; CHECK-SAME: (i1 [[CND1:%.*]], i1 [[CND2:%.*]]) #[[ATTR1:[0-9]+]] {
; CHECK-NEXT: entry:
-; CHECK-NEXT: [[BYTES:%.*]] = alloca [1024 x i8], align 16
-; CHECK-NEXT: [[GEP23:%.*]] = getelementptr inbounds [1024 x i8], ptr [[BYTES]], i64 0, i64 23
-; CHECK-NEXT: store i8 23, ptr [[GEP23]], align 4
-; CHECK-NEXT: [[GEP29:%.*]] = getelementptr inbounds [1024 x i8], ptr [[BYTES]], i64 0, i64 29
-; CHECK-NEXT: store i8 29, ptr [[GEP29]], align 4
-; CHECK-NEXT: [[GEP7:%.*]] = getelementptr inbounds [1024 x i8], ptr [[BYTES]], i64 0, i64 7
-; CHECK-NEXT: store i8 7, ptr [[GEP7]], align 4
-; CHECK-NEXT: [[GEP31:%.*]] = getelementptr inbounds [1024 x i8], ptr [[BYTES]], i64 0, i64 31
+; CHECK-NEXT: [[BYTES1:%.*]] = alloca [4 x i8], align 1
+; CHECK-NEXT: [[GEP23:%.*]] = getelementptr inbounds [1024 x i8], ptr [[BYTES1]], i64 0, i64 23
+; CHECK-NEXT: [[NEWGEP:%.*]] = getelementptr ptr, ptr [[GEP23]], i64 -22
+; CHECK-NEXT: store i8 23, ptr [[NEWGEP]], align 4
+; CHECK-NEXT: [[GEP29:%.*]] = getelementptr inbounds [1024 x i8], ptr [[BYTES1]], i64 0, i64 29
+; CHECK-NEXT: [[NEWGEP5:%.*]] = getelementptr ptr, ptr [[GEP29]], i64 -27
+; CHECK-NEXT: store i8 29, ptr [[NEWGEP5]], align 4
+; CHECK-NEXT: [[GEP7:%.*]] = getelementptr inbounds [1024 x i8], ptr [[BYTES1]], i64 0, i64 7
+; CHECK-NEXT: [[NEWGEP4:%.*]] = getelementptr ptr, ptr [[GEP7]], i64 -4
+; CHECK-NEXT: store i8 7, ptr [[NEWGEP4]], align 4
+; CHECK-NEXT: [[GEP31:%.*]] = getelementptr inbounds [1024 x i8], ptr [[BYTES1]], i64 0, i64 31
+; CHECK-NEXT: [[NEWGEP6:%.*]] = getelementptr ptr, ptr [[GEP31]], i64 -31
+; CHECK-NEXT: store i8 42, ptr [[NEWGEP6]], align 4
; CHECK-NEXT: [[SEL0:%.*]] = select i1 [[CND1]], i64 20, i64 26
; CHECK-NEXT: [[SEL1:%.*]] = select i1 [[CND2]], i64 [[SEL0]], i64 4
-; CHECK-NEXT: [[GEP_SEL:%.*]] = getelementptr inbounds [1024 x i8], ptr [[BYTES]], i64 0, i64 [[SEL1]]
+; CHECK-NEXT: [[GEP_SEL:%.*]] = getelementptr inbounds [1024 x i8], ptr [[BYTES1]], i64 0, i64 [[SEL1]]
; CHECK-NEXT: [[GEP_PLUS:%.*]] = getelementptr inbounds i8, ptr [[GEP_SEL]], i64 3
-; CHECK-NEXT: [[I:%.*]] = load i8, ptr [[GEP_PLUS]], align 4
-; CHECK-NEXT: ret i8 [[I]]
+; CHECK-NEXT: [[NEWGEP2:%.*]] = getelementptr ptr, ptr [[GEP_PLUS]], i64 -22
+; CHECK-NEXT: [[I3:%.*]] = load i8, ptr [[NEWGEP2]], align 4
+; CHECK-NEXT: ret i8 [[I3]]
;
entry:
%Bytes = alloca [1024 x i8], align 16
@@ -93,10 +99,15 @@ define i8 @select_offsets_simplifiable_3(i1 %cnd1, i1 %cnd2) {
; CHECK-LABEL: define {{[^@]+}}@select_offsets_simplifiable_3
; CHECK-SAME: (i1 [[CND1:%.*]], i1 [[CND2:%.*]]) #[[ATTR1]] {
; CHECK-NEXT: entry:
-; CHECK-NEXT: [[BUNDLE:%.*]] = alloca [[STRUCT_T:%.*]], align 64
+; CHECK-NEXT: [[BUNDLE1:%.*]] = alloca [5 x i8], align 1
+; CHECK-NEXT: [[GEP_FIXED:%.*]] = getelementptr inbounds [[STRUCT_T:%.*]], ptr [[BUNDLE1]], i64 0, i32 1, i64 1, i64 1
+; CHECK-NEXT: [[NEWGEP:%.*]] = getelementptr ptr, ptr [[GEP_FIXED]], i64 -22
+; CHECK-NEXT: store i8 100, ptr [[NEWGEP]], align 4
; CHECK-NEXT: [[SEL1:%.*]] = select i1 [[CND1]], i64 1, i64 3
; CHECK-NEXT: [[SEL2:%.*]] = select i1 [[CND2]], i64 5, i64 11
-; CHECK-NEXT: [[GEP_SEL:%.*]] = getelementptr inbounds [[STRUCT_T]], ptr [[BUNDLE]], i64 0, i32 1, i64 [[SEL1]], i64 [[SEL2]]
+; CHECK-NEXT: [[GEP_SEL:%.*]] = getelementptr inbounds [[STRUCT_T]], ptr [[BUNDLE1]], i64 0, i32 1, i64 [[SEL1]], i64 [[SEL2]]
+; CHECK-NEXT: [[NEWGEP2:%.*]] = getelementptr ptr, ptr [[GEP_SEL]], i64 -69
+; CHECK-NEXT: store i8 42, ptr [[NEWGEP2]], align 4
; CHECK-NEXT: ret i8 100
;
entry:
@@ -117,10 +128,12 @@ define i8 @select_offsets_simplifiable_4(i1 %cnd1, i1 %cnd2) {
; CHECK-LABEL: define {{[^@]+}}@select_offsets_simplifiable_4
; CHECK-SAME: (i1 [[CND1:%.*]], i1 [[CND2:%.*]]) #[[ATTR1]] {
; CHECK-NEXT: entry:
-; CHECK-NEXT: [[BYTES:%.*]] = alloca [1024 x i8], align 16
+; CHECK-NEXT: [[BYTES1:%.*]] = alloca [3 x i8], align 1
; CHECK-NEXT: [[SEL0:%.*]] = select i1 [[CND1]], i64 23, i64 29
; CHECK-NEXT: [[SEL1:%.*]] = select i1 [[CND2]], i64 [[SEL0]], i64 7
-; CHECK-NEXT: [[GEP_SEL:%.*]] = getelementptr inbounds [1024 x i8], ptr [[BYTES]], i64 0, i64 [[SEL1]]
+; CHECK-NEXT: [[GEP_SEL:%.*]] = getelementptr inbounds [1024 x i8], ptr [[BYTES1]], i64 0, i64 [[SEL1]]
+; CHECK-NEXT: [[NEWGEP:%.*]] = getelementptr ptr, ptr [[GEP_SEL]], i64 -23
+; CHECK-NEXT: store i8 100, ptr [[NEWGEP]], align 4
; CHECK-NEXT: ret i8 100
;
entry:
@@ -135,18 +148,35 @@ entry:
}
define i8 @select_offsets_not_simplifiable_1(i1 %cnd1, i1 %cnd2) {
-; CHECK: Function Attrs: mustprogress nofree norecurse nosync nounwind willreturn memory(none)
-; CHECK-LABEL: define {{[^@]+}}@select_offsets_not_simplifiable_1
-; CHECK-SAME: (i1 [[CND1:%.*]], i1 [[CND2:%.*]]) #[[ATTR1]] {
-; CHECK-NEXT: entry:
-; CHECK-NEXT: [[BYTES:%.*]] = alloca [1024 x i8], align 16
-; CHECK-NEXT: [[SEL0:%.*]] = select i1 [[CND1]], i64 23, i64 29
-; CHECK-NEXT: [[SEL1:%.*]] = select i1 [[CND2]], i64 [[SEL0]], i64 7
-; CHECK-NEXT: [[GEP23:%.*]] = getelementptr inbounds [1024 x i8], ptr [[BYTES]], i64 0, i64 23
-; CHECK-NEXT: store i8 100, ptr [[GEP23]], align 4
-; CHECK-NEXT: [[GEP_SEL:%.*]] = getelementptr inbounds [1024 x i8], ptr [[BYTES]], i64 0, i64 [[SEL1]]
-; CHECK-NEXT: [[I:%.*]] = load i8, ptr [[GEP_SEL]], align 4
-; CHECK-NEXT: ret i8 [[I]]
+; TUNIT: Function Attrs: mustprogress nofree norecurse nosync nounwind willreturn memory(none)
+; TUNIT-LABEL: define {{[^@]+}}@select_offsets_not_simplifiable_1
+; TUNIT-SAME: (i1 [[CND1:%.*]], i1 [[CND2:%.*]]) #[[ATTR1]] {
+; TUNIT-NEXT: entry:
+; TUNIT-NEXT: [[BYTES1:%.*]] = alloca [3 x i8], align 1
+; TUNIT-NEXT: [[SEL0:%.*]] = select i1 [[CND1]], i64 23, i64 29
+; TUNIT-NEXT: [[SEL1:%.*]] = select i1 [[CND2]], i64 [[SEL0]], i64 7
+; TUNIT-NEXT: [[GEP23:%.*]] = getelementptr inbounds [1024 x i8], ptr [[BYTES1]], i64 0, i64 23
+; TUNIT-NEXT: [[NEWGEP:%.*]] = getelementptr ptr, ptr [[GEP23]], i64 -23
+; TUNIT-NEXT: store i8 100, ptr [[NEWGEP]], align 4
+; TUNIT-NEXT: [[GEP_SEL:%.*]] = getelementptr inbounds [1024 x i8], ptr [[BYTES1]], i64 0, i64 [[SEL1]]
+; TUNIT-NEXT: [[NEWGEP2:%.*]] = getelementptr ptr, ptr [[GEP_SEL]], i64 -23
+; TUNIT-NEXT: [[I3:%.*]] = load i8, ptr [[NEWGEP2]], align 4
+; TUNIT-NEXT: ret i8 [[I3]]
+;
+; CGSCC: Function Attrs: mustprogress nofree norecurse nosync nounwind willreturn memory(none)
+; CGSCC-LABEL: define {{[^@]+}}@select_offsets_not_simplifiable_1
+; CGSCC-SAME: (i1 [[CND1:%.*]], i1 [[CND2:%.*]]) #[[ATTR1]] {
+; CGSCC-NEXT: entry:
+; CGSCC-NEXT: [[BYTES1:%.*]] = alloca [3 x i8], align 1
+; CGSCC-NEXT: [[SEL0:%.*]] = select i1 [[CND1]], i64 23, i64 29
+; CGSCC-NEXT: [[SEL1:%.*]] = select i1 [[CND2]], i64 [[SEL0]], i64 7
+; CGSCC-NEXT: [[GEP23:%.*]] = getelementptr inbounds [1024 x i8], ptr [[BYTES1]], i64 0, i64 23
+; CGSCC-NEXT: [[NEWGEP3:%.*]] = getelementptr ptr, ptr [[GEP23]], i64 -23
+; CGSCC-NEXT: store i8 100, ptr [[NEWGEP3]], align 4
+; CGSCC-NEXT: [[GEP_SEL:%.*]] = getelementptr inbounds [1024 x i8], ptr [[BYTES1]], i64 0, i64 [[SEL1]]
+; CGSCC-NEXT: [[NEWGEP:%.*]] = getelementptr ptr, ptr [[GEP_SEL]], i64 -23
+; CGSCC-NEXT: [[I2:%.*]] = load i8, ptr [[NEWGEP]], align 4
+; CGSCC-NEXT: ret i8 [[I2]]
;
entry:
%Bytes = alloca [1024 x i8], align 16
@@ -164,15 +194,17 @@ define i8 @select_offsets_not_simplifiable_2(i1 %cnd1, i1 %cnd2) {
; CHECK-LABEL: define {{[^@]+}}@select_offsets_not_simplifiable_2
; CHECK-SAME: (i1 [[CND1:%.*]], i1 [[CND2:%.*]]) #[[ATTR1]] {
; CHECK-NEXT: entry:
-; CHECK-NEXT: [[BYTES:%.*]] = alloca [1024 x i8], align 16
+; CHECK-NEXT: [[BYTES1:%.*]] = alloca [3 x i8], align 1
; CHECK-NEXT: [[SEL0:%.*]] = select i1 [[CND1]], i64 23, i64 29
; CHECK-NEXT: [[SEL1:%.*]] = select i1 [[CND2]], i64 [[SEL0]], i64 7
-; CHECK-NEXT: [[GEP32:%.*]] = getelementptr inbounds [1024 x i8], ptr [[BYTES]], i64 0, i64 32
-; CHECK-NEXT: store i8 100, ptr [[GEP32]], align 16
-; CHECK-NEXT: [[GEP_SEL:%.*]] = getelementptr inbounds [1024 x i8], ptr [[BYTES]], i64 0, i64 [[SEL1]]
+; CHECK-NEXT: [[GEP32:%.*]] = getelementptr inbounds [1024 x i8], ptr [[BYTES1]], i64 0, i64 32
+; CHECK-NEXT: [[NEWGEP3:%.*]] = getelementptr ptr, ptr [[GEP32]], i64 -32
+; CHECK-NEXT: store i8 100, ptr [[NEWGEP3]], align 16
+; CHECK-NEXT: [[GEP_SEL:%.*]] = getelementptr inbounds [1024 x i8], ptr [[BYTES1]], i64 0, i64 [[SEL1]]
; CHECK-NEXT: [[GEP_PLUS:%.*]] = getelementptr inbounds i8, ptr [[GEP_SEL]], i64 3
-; CHECK-NEXT: [[I:%.*]] = load i8, ptr [[GEP_PLUS]], align 4
-; CHECK-NEXT: ret i8 [[I]]
+; CHECK-NEXT: [[NEWGEP:%.*]] = getelementptr ptr, ptr [[GEP_PLUS]], i64 -32
+; CHECK-NEXT: [[I2:%.*]] = load i8, ptr [[NEWGEP]], align 4
+; CHECK-NEXT: ret i8 [[I2]]
;
entry:
%Bytes = alloca [1024 x i8], align 16
@@ -237,19 +269,37 @@ entry:
}
define i8 @select_offsets_not_simplifiable_5(i1 %cnd1, i1 %cnd2) {
-; CHECK: Function Attrs: mustprogress nofree norecurse nosync nounwind willreturn memory(none)
-; CHECK-LABEL: define {{[^@]+}}@select_offsets_not_simplifiable_5
-; CHECK-SAME: (i1 [[CND1:%.*]], i1 [[CND2:%.*]]) #[[ATTR1]] {
-; CHECK-NEXT: entry:
-; CHECK-NEXT: [[BUNDLE:%.*]] = alloca [[STRUCT_T:%.*]], align 64
-; CHECK-NEXT: [[GEP_FIXED:%.*]] = getelementptr inbounds [[STRUCT_T]], ptr [[BUNDLE]], i64 0, i32 1, i64 3, i64 5
-; CHECK-NEXT: store i8 100, ptr [[GEP_FIXED]], align 4
-; CHECK-NEXT: [[SEL1:%.*]] = select i1 [[CND1]], i64 1, i64 3
-; CHECK-NEXT: [[SEL2:%.*]] = select i1 [[CND2]], i64 5, i64 11
-; CHECK-NEXT: [[GEP_SEL:%.*]] = getelementptr inbounds [[STRUCT_T]], ptr [[BUNDLE]], i64 0, i32 1, i64 [[SEL1]], i64 [[SEL2]]
-; CHECK-NEXT: store i8 42, ptr [[GEP_SEL]], align 4
-; CHECK-NEXT: [[I:%.*]] = load i8, ptr [[GEP_FIXED]], align 4
-; CHECK-NEXT: ret i8 [[I]]
+; TUNIT: Function Attrs: mustprogress nofree norecurse nosync nounwind willreturn memory(none)
+; TUNIT-LABEL: define {{[^@]+}}@select_offsets_not_simplifiable_5
+; TUNIT-SAME: (i1 [[CND1:%.*]], i1 [[CND2:%.*]]) #[[ATTR1]] {
+; TUNIT-NEXT: entry:
+; TUNIT-NEXT: [[BUNDLE1:%.*]] = alloca [4 x i8], align 1
+; TUNIT-NEXT: [[GEP_FIXED:%.*]] = getelementptr inbounds [[STRUCT_T:%.*]], ptr [[BUNDLE1]], i64 0, i32 1, i64 3, i64 5
+; TUNIT-NEXT: [[NEWGEP:%.*]] = getelementptr ptr, ptr [[GEP_FIXED]], i64 -69
+; TUNIT-NEXT: store i8 100, ptr [[NEWGEP]], align 4
+; TUNIT-NEXT: [[SEL1:%.*]] = select i1 [[CND1]], i64 1, i64 3
+; TUNIT-NEXT: [[SEL2:%.*]] = select i1 [[CND2]], i64 5, i64 11
+; TUNIT-NEXT: [[GEP_SEL:%.*]] = getelementptr inbounds [[STRUCT_T]], ptr [[BUNDLE1]], i64 0, i32 1, i64 [[SEL1]], i64 [[SEL2]]
+; TUNIT-NEXT: [[NEWGEP2:%.*]] = getelementptr ptr, ptr [[GEP_SEL]], i64 -69
+; TUNIT-NEXT: store i8 42, ptr [[NEWGEP2]], align 4
+; TUNIT-NEXT: [[I:%.*]] = load i8, ptr [[GEP_FIXED]], align 4
+; TUNIT-NEXT: ret i8 [[I]]
+;
+; CGSCC: Function Attrs: mustprogress nofree norecurse nosync nounwind willreturn memory(none)
+; CGSCC-LABEL: define {{[^@]+}}@select_offsets_not_simplifiable_5
+; CGSCC-SAME: (i1 [[CND1:%.*]], i1 [[CND2:%.*]]) #[[ATTR1]] {
+; CGSCC-NEXT: entry:
+; CGSCC-NEXT: [[BUNDLE1:%.*]] = alloca [4 x i8], align 1
+; CGSCC-NEXT: [[GEP_FIXED:%.*]] = getelementptr inbounds [[STRUCT_T:%.*]], ptr [[BUNDLE1]], i64 0, i32 1, i64 3, i64 5
+; CGSCC-NEXT: [[NEWGEP2:%.*]] = getelementptr ptr, ptr [[GEP_FIXED]], i64 -69
+; CGSCC-NEXT: store i8 100, ptr [[NEWGEP2]], align 4
+; CGSCC-NEXT: [[SEL1:%.*]] = select i1 [[CND1]], i64 1, i64 3
+; CGSCC-NEXT: [[SEL2:%.*]] = select i1 [[CND2]], i64 5, i64 11
+; CGSCC-NEXT: [[GEP_SEL:%.*]] = getelementptr inbounds [[STRUCT_T]], ptr [[BUNDLE1]], i64 0, i32 1, i64 [[SEL1]], i64 [[SEL2]]
+; CGSCC-NEXT: [[NEWGEP:%.*]] = getelementptr ptr, ptr [[GEP_SEL]], i64 -69
+; CGSCC-NEXT: store i8 42, ptr [[NEWGEP]], align 4
+; CGSCC-NEXT: [[I:%.*]] = load i8, ptr [[GEP_FIXED]], align 4
+; CGSCC-NEXT: ret i8 [[I]]
;
entry:
%bundle = alloca %struct.T, align 64
@@ -267,16 +317,35 @@ entry:
}
define i8 @select_gep_simplifiable_1(i1 %cnd1, i1 %cnd2) {
-; CHECK: Function Attrs: mustprogress nofree norecurse nosync nounwind willreturn memory(write)
-; CHECK-LABEL: define {{[^@]+}}@select_gep_simplifiable_1
-; CHECK-SAME: (i1 [[CND1:%.*]], i1 [[CND2:%.*]]) #[[ATTR2:[0-9]+]] {
-; CHECK-NEXT: entry:
-; CHECK-NEXT: [[BYTES:%.*]] = alloca [1024 x i8], align 16
-; CHECK-NEXT: [[GEP7:%.*]] = getelementptr inbounds [1024 x i8], ptr [[BYTES]], i64 0, i64 7
-; CHECK-NEXT: [[GEP23:%.*]] = getelementptr inbounds [1024 x i8], ptr [[BYTES]], i64 0, i64 23
-; CHECK-NEXT: [[SEL_PTR:%.*]] = select i1 [[CND1]], ptr [[GEP7]], ptr [[GEP23]]
-; CHECK-NEXT: store i8 42, ptr [[SEL_PTR]], align 4
-; CHECK-NEXT: ret i8 21
+; TUNIT: Function Attrs: mustprogress nofree norecurse nosync nounwind willreturn memory(write)
+; TUNIT-LABEL: define {{[^@]+}}@select_gep_simplifiable_1
+; TUNIT-SAME: (i1 [[CND1:%.*]], i1 [[CND2:%.*]]) #[[ATTR2:[0-9]+]] {
+; TUNIT-NEXT: entry:
+; TUNIT-NEXT: [[BYTES1:%.*]] = alloca [3 x i8], align 1
+; TUNIT-NEXT: [[GEP3:%.*]] = getelementptr inbounds [1024 x i8], ptr [[BYTES1]], i64 0, i64 3
+; TUNIT-NEXT: [[NEWGEP2:%.*]] = getelementptr ptr, ptr [[GEP3]], i64 -1
+; TUNIT-NEXT: store i8 21, ptr [[NEWGEP2]], align 4
+; TUNIT-NEXT: [[GEP7:%.*]] = getelementptr inbounds [1024 x i8], ptr [[BYTES1]], i64 0, i64 7
+; TUNIT-NEXT: [[GEP23:%.*]] = getelementptr inbounds [1024 x i8], ptr [[BYTES1]], i64 0, i64 23
+; TUNIT-NEXT: [[SEL_PTR:%.*]] = select i1 [[CND1]], ptr [[GEP7]], ptr [[GEP23]]
+; TUNIT-NEXT: [[NEWGEP:%.*]] = getelementptr ptr, ptr [[SEL_PTR]], i64 -23
+; TUNIT-NEXT: store i8 42, ptr [[NEWGEP]], align 4
+; TUNIT-NEXT: ret i8 21
+;
+; CGSCC: Function Attrs: mustprogress nofree norecurse nosync nounwind willreturn memory(write)
+; CGSCC-LABEL: define {{[^@]+}}@select_gep_simplifiable_1
+; CGSCC-SAME: (i1 [[CND1:%.*]], i1 [[CND2:%.*]]) #[[ATTR2:[0-9]+]] {
+; CGSCC-NEXT: entry:
+; CGSCC-NEXT: [[BYTES1:%.*]] = alloca [3 x i8], align 1
+; CGSCC-NEXT: [[GEP3:%.*]] = getelementptr inbounds [1024 x i8], ptr [[BYTES1]], i64 0, i64 3
+; CGSCC-NEXT: [[NEWGEP:%.*]] = getelementptr ptr, ptr [[GEP3]], i64 -1
+; CGSCC-NEXT: store i8 21, ptr [[NEWGEP]], align 4
+; CGSCC-NEXT: [[GEP7:%.*]] = getelementptr inbounds [1024 x i8], ptr [[BYTES1]], i64 0, i64 7
+; CGSCC-NEXT: [[GEP23:%.*]] = getelementptr inbounds [1024 x i8], ptr [[BYTES1]], i64 0, i64 23
+; CGSCC-NEXT: [[SEL_PTR:%.*]] = select i1 [[CND1]], ptr [[GEP7]], ptr [[GEP23]]
+; CGSCC-NEXT: [[NEWGEP2:%.*]] = getelementptr ptr, ptr [[SEL_PTR]], i64 -23
+; CGSCC-NEXT: store i8 42, ptr [[NEWGEP2]], align 4
+; CGSCC-NEXT: ret i8 21
;
entry:
%Bytes = alloca [1024 x i8], align 16
@@ -295,12 +364,14 @@ define i8 @select_gep_not_simplifiable_1(i1 %cnd1, i1 %cnd2) {
; CHECK-LABEL: define {{[^@]+}}@select_gep_not_simplifiable_1
; CHECK-SAME: (i1 [[CND1:%.*]], i1 [[CND2:%.*]]) #[[ATTR3:[0-9]+]] {
; CHECK-NEXT: entry:
-; CHECK-NEXT: [[BYTES:%.*]] = alloca [1024 x i8], align 16
-; CHECK-NEXT: [[GEP7:%.*]] = getelementptr inbounds [1024 x i8], ptr [[BYTES]], i64 0, i64 7
-; CHECK-NEXT: store i8 1, ptr [[GEP7]], align 4
-; CHECK-NEXT: [[GEP23:%.*]] = getelementptr inbounds [1024 x i8], ptr [[BYTES]], i64 0, i64 23
+; CHECK-NEXT: [[BYTES1:%.*]] = alloca [2 x i8], align 1
+; CHECK-NEXT: [[GEP7:%.*]] = getelementptr inbounds [1024 x i8], ptr [[BYTES1]], i64 0, i64 7
+; CHECK-NEXT: [[NEWGEP:%.*]] = getelementptr ptr, ptr [[GEP7]], i64 -6
+; CHECK-NEXT: store i8 1, ptr [[NEWGEP]], align 4
+; CHECK-NEXT: [[GEP23:%.*]] = getelementptr inbounds [1024 x i8], ptr [[BYTES1]], i64 0, i64 23
; CHECK-NEXT: [[SEL_PTR:%.*]] = select i1 [[CND1]], ptr [[GEP7]], ptr [[GEP23]]
-; CHECK-NEXT: store i8 42, ptr [[SEL_PTR]], align 4
+; CHECK-NEXT: [[NEWGEP2:%.*]] = getelementptr ptr, ptr [[SEL_PTR]], i64 -23
+; CHECK-NEXT: store i8 42, ptr [[NEWGEP2]], align 4
; CHECK-NEXT: [[I:%.*]] = load i8, ptr [[GEP7]], align 4
; CHECK-NEXT: ret i8 [[I]]
;
@@ -318,25 +389,55 @@ entry:
; FIXME: The whole function is just "ret i8 21".
define i8 @phi_gep_simplifiable_1(i1 %cnd1, i1 %cnd2) {
-; CHECK: Function Attrs: mustprogress nofree norecurse nosync nounwind willreturn
-; CHECK-LABEL: define {{[^@]+}}@phi_gep_simplifiable_1
-; CHECK-SAME: (i1 noundef [[CND1:%.*]], i1 [[CND2:%.*]]) #[[ATTR3]] {
-; 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], ptr [[BYTES]], i64 0, i64 23
-; CHECK-NEXT: store i8 21, ptr [[GEP23]], align 4
-; CHECK-NEXT: br label [[JOIN:%.*]]
-; CHECK: else:
-; CHECK-NEXT: [[GEP31:%.*]] = getelementptr inbounds [1024 x i8], ptr [[BYTES]], i64 0, i64 31
-; CHECK-NEXT: store i8 21, ptr [[GEP31]], align 4
-; CHECK-NEXT: br label [[JOIN]]
-; CHECK: join:
-; CHECK-NEXT: [[PHI_PTR:%.*]] = phi ptr [ [[GEP23]], [[THEN]] ], [ [[GEP31]], [[ELSE]] ]
-; CHECK-NEXT: [[GEP29:%.*]] = getelementptr inbounds [1024 x i8], ptr [[BYTES]], i64 0, i64 29
-; CHECK-NEXT: [[I:%.*]] = load i8, ptr [[PHI_PTR]], align 4
-; CHECK-NEXT: ret i8 [[I]]
+; TUNIT: Function Attrs: mustprogress nofree norecurse nosync nounwind willreturn
+; TUNIT-LABEL: define {{[^@]+}}@phi_gep_simplifiable_1
+; TUNIT-SAME: (i1 noundef [[CND1:%.*]], i1 [[CND2:%.*]]) #[[ATTR3]] {
+; TUNIT-NEXT: entry:
+; TUNIT-NEXT: [[BYTES1:%.*]] = alloca [3 x i8], align 1
+; TUNIT-NEXT: br i1 [[CND1]], label [[THEN:%.*]], label [[ELSE:%.*]]
+; TUNIT: then:
+; TUNIT-NEXT: [[GEP23:%.*]] = getelementptr inbounds [1024 x i8], ptr [[BYTES1]], i64 0, i64 23
+; TUNIT-NEXT: [[NEWGEP2:%.*]] = getelementptr ptr, ptr [[GEP23]], i64 -22
+; TUNIT-NEXT: store i8 21, ptr [[NEWGEP2]], align 4
+; TUNIT-NEXT: br label [[JOIN:%.*]]
+; TUNIT: else:
+; TUNIT-NEXT: [[GEP31:%.*]] = getelementptr inbounds [1024 x i8], ptr [[BYTES1]], i64 0, i64 31
+; TUNIT-NEXT: [[NEWGEP3:%.*]] = getelementptr ptr, ptr [[GEP31]], i64 -31
+; TUNIT-NEXT: store i8 21, ptr [[NEWGEP3]], align 4
+; TUNIT-NEXT: br label [[JOIN]]
+; TUNIT: join:
+; TUNIT-NEXT: [[PHI_PTR:%.*]] = phi ptr [ [[GEP23]], [[THEN]] ], [ [[GEP31]], [[ELSE]] ]
+; TUNIT-NEXT: [[GEP29:%.*]] = getelementptr inbounds [1024 x i8], ptr [[BYTES1]], i64 0, i64 29
+; TUNIT-NEXT: [[NEWGEP:%.*]] = getelementptr ptr, ptr [[GEP29]], i64 -27
+; TUNIT-NEXT: store i8 42, ptr [[NEWGEP]], align 4
+; TUNIT-NEXT: [[NEWGEP4:%.*]] = getelementptr ptr, ptr [[PHI_PTR]], i64 -31
+; TUNIT-NEXT: [[I5:%.*]] = load i8, ptr [[NEWGEP4]], align 4
+; TUNIT-NEXT: ret i8 [[I5]]
+;
+; CGSCC: Function Attrs: mustprogress nofree norecurse nosync nounwind willreturn
+; CGSCC-LABEL: define {{[^@]+}}@phi_gep_simplifiable_1
+; CGSCC-SAME: (i1 noundef [[CND1:%.*]], i1 [[CND2:%.*]]) #[[ATTR3]] {
+; CGSCC-NEXT: entry:
+; CGSCC-NEXT: [[BYTES1:%.*]] = alloca [3 x i8], align 1
+; CGSCC-NEXT: br i1 [[CND1]], label [[THEN:%.*]], label [[ELSE:%.*]]
+; CGSCC: then:
+; CGSCC-NEXT: [[GEP23:%.*]] = getelementptr inbounds [1024 x i8], ptr [[BYTES1]], i64 0, i64 23
+; CGSCC-NEXT: [[NEWGEP:%.*]] = getelementptr ptr, ptr [[GEP23]], i64 -22
+; CGSCC-NEXT: store i8 21, ptr [[NEWGEP]], align 4
+; CGSCC-NEXT: br label [[JOIN:%.*]]
+; CGSCC: else:
+; CGSCC-NEXT: [[GEP31:%.*]] = getelementptr inbounds [1024 x i8], ptr [[BYTES1]], i64 0, i64 31
+; CGSCC-NEXT: [[NEWGEP3:%.*]] = getelementptr ptr, ptr [[GEP31]], i64 -31
+; CGSCC-NEXT: store i8 21, ptr [[NEWGEP3]], align 4
+; CGSCC-NEXT: br label [[JOIN]]
+; CGSCC: join:
+; CGSCC-NEXT: [[PHI_PTR:%.*]] = phi ptr [ [[GEP23]], [[THEN]] ], [ [[GEP31]], [[ELSE]] ]
+; CGSCC-NEXT: [[GEP29:%.*]] = getelementptr inbounds [1024 x i8], ptr [[BYTES1]], i64 0, i64 29
+; CGSCC-NEXT: [[NEWGEP2:%.*]] = getelementptr ptr, ptr [[GEP29]], i64 -27
+; CGSCC-NEXT: store i8 42, ptr [[NEWGEP2]], align 4
+; CGSCC-NEXT: [[NEWGEP4:%.*]] = getelementptr ptr, ptr [[PHI_PTR]], i64 -31
+; CGSCC-NEXT: [[I5:%.*]] = load i8, ptr [[NEWGEP4]], align 4
+; CGSCC-NEXT: ret i8 [[I5]]
;
entry:
%Bytes = alloca [1024 x i8], align 16
@@ -366,19 +467,23 @@ join:
define i8 @phi_gep_simplifiable_2(i1 %cnd1, i1 %cnd2) {
; CHECK: Function Attrs: mustprogress nofree norecurse nosync nounwind willreturn memory(write)
; CHECK-LABEL: define {{[^@]+}}@phi_gep_simplifiable_2
-; CHECK-SAME: (i1 noundef [[CND1:%.*]], i1 [[CND2:%.*]]) #[[ATTR2]] {
+; CHECK-SAME: (i1 noundef [[CND1:%.*]], i1 [[CND2:%.*]]) #[[ATTR2:[0-9]+]] {
; CHECK-NEXT: entry:
-; CHECK-NEXT: [[BYTES:%.*]] = alloca [1024 x i8], align 16
+; CHECK-NEXT: [[BYTES1:%.*]] = alloca [3 x i8], align 1
+; CHECK-NEXT: [[GEP29:%.*]] = getelementptr inbounds [1024 x i8], ptr [[BYTES1]], i64 0, i64 29
+; CHECK-NEXT: [[NEWGEP2:%.*]] = getelementptr ptr, ptr [[GEP29]], i64 -27
+; CHECK-NEXT: store i8 42, ptr [[NEWGEP2]], align 4
; CHECK-NEXT: br i1 [[CND1]], label [[THEN:%.*]], label [[ELSE:%.*]]
; CHECK: then:
-; CHECK-NEXT: [[GEP23:%.*]] = getelementptr inbounds [1024 x i8], ptr [[BYTES]], i64 0, i64 23
+; CHECK-NEXT: [[GEP23:%.*]] = getelementptr inbounds [1024 x i8], ptr [[BYTES1]], i64 0, i64 23
; CHECK-NEXT: br label [[JOIN:%.*]]
; CHECK: else:
-; CHECK-NEXT: [[GEP31:%.*]] = getelementptr inbounds [1024 x i8], ptr [[BYTES]], i64 0, i64 31
+; CHECK-NEXT: [[GEP31:%.*]] = getelementptr inbounds [1024 x i8], ptr [[BYTES1]], i64 0, i64 31
; CHECK-NEXT: br label [[JOIN]]
; CHECK: join:
; CHECK-NEXT: [[PHI_PTR:%.*]] = phi ptr [ [[GEP23]], [[THEN]] ], [ [[GEP31]], [[ELSE]] ]
-; CHECK-NEXT: store i8 21, ptr [[PHI_PTR]], align 4
+; CHECK-NEXT: [[NEWGEP:%.*]] = getelementptr ptr, ptr [[PHI_PTR]], i64 -31
+; CHECK-NEXT: store i8 21, ptr [[NEWGEP]], align 4
; CHECK-NEXT: ret i8 42
;
entry:
@@ -405,23 +510,45 @@ join:
}
define i8 @phi_gep_not_simplifiable_1(i1 %cnd1, i1 %cnd2) {
-; CHECK: Function Attrs: mustprogress nofree norecurse nosync nounwind willreturn
-; CHECK-LABEL: define {{[^@]+}}@phi_gep_not_simplifiable_1
-; CHECK-SAME: (i1 noundef [[CND1:%.*]], i1 [[CND2:%.*]]) #[[ATTR3]] {
-; CHECK-NEXT: entry:
-; CHECK-NEXT: [[BYTES:%.*]] = alloca [1024 x i8], align 16
-; CHECK-NEXT: [[GEP23:%.*]] = getelementptr inbounds [1024 x i8], ptr [[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], ptr [[BYTES]], i64 0, i64 31
-; CHECK-NEXT: br label [[JOIN]]
-; CHECK: join:
-; CHECK-NEXT: [[PHI_PTR:%.*]] = phi ptr [ [[GEP23]], [[THEN]] ], [ [[GEP31]], [[ELSE]] ]
-; CHECK-NEXT: store i8 42, ptr [[GEP23]], align 4
-; CHECK-NEXT: [[I:%.*]] = load i8, ptr [[PHI_PTR]], align 4
-; CHECK-NEXT: ret i8 [[I]]
+; TUNIT: Function Attrs: mustprogress nofree norecurse nosync nounwind willreturn
+; TUNIT-LABEL: define {{[^@]+}}@phi_gep_not_simplifiable_1
+; TUNIT-SAME: (i1 noundef [[CND1:%.*]], i1 [[CND2:%.*]]) #[[ATTR3]] {
+; TUNIT-NEXT: entry:
+; TUNIT-NEXT: [[BYTES1:%.*]] = alloca [2 x i8], align 1
+; TUNIT-NEXT: [[GEP23:%.*]] = getelementptr inbounds [1024 x i8], ptr [[BYTES1]], i64 0, i64 23
+; TUNIT-NEXT: br i1 [[CND1]], label [[THEN:%.*]], label [[ELSE:%.*]]
+; TUNIT: then:
+; TUNIT-NEXT: br label [[JOIN:%.*]]
+; TUNIT: else:
+; TUNIT-NEXT: [[GEP31:%.*]] = getelementptr inbounds [1024 x i8], ptr [[BYTES1]], i64 0, i64 31
+; TUNIT-NEXT: br label [[JOIN]]
+; TUNIT: join:
+; TUNIT-NEXT: [[PHI_PTR:%.*]] = phi ptr [ [[GEP23]], [[THEN]] ], [ [[GEP31]], [[ELSE]] ]
+; TUNIT-NEXT: [[NEWGEP:%.*]] = getelementptr ptr, ptr [[GEP23]], i64 -22
+; TUNIT-NEXT: store i8 42, ptr [[NEWGEP]], align 4
+; TUNIT-NEXT: [[NEWGEP2:%.*]] = getelementptr ptr, ptr [[PHI_PTR]], i64 -31
+; TUNIT-NEXT: [[I3:%.*]] = load i8, ptr [[NEWGEP2]], align 4
+; TUNIT-NEXT: ret i8 [[I3]]
+;
+; CGSCC: Function Attrs: mustprogress nofree norecurse nosync nounwind willreturn
+; CGSCC-LABEL: define {{[^@]+}}@phi_gep_not_simplifiable_1
+; CGSCC-SAME: (i1 noundef [[CND1:%.*]], i1 [[CND2:%.*]]) #[[ATTR3]] {
+; CGSCC-NEXT: entry:
+; CGSCC-NEXT: [[BYTES1:%.*]] = alloca [2 x i8], align 1
+; CGSCC-NEXT: [[GEP23:%.*]] = getelementptr inbounds [1024 x i8], ptr [[BYTES1]], i64 0, i64 23
+; CGSCC-NEXT: br i1 [[CND1]], label [[THEN:%.*]], label [[ELSE:%.*]]
+; CGSCC: then:
+; CGSCC-NEXT: br label [[JOIN:%.*]]
+; CGSCC: else:
+; CGSCC-NEXT: [[GEP31:%.*]] = getelementptr inbounds [1024 x i8], ptr [[BYTES1]], i64 0, i64 31
+; CGSCC-NEXT: br label [[JOIN]]
+; CGSCC: join:
+; CGSCC-NEXT: [[PHI_PTR:%.*]] = phi ptr [ [[GEP23]], [[THEN]] ], [ [[GEP31]], [[ELSE]] ]
+; CGSCC-NEXT: [[NEWGEP3:%.*]] = getelementptr ptr, ptr [[GEP23]], i64 -22
+; CGSCC-NEXT: store i8 42, ptr [[NEWGEP3]], align 4
+; CGSCC-NEXT: [[NEWGEP:%.*]] = getelementptr ptr, ptr [[PHI_PTR]], i64 -31
+; CGSCC-NEXT: [[I2:%.*]] = load i8, ptr [[NEWGEP]], align 4
+; CGSCC-NEXT: ret i8 [[I2]]
;
entry:
%Bytes = alloca [1024 x i8], align 16
@@ -485,7 +612,7 @@ define i8 @phi_offsets(i1 %cnd1, i1 %cnd2) {
; CHECK-LABEL: define {{[^@]+}}@phi_offsets
; CHECK-SAME: (i1 noundef [[CND1:%.*]], i1 [[CND2:%.*]]) #[[ATTR1]] {
; CHECK-NEXT: entry:
-; CHECK-NEXT: [[BYTES:%.*]] = alloca [1024 x i8], align 16
+; CHECK-NEXT: [[BYTES1:%.*]] = alloca [3 x i8], align 1
; CHECK-NEXT: br i1 [[CND1]], label [[THEN:%.*]], label [[ELSE:%.*]]
; CHECK: then:
; CHECK-NEXT: br label [[JOIN:%.*]]
@@ -493,7 +620,9 @@ define i8 @phi_offsets(i1 %cnd1, i1 %cnd2) {
; CHECK-NEXT: br label [[JOIN]]
; CHECK: join:
; CHECK-NEXT: [[PHI:%.*]] = phi i64 [ 3, [[THEN]] ], [ 11, [[ELSE]] ]
-; CHECK-NEXT: [[GEP_PHI:%.*]] = getelementptr inbounds [1024 x i8], ptr [[BYTES]], i64 0, i64 [[PHI]]
+; CHECK-NEXT: [[GEP_PHI:%.*]] = getelementptr inbounds [1024 x i8], ptr [[BYTES1]], i64 0, i64 [[PHI]]
+; CHECK-NEXT: [[NEWGEP:%.*]] = getelementptr ptr, ptr [[GEP_PHI]], i64 -10
+; CHECK-NEXT: store i8 42, ptr [[NEWGEP]], align 4
; CHECK-NEXT: ret i8 100
;
entry:
@@ -521,6 +650,3 @@ join:
; CHECK: attributes #[[ATTR2]] = { mustprogress nofree norecurse nosync nounwind willreturn memory(write) }
; CHECK: attributes #[[ATTR3]] = { mustprogress nofree norecurse nosync nounwind willreturn }
;.
-;; 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/noalias.ll b/llvm/test/Transforms/Attributor/noalias.ll
index c63d81878f535..3483ba83b5268 100644
--- a/llvm/test/Transforms/Attributor/noalias.ll
+++ b/llvm/test/Transforms/Attributor/noalias.ll
@@ -399,10 +399,10 @@ declare void @use_nocapture(ptr nocapture)
declare void @use(ptr)
define void @test12_1() {
; CHECK-LABEL: define {{[^@]+}}@test12_1() {
-; CHECK-NEXT: [[A:%.*]] = alloca i8, align 4
+; CHECK-NEXT: [[A1:%.*]] = alloca [0 x i8], align 1
; CHECK-NEXT: [[B:%.*]] = tail call noalias ptr @malloc(i64 noundef 4)
-; CHECK-NEXT: tail call void @use_nocapture(ptr noalias nocapture noundef nonnull align 4 dereferenceable(1) [[A]])
-; CHECK-NEXT: tail call void @use_nocapture(ptr noalias nocapture noundef nonnull align 4 dereferenceable(1) [[A]])
+; CHECK-NEXT: tail call void @use_nocapture(ptr noalias nocapture noundef nonnull align 4 dereferenceable(1) [[A1]])
+; CHECK-NEXT: tail call void @use_nocapture(ptr noalias nocapture noundef nonnull align 4 dereferenceable(1) [[A1]])
; CHECK-NEXT: tail call void @use_nocapture(ptr noalias nocapture [[B]])
; CHECK-NEXT: tail call void @use_nocapture(ptr noalias nocapture [[B]])
; CHECK-NEXT: ret void
diff --git a/llvm/test/Transforms/Attributor/nocapture-2.ll b/llvm/test/Transforms/Attributor/nocapture-2.ll
index 1e5e9da19909f..b717fce516182 100644
--- a/llvm/test/Transforms/Attributor/nocapture-2.ll
+++ b/llvm/test/Transforms/Attributor/nocapture-2.ll
@@ -757,19 +757,19 @@ define ptr @b64613_b(ptr noundef %p, i32 %i) {
; TUNIT: Function Attrs: mustprogress nofree norecurse nosync nounwind willreturn memory(none)
; TUNIT-LABEL: define ptr @b64613_b
; TUNIT-SAME: (ptr nofree noundef [[P:%.*]], i32 [[I:%.*]]) #[[ATTR11]] {
-; TUNIT-NEXT: [[P_ADDR:%.*]] = alloca <2 x ptr>, align 1
-; TUNIT-NEXT: [[G:%.*]] = getelementptr i8, ptr [[P_ADDR]], i32 [[I]]
+; TUNIT-NEXT: [[P_ADDR1:%.*]] = alloca [8 x i8], align 1
+; TUNIT-NEXT: [[G:%.*]] = getelementptr i8, ptr [[P_ADDR1]], i32 [[I]]
; TUNIT-NEXT: store ptr [[P]], ptr [[G]], align 1
-; TUNIT-NEXT: [[R:%.*]] = load ptr, ptr [[P_ADDR]], align 1
+; TUNIT-NEXT: [[R:%.*]] = load ptr, ptr [[P_ADDR1]], align 1
; TUNIT-NEXT: ret ptr [[R]]
;
; CGSCC: Function Attrs: mustprogress nofree norecurse nosync nounwind willreturn memory(none)
; CGSCC-LABEL: define ptr @b64613_b
; CGSCC-SAME: (ptr nofree noundef [[P:%.*]], i32 [[I:%.*]]) #[[ATTR12]] {
-; CGSCC-NEXT: [[P_ADDR:%.*]] = alloca <2 x ptr>, align 1
-; CGSCC-NEXT: [[G:%.*]] = getelementptr i8, ptr [[P_ADDR]], i32 [[I]]
+; CGSCC-NEXT: [[P_ADDR1:%.*]] = alloca [8 x i8], align 1
+; CGSCC-NEXT: [[G:%.*]] = getelementptr i8, ptr [[P_ADDR1]], i32 [[I]]
; CGSCC-NEXT: store ptr [[P]], ptr [[G]], align 1
-; CGSCC-NEXT: [[R:%.*]] = load ptr, ptr [[P_ADDR]], align 1
+; CGSCC-NEXT: [[R:%.*]] = load ptr, ptr [[P_ADDR1]], align 1
; CGSCC-NEXT: ret ptr [[R]]
;
%p.addr = alloca <2 x ptr>, align 1
@@ -782,16 +782,16 @@ define void @b64613_positive(ptr noundef %p, i32 %i) {
; TUNIT: Function Attrs: mustprogress nofree norecurse nosync nounwind willreturn memory(none)
; TUNIT-LABEL: define void @b64613_positive
; TUNIT-SAME: (ptr nocapture nofree noundef [[P:%.*]], i32 [[I:%.*]]) #[[ATTR11]] {
-; TUNIT-NEXT: [[P_ADDR:%.*]] = alloca <2 x ptr>, align 1
-; TUNIT-NEXT: [[G:%.*]] = getelementptr i8, ptr [[P_ADDR]], i32 [[I]]
+; TUNIT-NEXT: [[P_ADDR1:%.*]] = alloca [8 x i8], align 1
+; TUNIT-NEXT: [[G:%.*]] = getelementptr i8, ptr [[P_ADDR1]], i32 [[I]]
; TUNIT-NEXT: store ptr [[P]], ptr [[G]], align 1
; TUNIT-NEXT: ret void
;
; CGSCC: Function Attrs: mustprogress nofree nosync nounwind willreturn memory(none)
; CGSCC-LABEL: define void @b64613_positive
; CGSCC-SAME: (ptr nocapture nofree noundef [[P:%.*]], i32 [[I:%.*]]) #[[ATTR13:[0-9]+]] {
-; CGSCC-NEXT: [[P_ADDR:%.*]] = alloca <2 x ptr>, align 1
-; CGSCC-NEXT: [[G:%.*]] = getelementptr i8, ptr [[P_ADDR]], i32 [[I]]
+; CGSCC-NEXT: [[P_ADDR1:%.*]] = alloca [8 x i8], align 1
+; CGSCC-NEXT: [[G:%.*]] = getelementptr i8, ptr [[P_ADDR1]], i32 [[I]]
; CGSCC-NEXT: store ptr [[P]], ptr [[G]], align 1
; CGSCC-NEXT: ret void
;
diff --git a/llvm/test/Transforms/Attributor/nodelete.ll b/llvm/test/Transforms/Attributor/nodelete.ll
index c28cb28379348..a865708cda06b 100644
--- a/llvm/test/Transforms/Attributor/nodelete.ll
+++ b/llvm/test/Transforms/Attributor/nodelete.ll
@@ -10,7 +10,7 @@ define hidden i64 @f1() align 2 {
; TUNIT-LABEL: define {{[^@]+}}@f1
; TUNIT-SAME: () #[[ATTR0:[0-9]+]] align 2 {
; TUNIT-NEXT: entry:
-; TUNIT-NEXT: [[REF_TMP1:%.*]] = alloca i8, i32 0, align 8
+; TUNIT-NEXT: [[REF_TMP1:%.*]] = alloca [0 x i8], align 1
; TUNIT-NEXT: ret i64 undef
;
; CGSCC: Function Attrs: mustprogress nofree nosync nounwind willreturn memory(none)
@@ -18,7 +18,7 @@ define hidden i64 @f1() align 2 {
; CGSCC-SAME: () #[[ATTR0:[0-9]+]] align 2 {
; CGSCC-NEXT: entry:
; CGSCC-NEXT: [[REF_TMP:%.*]] = alloca [[A:%.*]], align 8
-; CGSCC-NEXT: [[REF_TMP1:%.*]] = alloca i8, i32 0, align 8
+; CGSCC-NEXT: [[REF_TMP1:%.*]] = alloca [0 x i8], align 1
; CGSCC-NEXT: [[CALL2:%.*]] = call i64 @f2() #[[ATTR2:[0-9]+]]
; CGSCC-NEXT: ret i64 [[CALL2]]
;
diff --git a/llvm/test/Transforms/Attributor/nofpclass.ll b/llvm/test/Transforms/Attributor/nofpclass.ll
index b38f9bae50ccc..507111e610138 100644
--- a/llvm/test/Transforms/Attributor/nofpclass.ll
+++ b/llvm/test/Transforms/Attributor/nofpclass.ll
@@ -1,4 +1,4 @@
-; NOTE: Assertions have been autogenerated by utils/update_test_checks.py UTC_ARGS: --check-attributes --version 2
+; 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
@@ -2689,3 +2689,51 @@ attributes #2 = { "denormal-fp-math"="ieee,preserve-sign" }
attributes #3 = { "denormal-fp-math"="positive-zero,positive-zero" }
attributes #4 = { "denormal-fp-math"="positive-zero,ieee" }
attributes #5 = { "denormal-fp-math"="ieee,positive-zero" }
+;.
+; TUNIT: attributes #[[ATTR0:[0-9]+]] = { nocallback nofree nosync nounwind willreturn memory(inaccessiblemem: write) }
+; TUNIT: attributes #[[ATTR1:[0-9]+]] = { nocallback nofree nosync nounwind speculatable willreturn memory(none) }
+; TUNIT: attributes #[[ATTR2:[0-9]+]] = { nocallback nofree nosync nounwind strictfp willreturn memory(inaccessiblemem: readwrite) }
+; TUNIT: attributes #[[ATTR3]] = { mustprogress nofree norecurse nosync nounwind willreturn memory(none) }
+; TUNIT: attributes #[[ATTR4]] = { mustprogress nofree nosync nounwind willreturn memory(none) }
+; TUNIT: attributes #[[ATTR5]] = { mustprogress nofree norecurse nosync nounwind willreturn memory(argmem: read) }
+; TUNIT: attributes #[[ATTR6]] = { mustprogress nofree norecurse nounwind willreturn memory(argmem: readwrite) }
+; TUNIT: attributes #[[ATTR7]] = { mustprogress nofree norecurse nosync nounwind willreturn memory(argmem: readwrite) }
+; TUNIT: attributes #[[ATTR8]] = { mustprogress nofree norecurse nosync nounwind strictfp willreturn memory(inaccessiblemem: readwrite) }
+; TUNIT: attributes #[[ATTR9]] = { mustprogress nofree norecurse nosync nounwind willreturn memory(none) "denormal-fp-math"="positive-zero,positive-zero" }
+; TUNIT: attributes #[[ATTR10]] = { mustprogress nofree norecurse nosync nounwind willreturn memory(none) "denormal-fp-math"="preserve-sign,preserve-sign" }
+; TUNIT: attributes #[[ATTR11]] = { mustprogress nofree norecurse nosync nounwind willreturn memory(none) "denormal-fp-math"="ieee,preserve-sign" }
+; TUNIT: attributes #[[ATTR12]] = { mustprogress nofree norecurse nosync nounwind willreturn memory(none) "denormal-fp-math"="positive-zero,ieee" }
+; TUNIT: attributes #[[ATTR13]] = { mustprogress nofree norecurse nosync nounwind willreturn memory(none) "denormal-fp-math"="preserve-sign,ieee" }
+; TUNIT: attributes #[[ATTR14]] = { mustprogress nofree norecurse nosync nounwind willreturn memory(none) "denormal-fp-math"="ieee,positive-zero" }
+; TUNIT: attributes #[[ATTR15]] = { memory(readwrite, argmem: none) }
+; TUNIT: attributes #[[ATTR16]] = { norecurse }
+; TUNIT: attributes #[[ATTR17]] = { nounwind willreturn }
+; TUNIT: attributes #[[ATTR18]] = { nofree willreturn memory(write) }
+; TUNIT: attributes #[[ATTR19]] = { nofree nosync nounwind willreturn memory(none) }
+; TUNIT: attributes #[[ATTR20]] = { nofree willreturn }
+; TUNIT: attributes #[[ATTR21]] = { nofree nosync nounwind willreturn memory(read) }
+; TUNIT: attributes #[[ATTR22]] = { nofree nosync willreturn }
+;.
+; CGSCC: attributes #[[ATTR0:[0-9]+]] = { nocallback nofree nosync nounwind willreturn memory(inaccessiblemem: write) }
+; CGSCC: attributes #[[ATTR1:[0-9]+]] = { nocallback nofree nosync nounwind speculatable willreturn memory(none) }
+; CGSCC: attributes #[[ATTR2:[0-9]+]] = { nocallback nofree nosync nounwind strictfp willreturn memory(inaccessiblemem: readwrite) }
+; CGSCC: attributes #[[ATTR3]] = { mustprogress nofree norecurse nosync nounwind willreturn memory(none) }
+; CGSCC: attributes #[[ATTR4]] = { mustprogress nofree nosync nounwind willreturn memory(none) }
+; CGSCC: attributes #[[ATTR5]] = { mustprogress nofree norecurse nosync nounwind willreturn memory(argmem: read) }
+; CGSCC: attributes #[[ATTR6]] = { mustprogress nofree norecurse nounwind willreturn memory(argmem: readwrite) }
+; CGSCC: attributes #[[ATTR7]] = { mustprogress nofree norecurse nosync nounwind willreturn memory(argmem: readwrite) }
+; CGSCC: attributes #[[ATTR8]] = { mustprogress nofree norecurse nosync nounwind strictfp willreturn memory(inaccessiblemem: readwrite) }
+; CGSCC: attributes #[[ATTR9]] = { mustprogress nofree norecurse nosync nounwind willreturn memory(none) "denormal-fp-math"="positive-zero,positive-zero" }
+; CGSCC: attributes #[[ATTR10]] = { mustprogress nofree norecurse nosync nounwind willreturn memory(none) "denormal-fp-math"="preserve-sign,preserve-sign" }
+; CGSCC: attributes #[[ATTR11]] = { mustprogress nofree norecurse nosync nounwind willreturn memory(none) "denormal-fp-math"="ieee,preserve-sign" }
+; CGSCC: attributes #[[ATTR12]] = { mustprogress nofree norecurse nosync nounwind willreturn memory(none) "denormal-fp-math"="positive-zero,ieee" }
+; CGSCC: attributes #[[ATTR13]] = { mustprogress nofree norecurse nosync nounwind willreturn memory(none) "denormal-fp-math"="preserve-sign,ieee" }
+; CGSCC: attributes #[[ATTR14]] = { mustprogress nofree norecurse nosync nounwind willreturn memory(none) "denormal-fp-math"="ieee,positive-zero" }
+; CGSCC: attributes #[[ATTR15]] = { memory(readwrite, argmem: none) }
+; CGSCC: attributes #[[ATTR16]] = { norecurse }
+; CGSCC: attributes #[[ATTR17]] = { nounwind willreturn }
+; CGSCC: attributes #[[ATTR18]] = { nofree willreturn memory(write) }
+; CGSCC: attributes #[[ATTR19]] = { nofree nosync willreturn }
+; CGSCC: attributes #[[ATTR20]] = { nofree willreturn }
+; CGSCC: attributes #[[ATTR21]] = { nofree willreturn memory(read) }
+;.
diff --git a/llvm/test/Transforms/Attributor/pointer-info.ll b/llvm/test/Transforms/Attributor/pointer-info.ll
index 6afdbdaee317c..c8fec4f1de7b4 100644
--- a/llvm/test/Transforms/Attributor/pointer-info.ll
+++ b/llvm/test/Transforms/Attributor/pointer-info.ll
@@ -10,10 +10,12 @@ define void @foo(ptr %ptr) {
; TUNIT-LABEL: define {{[^@]+}}@foo
; TUNIT-SAME: (ptr nocapture nofree readnone [[PTR:%.*]]) #[[ATTR0:[0-9]+]] {
; TUNIT-NEXT: entry:
-; TUNIT-NEXT: [[TMP0:%.*]] = alloca [[STRUCT_TEST_A:%.*]], align 8
+; TUNIT-NEXT: [[TMP0:%.*]] = alloca [8 x i8], align 1
; TUNIT-NEXT: br label [[CALL_BR:%.*]]
; TUNIT: call.br:
-; TUNIT-NEXT: [[TMP1:%.*]] = getelementptr inbounds [[STRUCT_TEST_A]], ptr [[TMP0]], i64 0, i32 2
+; TUNIT-NEXT: [[TMP1:%.*]] = getelementptr inbounds [[STRUCT_TEST_A:%.*]], ptr [[TMP0]], i64 0, i32 2
+; TUNIT-NEXT: [[NEWGEP:%.*]] = getelementptr ptr, ptr [[TMP1]], i64 -16
+; TUNIT-NEXT: store ptr [[PTR]], ptr [[NEWGEP]], align 8
; TUNIT-NEXT: tail call void @bar(ptr noalias nocapture nofree noundef nonnull readonly byval([[STRUCT_TEST_A]]) align 8 dereferenceable(24) [[TMP0]]) #[[ATTR2:[0-9]+]]
; TUNIT-NEXT: ret void
;
diff --git a/llvm/test/Transforms/Attributor/value-simplify-local-remote.ll b/llvm/test/Transforms/Attributor/value-simplify-local-remote.ll
index 20b52c3fcd85a..9ff51e97d6e15 100644
--- a/llvm/test/Transforms/Attributor/value-simplify-local-remote.ll
+++ b/llvm/test/Transforms/Attributor/value-simplify-local-remote.ll
@@ -106,7 +106,7 @@ define ptr @t2(ptr %this, ptr %this.addr, ptr %this1) {
; TUNIT-SAME: (ptr nofree noundef nonnull align 8 dereferenceable(8) [[THIS:%.*]], ptr nocapture nofree readnone [[THIS_ADDR:%.*]], ptr nocapture nofree readnone [[THIS1:%.*]]) #[[ATTR1:[0-9]+]] {
; TUNIT-NEXT: entry:
; TUNIT-NEXT: store ptr [[THIS]], ptr [[THIS]], align 8
-; TUNIT-NEXT: [[CALL:%.*]] = call [[S:%.*]] @foo.1(ptr nofree noundef nonnull align 8 dereferenceable(8) [[THIS]]) #[[ATTR4:[0-9]+]]
+; TUNIT-NEXT: [[CALL:%.*]] = call [[S:%.*]] @[[FOO_1:[a-zA-Z0-9_$\"\\.-]*[a-zA-Z_$\"\\.-][a-zA-Z0-9_$\"\\.-]*]](ptr nofree noundef nonnull align 8 dereferenceable(8) [[THIS]]) #[[ATTR4:[0-9]+]]
; TUNIT-NEXT: [[TEST_RET:%.*]] = extractvalue [[S]] [[CALL]], 0
; TUNIT-NEXT: ret ptr [[TEST_RET]]
;
@@ -115,7 +115,7 @@ define ptr @t2(ptr %this, ptr %this.addr, ptr %this1) {
; CGSCC-SAME: (ptr nofree noundef nonnull align 8 dereferenceable(8) [[THIS:%.*]], ptr nocapture nofree readnone [[THIS_ADDR:%.*]], ptr nocapture nofree readnone [[THIS1:%.*]]) #[[ATTR2:[0-9]+]] {
; CGSCC-NEXT: entry:
; CGSCC-NEXT: store ptr [[THIS]], ptr [[THIS]], align 8
-; CGSCC-NEXT: [[CALL:%.*]] = call [[S:%.*]] @foo.1(ptr nofree noundef nonnull align 8 dereferenceable(8) [[THIS]]) #[[ATTR8:[0-9]+]]
+; CGSCC-NEXT: [[CALL:%.*]] = call [[S:%.*]] @[[FOO_1:[a-zA-Z0-9_$\"\\.-]*[a-zA-Z_$\"\\.-][a-zA-Z0-9_$\"\\.-]*]](ptr nofree noundef nonnull align 8 dereferenceable(8) [[THIS]]) #[[ATTR8:[0-9]+]]
; CGSCC-NEXT: [[TEST_RET:%.*]] = extractvalue [[S]] [[CALL]], 0
; CGSCC-NEXT: ret ptr [[TEST_RET]]
;
@@ -205,7 +205,7 @@ define ptr @foo(ptr %this, ptr %this.addr, ptr %this1) {
; TUNIT-SAME: (ptr nofree noundef nonnull align 8 dereferenceable(8) [[THIS:%.*]], ptr nocapture nofree readnone [[THIS_ADDR:%.*]], ptr nocapture nofree readnone [[THIS1:%.*]]) #[[ATTR1]] {
; TUNIT-NEXT: entry:
; TUNIT-NEXT: store ptr [[THIS]], ptr [[THIS]], align 8
-; TUNIT-NEXT: [[CALL:%.*]] = call [[S:%.*]] @bar.5(ptr nofree noundef nonnull align 8 dereferenceable(8) [[THIS]]) #[[ATTR4]]
+; TUNIT-NEXT: [[CALL:%.*]] = call [[S:%.*]] @[[BAR_5:[a-zA-Z0-9_$\"\\.-]*[a-zA-Z_$\"\\.-][a-zA-Z0-9_$\"\\.-]*]](ptr nofree noundef nonnull align 8 dereferenceable(8) [[THIS]]) #[[ATTR4]]
; TUNIT-NEXT: [[FOO_RET:%.*]] = extractvalue [[S]] [[CALL]], 0
; TUNIT-NEXT: ret ptr [[FOO_RET]]
;
@@ -214,7 +214,7 @@ define ptr @foo(ptr %this, ptr %this.addr, ptr %this1) {
; CGSCC-SAME: (ptr nofree noundef nonnull align 8 dereferenceable(8) [[THIS:%.*]], ptr nocapture nofree readnone [[THIS_ADDR:%.*]], ptr nocapture nofree readnone [[THIS1:%.*]]) #[[ATTR2]] {
; CGSCC-NEXT: entry:
; CGSCC-NEXT: store ptr [[THIS]], ptr [[THIS]], align 8
-; CGSCC-NEXT: [[CALL:%.*]] = call [[S:%.*]] @bar.5(ptr nofree noundef nonnull align 8 dereferenceable(8) [[THIS]]) #[[ATTR8]]
+; CGSCC-NEXT: [[CALL:%.*]] = call [[S:%.*]] @[[BAR_5:[a-zA-Z0-9_$\"\\.-]*[a-zA-Z_$\"\\.-][a-zA-Z0-9_$\"\\.-]*]](ptr nofree noundef nonnull align 8 dereferenceable(8) [[THIS]]) #[[ATTR8]]
; CGSCC-NEXT: [[FOO_RET:%.*]] = extractvalue [[S]] [[CALL]], 0
; CGSCC-NEXT: ret ptr [[FOO_RET]]
;
@@ -317,7 +317,7 @@ define weak_odr void @t3() {
; CHECK: for.cond:
; CHECK-NEXT: br label [[FOR_BODY:%.*]]
; CHECK: for.body:
-; CHECK-NEXT: [[CALL4:%.*]] = call [[S_2:%.*]] @t3.helper()
+; CHECK-NEXT: [[CALL4:%.*]] = call [[S_2:%.*]] @[[T3_HELPER:[a-zA-Z0-9_$\"\\.-]*[a-zA-Z_$\"\\.-][a-zA-Z0-9_$\"\\.-]*]]()
; CHECK-NEXT: ret void
;
entry:
@@ -380,8 +380,8 @@ define dso_local void @spam() {
; 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 @@ define dso_local void @spam() {
; 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:
@@ -467,7 +467,7 @@ define double @t4(ptr %this, ptr %this.addr, ptr %this1) {
; TUNIT-NEXT: entry:
; TUNIT-NEXT: [[THIS_ADDR1:%.*]] = alloca ptr, i32 0, align 8
; TUNIT-NEXT: store ptr [[THIS]], ptr [[THIS]], align 8
-; TUNIT-NEXT: [[CALL:%.*]] = call [[S:%.*]] @t4a(ptr nofree noundef nonnull writeonly align 8 dereferenceable(8) [[THIS]]) #[[ATTR5]]
+; TUNIT-NEXT: [[CALL:%.*]] = call [[S:%.*]] @[[T4A:[a-zA-Z0-9_$\"\\.-]*[a-zA-Z_$\"\\.-][a-zA-Z0-9_$\"\\.-]*]](ptr nofree noundef nonnull writeonly align 8 dereferenceable(8) [[THIS]]) #[[ATTR5]]
; TUNIT-NEXT: ret double 0.000000e+00
;
; CGSCC: Function Attrs: mustprogress nofree nosync nounwind willreturn memory(argmem: readwrite)
@@ -476,7 +476,7 @@ define double @t4(ptr %this, ptr %this.addr, ptr %this1) {
; CGSCC-NEXT: entry:
; CGSCC-NEXT: [[THIS_ADDR1:%.*]] = alloca ptr, i32 0, align 8
; CGSCC-NEXT: store ptr [[THIS]], ptr [[THIS]], align 8
-; CGSCC-NEXT: [[CALL:%.*]] = call [[S:%.*]] @t4a(ptr nofree noundef nonnull align 8 dereferenceable(8) [[THIS]]) #[[ATTR8]]
+; CGSCC-NEXT: [[CALL:%.*]] = call [[S:%.*]] @[[T4A:[a-zA-Z0-9_$\"\\.-]*[a-zA-Z_$\"\\.-][a-zA-Z0-9_$\"\\.-]*]](ptr nofree noundef nonnull align 8 dereferenceable(8) [[THIS]]) #[[ATTR8]]
; CGSCC-NEXT: [[TMP0:%.*]] = extractvalue [[S]] [[CALL]], 0
; CGSCC-NEXT: ret double 0.000000e+00
;
@@ -615,12 +615,21 @@ entry:
; CGSCC: attributes #[[ATTR8]] = { nofree nounwind willreturn }
; CGSCC: attributes #[[ATTR9]] = { nofree nounwind willreturn memory(readwrite) }
;.
-; CHECK: [[META0:![0-9]+]] = !{i32 2, !"SDK Version", [2 x i32] [i32 11, i32 5]}
-; CHECK: [[META1:![0-9]+]] = !{i32 1, !"wchar_size", i32 4}
-; CHECK: [[META2:![0-9]+]] = !{i32 7, !"openmp", i32 50}
-; CHECK: [[META3:![0-9]+]] = !{i32 7, !"openmp-device", i32 50}
-; CHECK: [[META4:![0-9]+]] = !{i32 8, !"PIC Level", i32 2}
-; CHECK: [[META5:![0-9]+]] = !{i32 7, !"frame-pointer", i32 2}
-; CHECK: [[META6:![0-9]+]] = !{i32 7, !"Dwarf Version", i32 2}
-; CHECK: [[META7:![0-9]+]] = !{i32 2, !"Debug Info Version", i32 3}
+; TUNIT: [[META0:![0-9]+]] = !{i32 2, !"SDK Version", [2 x i32] [i32 11, i32 5]}
+; TUNIT: [[META1:![0-9]+]] = !{i32 1, !"wchar_size", i32 4}
+; TUNIT: [[META2:![0-9]+]] = !{i32 7, !"openmp", i32 50}
+; TUNIT: [[META3:![0-9]+]] = !{i32 7, !"openmp-device", i32 50}
+; TUNIT: [[META4:![0-9]+]] = !{i32 8, !"PIC Level", i32 2}
+; TUNIT: [[META5:![0-9]+]] = !{i32 7, !"frame-pointer", i32 2}
+; TUNIT: [[META6:![0-9]+]] = !{i32 7, !"Dwarf Version", i32 2}
+; TUNIT: [[META7:![0-9]+]] = !{i32 2, !"Debug Info Version", i32 3}
+;.
+; CGSCC: [[META0:![0-9]+]] = !{i32 2, !"SDK Version", [2 x i32] [i32 11, i32 5]}
+; CGSCC: [[META1:![0-9]+]] = !{i32 1, !"wchar_size", i32 4}
+; CGSCC: [[META2:![0-9]+]] = !{i32 7, !"openmp", i32 50}
+; CGSCC: [[META3:![0-9]+]] = !{i32 7, !"openmp-device", i32 50}
+; CGSCC: [[META4:![0-9]+]] = !{i32 8, !"PIC Level", i32 2}
+; CGSCC: [[META5:![0-9]+]] = !{i32 7, !"frame-pointer", i32 2}
+; CGSCC: [[META6:![0-9]+]] = !{i32 7, !"Dwarf Version", i32 2}
+; CGSCC: [[META7:![0-9]+]] = !{i32 2, !"Debug Info Version", i32 3}
;.
diff --git a/llvm/test/Transforms/Attributor/value-simplify-pointer-info-vec.ll b/llvm/test/Transforms/Attributor/value-simplify-pointer-info-vec.ll
index 70793ec5c7f83..c07b8f9a3efe8 100644
--- a/llvm/test/Transforms/Attributor/value-simplify-pointer-info-vec.ll
+++ b/llvm/test/Transforms/Attributor/value-simplify-pointer-info-vec.ll
@@ -83,6 +83,12 @@ define i32 @vec_write_4() {
; CHECK: Function Attrs: mustprogress nofree norecurse nosync nounwind willreturn memory(none)
; CHECK-LABEL: define {{[^@]+}}@vec_write_4
; CHECK-SAME: () #[[ATTR0]] {
+; CHECK-NEXT: [[A1:%.*]] = alloca [12 x i8], align 1
+; CHECK-NEXT: [[NEWGEP:%.*]] = getelementptr ptr, ptr [[A1]], i64 4
+; CHECK-NEXT: store i32 3, ptr [[NEWGEP]], align 16
+; CHECK-NEXT: [[G:%.*]] = getelementptr i32, ptr [[A1]], i64 1
+; CHECK-NEXT: [[NEWGEP2:%.*]] = getelementptr ptr, ptr [[G]], i64 -4
+; CHECK-NEXT: store <2 x i32> <i32 5, i32 5>, ptr [[NEWGEP2]], align 8
; CHECK-NEXT: ret i32 13
;
%a = alloca <4 x i32>
@@ -101,8 +107,12 @@ define i32 @vec_write_5(i32 %arg) {
; CHECK: Function Attrs: mustprogress nofree norecurse nosync nounwind willreturn memory(none)
; CHECK-LABEL: define {{[^@]+}}@vec_write_5
; CHECK-SAME: (i32 [[ARG:%.*]]) #[[ATTR0]] {
-; CHECK-NEXT: [[A:%.*]] = alloca <4 x i32>, align 16
-; CHECK-NEXT: store i32 [[ARG]], ptr [[A]], align 16
+; CHECK-NEXT: [[A1:%.*]] = alloca [12 x i8], align 1
+; CHECK-NEXT: [[NEWGEP2:%.*]] = getelementptr ptr, ptr [[A1]], i64 4
+; CHECK-NEXT: store i32 [[ARG]], ptr [[NEWGEP2]], align 16
+; CHECK-NEXT: [[G:%.*]] = getelementptr i32, ptr [[A1]], i64 1
+; CHECK-NEXT: [[NEWGEP:%.*]] = getelementptr ptr, ptr [[G]], i64 -4
+; CHECK-NEXT: store <2 x i32> <i32 5, i32 5>, ptr [[NEWGEP]], align 8
; CHECK-NEXT: [[ADD1:%.*]] = add i32 [[ARG]], 5
; CHECK-NEXT: [[ADD2:%.*]] = add i32 5, [[ADD1]]
; CHECK-NEXT: ret i32 [[ADD2]]
diff --git a/llvm/test/Transforms/Attributor/value-simplify-pointer-info.ll b/llvm/test/Transforms/Attributor/value-simplify-pointer-info.ll
index 7a35b5c856097..95b0d719ffc55 100644
--- a/llvm/test/Transforms/Attributor/value-simplify-pointer-info.ll
+++ b/llvm/test/Transforms/Attributor/value-simplify-pointer-info.ll
@@ -259,8 +259,8 @@ define void @local_alloca_simplifiable_2() {
; TUNIT-LABEL: define {{[^@]+}}@local_alloca_simplifiable_2
; TUNIT-SAME: () #[[ATTR3:[0-9]+]] {
; TUNIT-NEXT: entry:
-; TUNIT-NEXT: [[BYTES:%.*]] = alloca [1024 x i8], align 16
-; TUNIT-NEXT: call void @llvm.lifetime.start.p0(i64 noundef 1024, ptr noalias nocapture nofree noundef nonnull align 16 dereferenceable(1024) [[BYTES]]) #[[ATTR17]]
+; TUNIT-NEXT: [[BYTES1:%.*]] = alloca [6 x i8], align 1
+; TUNIT-NEXT: call void @llvm.lifetime.start.p0(i64 noundef 1024, ptr noalias nocapture nofree noundef nonnull align 16 dereferenceable(1024) [[BYTES1]]) #[[ATTR17]]
; TUNIT-NEXT: br label [[FOR_COND:%.*]]
; TUNIT: for.cond:
; TUNIT-NEXT: [[INDVARS_IV:%.*]] = phi i64 [ [[INDVARS_IV_NEXT:%.*]], [[FOR_INC:%.*]] ], [ 0, [[ENTRY:%.*]] ]
@@ -270,7 +270,7 @@ define void @local_alloca_simplifiable_2() {
; TUNIT-NEXT: br label [[FOR_END:%.*]]
; TUNIT: for.body:
; TUNIT-NEXT: [[I15:%.*]] = mul nuw nsw i64 [[INDVARS_IV]], 10
-; TUNIT-NEXT: [[ARRAYIDX:%.*]] = getelementptr inbounds [1024 x i8], ptr [[BYTES]], i64 0, i64 [[I15]]
+; TUNIT-NEXT: [[ARRAYIDX:%.*]] = getelementptr inbounds [1024 x i8], ptr [[BYTES1]], i64 0, i64 [[I15]]
; TUNIT-NEXT: br label [[FOR_INC]]
; TUNIT: for.inc:
; TUNIT-NEXT: [[INDVARS_IV_NEXT]] = add nuw nsw i64 [[INDVARS_IV]], 1
@@ -286,7 +286,7 @@ define void @local_alloca_simplifiable_2() {
; TUNIT: for.body5:
; TUNIT-NEXT: [[I17:%.*]] = mul nuw nsw i64 [[INDVARS_IV2]], 10
; TUNIT-NEXT: [[I18:%.*]] = or i64 [[I17]], 1
-; TUNIT-NEXT: [[ARRAYIDX8:%.*]] = getelementptr inbounds float, ptr [[BYTES]], i64 [[I18]]
+; TUNIT-NEXT: [[ARRAYIDX8:%.*]] = getelementptr inbounds float, ptr [[BYTES1]], i64 [[I18]]
; TUNIT-NEXT: br label [[FOR_INC9]]
; TUNIT: for.inc9:
; TUNIT-NEXT: [[INDVARS_IV_NEXT3]] = add nuw nsw i64 [[INDVARS_IV2]], 1
@@ -302,14 +302,16 @@ define void @local_alloca_simplifiable_2() {
; TUNIT: for.body16:
; TUNIT-NEXT: [[I20:%.*]] = mul nuw nsw i64 [[INDVARS_IV7]], 10
; TUNIT-NEXT: [[I21:%.*]] = add nuw nsw i64 [[I20]], 2
-; TUNIT-NEXT: [[ARRAYIDX21:%.*]] = getelementptr inbounds i64, ptr [[BYTES]], i64 [[I21]]
+; TUNIT-NEXT: [[ARRAYIDX21:%.*]] = getelementptr inbounds i64, ptr [[BYTES1]], i64 [[I21]]
; TUNIT-NEXT: br label [[FOR_INC22]]
; TUNIT: for.inc22:
; TUNIT-NEXT: [[INDVARS_IV_NEXT8]] = add nuw nsw i64 [[INDVARS_IV7]], 1
; TUNIT-NEXT: br label [[FOR_COND13]], !llvm.loop [[LOOP18:![0-9]+]]
; TUNIT: for.end24:
-; TUNIT-NEXT: [[ARRAYIDX25:%.*]] = getelementptr inbounds [1024 x i8], ptr [[BYTES]], i64 0, i64 1023
-; TUNIT-NEXT: [[ARRAYIDX26:%.*]] = getelementptr inbounds [1024 x i8], ptr [[BYTES]], i64 0, i64 500
+; TUNIT-NEXT: [[ARRAYIDX25:%.*]] = getelementptr inbounds [1024 x i8], ptr [[BYTES1]], i64 0, i64 1023
+; TUNIT-NEXT: [[NEWGEP:%.*]] = getelementptr ptr, ptr [[ARRAYIDX25]], i64 -1023
+; TUNIT-NEXT: store i8 0, ptr [[NEWGEP]], align 1
+; TUNIT-NEXT: [[ARRAYIDX26:%.*]] = getelementptr inbounds [1024 x i8], ptr [[BYTES1]], i64 0, i64 500
; TUNIT-NEXT: call void @write_arg(ptr nocapture nofree noundef nonnull writeonly align 4 dereferenceable(524) [[ARRAYIDX26]], i32 noundef 0) #[[ATTR18]]
; TUNIT-NEXT: br label [[FOR_COND28:%.*]]
; TUNIT: for.cond28:
@@ -326,7 +328,7 @@ define void @local_alloca_simplifiable_2() {
; TUNIT-NEXT: [[INDVARS_IV_NEXT13]] = add nuw nsw i64 [[INDVARS_IV12]], 1
; TUNIT-NEXT: br label [[FOR_COND28]], !llvm.loop [[LOOP20:![0-9]+]]
; TUNIT: for.end38:
-; TUNIT-NEXT: call void @llvm.lifetime.end.p0(i64 noundef 1024, ptr noalias nocapture nofree noundef nonnull align 16 dereferenceable(1024) [[BYTES]]) #[[ATTR17]]
+; TUNIT-NEXT: call void @llvm.lifetime.end.p0(i64 noundef 1024, ptr noalias nocapture nofree noundef nonnull align 16 dereferenceable(1024) [[BYTES1]]) #[[ATTR17]]
; TUNIT-NEXT: ret void
;
; CGSCC: Function Attrs: mustprogress nofree nosync nounwind willreturn
@@ -1589,38 +1591,38 @@ define i8 @local_alloca_not_simplifiable_2(i64 %index1, i64 %index2, i1 %cnd) {
; TUNIT-LABEL: define {{[^@]+}}@local_alloca_not_simplifiable_2
; TUNIT-SAME: (i64 [[INDEX1:%.*]], i64 [[INDEX2:%.*]], i1 noundef [[CND:%.*]]) #[[ATTR3]] {
; TUNIT-NEXT: entry:
-; TUNIT-NEXT: [[BYTES:%.*]] = alloca [1024 x i8], align 16
-; TUNIT-NEXT: store i8 7, ptr [[BYTES]], align 16
+; TUNIT-NEXT: [[BYTES1:%.*]] = alloca [1 x i8], align 1
+; TUNIT-NEXT: store i8 7, ptr [[BYTES1]], align 16
; TUNIT-NEXT: br i1 [[CND]], label [[LEFT:%.*]], label [[RIGHT:%.*]]
; TUNIT: left:
-; TUNIT-NEXT: [[GEP1:%.*]] = getelementptr inbounds [1024 x i8], ptr [[BYTES]], i64 0, i64 [[INDEX1]]
+; TUNIT-NEXT: [[GEP1:%.*]] = getelementptr inbounds [1024 x i8], ptr [[BYTES1]], i64 0, i64 [[INDEX1]]
; TUNIT-NEXT: br label [[JOIN:%.*]]
; TUNIT: right:
-; TUNIT-NEXT: [[GEP2:%.*]] = getelementptr inbounds [1024 x i8], ptr [[BYTES]], i64 0, i64 [[INDEX2]]
+; TUNIT-NEXT: [[GEP2:%.*]] = getelementptr inbounds [1024 x i8], ptr [[BYTES1]], i64 0, i64 [[INDEX2]]
; TUNIT-NEXT: br label [[JOIN]]
; TUNIT: join:
; TUNIT-NEXT: [[GEP_JOIN:%.*]] = phi ptr [ [[GEP1]], [[LEFT]] ], [ [[GEP2]], [[RIGHT]] ]
; TUNIT-NEXT: store i8 9, ptr [[GEP_JOIN]], align 4
-; TUNIT-NEXT: [[I:%.*]] = load i8, ptr [[BYTES]], align 16
+; TUNIT-NEXT: [[I:%.*]] = load i8, ptr [[BYTES1]], align 16
; TUNIT-NEXT: ret i8 [[I]]
;
; CGSCC: Function Attrs: mustprogress nofree norecurse nosync nounwind willreturn
; CGSCC-LABEL: define {{[^@]+}}@local_alloca_not_simplifiable_2
; CGSCC-SAME: (i64 [[INDEX1:%.*]], i64 [[INDEX2:%.*]], i1 noundef [[CND:%.*]]) #[[ATTR5]] {
; CGSCC-NEXT: entry:
-; CGSCC-NEXT: [[BYTES:%.*]] = alloca [1024 x i8], align 16
-; CGSCC-NEXT: store i8 7, ptr [[BYTES]], align 16
+; CGSCC-NEXT: [[BYTES1:%.*]] = alloca [1 x i8], align 1
+; CGSCC-NEXT: store i8 7, ptr [[BYTES1]], align 16
; CGSCC-NEXT: br i1 [[CND]], label [[LEFT:%.*]], label [[RIGHT:%.*]]
; CGSCC: left:
-; CGSCC-NEXT: [[GEP1:%.*]] = getelementptr inbounds [1024 x i8], ptr [[BYTES]], i64 0, i64 [[INDEX1]]
+; CGSCC-NEXT: [[GEP1:%.*]] = getelementptr inbounds [1024 x i8], ptr [[BYTES1]], i64 0, i64 [[INDEX1]]
; CGSCC-NEXT: br label [[JOIN:%.*]]
; CGSCC: right:
-; CGSCC-NEXT: [[GEP2:%.*]] = getelementptr inbounds [1024 x i8], ptr [[BYTES]], i64 0, i64 [[INDEX2]]
+; CGSCC-NEXT: [[GEP2:%.*]] = getelementptr inbounds [1024 x i8], ptr [[BYTES1]], i64 0, i64 [[INDEX2]]
; CGSCC-NEXT: br label [[JOIN]]
; CGSCC: join:
; CGSCC-NEXT: [[GEP_JOIN:%.*]] = phi ptr [ [[GEP1]], [[LEFT]] ], [ [[GEP2]], [[RIGHT]] ]
; CGSCC-NEXT: store i8 9, ptr [[GEP_JOIN]], align 4
-; CGSCC-NEXT: [[I:%.*]] = load i8, ptr [[BYTES]], align 16
+; CGSCC-NEXT: [[I:%.*]] = load i8, ptr [[BYTES1]], align 16
; CGSCC-NEXT: ret i8 [[I]]
;
entry:
@@ -1648,23 +1650,45 @@ join: ; preds = %right, %left
; We could simplify these if we separate accessed bins wrt. alignment (here mod 4).
define i32 @unknown_access_mixed_simplifiable(i32 %arg1, i32 %arg2) {
-; CHECK: Function Attrs: mustprogress nofree norecurse nosync nounwind willreturn memory(none)
-; CHECK-LABEL: define {{[^@]+}}@unknown_access_mixed_simplifiable
-; CHECK-SAME: (i32 [[ARG1:%.*]], i32 [[ARG2:%.*]]) #[[ATTR4]] {
-; CHECK-NEXT: entry:
-; CHECK-NEXT: [[S:%.*]] = alloca [[STRUCT_S:%.*]], align 4
-; CHECK-NEXT: [[GEP1:%.*]] = getelementptr inbounds [[STRUCT_S]], ptr [[S]], i64 0, i32 2
-; CHECK-NEXT: [[GEP2:%.*]] = getelementptr inbounds i32, ptr [[S]], i32 [[ARG1]]
-; CHECK-NEXT: [[GEP3:%.*]] = getelementptr inbounds i32, ptr [[S]], i32 [[ARG2]]
-; CHECK-NEXT: store i32 7, ptr [[GEP1]], align 4
-; CHECK-NEXT: store i32 7, ptr [[GEP2]], align 4
-; CHECK-NEXT: store i32 7, ptr [[GEP3]], align 4
-; CHECK-NEXT: [[L1:%.*]] = load i32, ptr [[GEP1]], align 4
-; CHECK-NEXT: [[L2:%.*]] = load i32, ptr [[GEP2]], align 4
-; CHECK-NEXT: [[L3:%.*]] = load i32, ptr [[GEP3]], align 4
-; CHECK-NEXT: [[ADD1:%.*]] = add i32 [[L1]], [[L2]]
-; CHECK-NEXT: [[ADD2:%.*]] = add i32 [[ADD1]], [[L3]]
-; CHECK-NEXT: ret i32 [[ADD2]]
+; TUNIT: Function Attrs: mustprogress nofree norecurse nosync nounwind willreturn memory(none)
+; TUNIT-LABEL: define {{[^@]+}}@unknown_access_mixed_simplifiable
+; TUNIT-SAME: (i32 [[ARG1:%.*]], i32 [[ARG2:%.*]]) #[[ATTR4]] {
+; TUNIT-NEXT: entry:
+; TUNIT-NEXT: [[S1:%.*]] = alloca [4 x i8], align 1
+; TUNIT-NEXT: [[GEP1:%.*]] = getelementptr inbounds [[STRUCT_S:%.*]], ptr [[S1]], i64 0, i32 2
+; TUNIT-NEXT: [[GEP2:%.*]] = getelementptr inbounds i32, ptr [[S1]], i32 [[ARG1]]
+; TUNIT-NEXT: [[GEP3:%.*]] = getelementptr inbounds i32, ptr [[S1]], i32 [[ARG2]]
+; TUNIT-NEXT: [[NEWGEP3:%.*]] = getelementptr ptr, ptr [[GEP1]], i64 -8
+; TUNIT-NEXT: store i32 7, ptr [[NEWGEP3]], align 4
+; TUNIT-NEXT: store i32 7, ptr [[GEP2]], align 4
+; TUNIT-NEXT: store i32 7, ptr [[GEP3]], align 4
+; TUNIT-NEXT: [[NEWGEP:%.*]] = getelementptr ptr, ptr [[GEP1]], i64 -8
+; TUNIT-NEXT: [[L12:%.*]] = load i32, ptr [[NEWGEP]], align 4
+; TUNIT-NEXT: [[L2:%.*]] = load i32, ptr [[GEP2]], align 4
+; TUNIT-NEXT: [[L3:%.*]] = load i32, ptr [[GEP3]], align 4
+; TUNIT-NEXT: [[ADD1:%.*]] = add i32 [[L12]], [[L2]]
+; TUNIT-NEXT: [[ADD2:%.*]] = add i32 [[ADD1]], [[L3]]
+; TUNIT-NEXT: ret i32 [[ADD2]]
+;
+; CGSCC: Function Attrs: mustprogress nofree norecurse nosync nounwind willreturn memory(none)
+; CGSCC-LABEL: define {{[^@]+}}@unknown_access_mixed_simplifiable
+; CGSCC-SAME: (i32 [[ARG1:%.*]], i32 [[ARG2:%.*]]) #[[ATTR4]] {
+; CGSCC-NEXT: entry:
+; CGSCC-NEXT: [[S1:%.*]] = alloca [4 x i8], align 1
+; CGSCC-NEXT: [[GEP1:%.*]] = getelementptr inbounds [[STRUCT_S:%.*]], ptr [[S1]], i64 0, i32 2
+; CGSCC-NEXT: [[GEP2:%.*]] = getelementptr inbounds i32, ptr [[S1]], i32 [[ARG1]]
+; CGSCC-NEXT: [[GEP3:%.*]] = getelementptr inbounds i32, ptr [[S1]], i32 [[ARG2]]
+; CGSCC-NEXT: [[NEWGEP:%.*]] = getelementptr ptr, ptr [[GEP1]], i64 -8
+; CGSCC-NEXT: store i32 7, ptr [[NEWGEP]], align 4
+; CGSCC-NEXT: store i32 7, ptr [[GEP2]], align 4
+; CGSCC-NEXT: store i32 7, ptr [[GEP3]], align 4
+; CGSCC-NEXT: [[NEWGEP2:%.*]] = getelementptr ptr, ptr [[GEP1]], i64 -8
+; CGSCC-NEXT: [[L13:%.*]] = load i32, ptr [[NEWGEP2]], align 4
+; CGSCC-NEXT: [[L2:%.*]] = load i32, ptr [[GEP2]], align 4
+; CGSCC-NEXT: [[L3:%.*]] = load i32, ptr [[GEP3]], align 4
+; CGSCC-NEXT: [[ADD1:%.*]] = add i32 [[L13]], [[L2]]
+; CGSCC-NEXT: [[ADD2:%.*]] = add i32 [[ADD1]], [[L3]]
+; CGSCC-NEXT: ret i32 [[ADD2]]
;
entry:
%s = alloca %struct.S, align 4
@@ -1688,20 +1712,22 @@ define i32 @unknown_access_mixed_not_simplifiable(i32 %arg1, i32 %arg2, i32 %arg
; CHECK-LABEL: define {{[^@]+}}@unknown_access_mixed_not_simplifiable
; CHECK-SAME: (i32 [[ARG1:%.*]], i32 [[ARG2:%.*]], i32 [[ARG3:%.*]]) #[[ATTR4]] {
; CHECK-NEXT: entry:
-; CHECK-NEXT: [[S:%.*]] = alloca [[STRUCT_S:%.*]], align 4
-; CHECK-NEXT: [[GEP1:%.*]] = getelementptr inbounds [[STRUCT_S]], ptr [[S]], i64 0, i32 2
-; CHECK-NEXT: [[GEP2:%.*]] = getelementptr inbounds i32, ptr [[S]], i32 [[ARG1]]
-; CHECK-NEXT: [[GEP3:%.*]] = getelementptr inbounds i32, ptr [[S]], i32 [[ARG2]]
-; CHECK-NEXT: [[GEP4:%.*]] = getelementptr inbounds i8, ptr [[S]], i32 [[ARG3]]
-; CHECK-NEXT: store i32 7, ptr [[GEP1]], align 4
+; CHECK-NEXT: [[S1:%.*]] = alloca [4 x i8], align 1
+; CHECK-NEXT: [[GEP1:%.*]] = getelementptr inbounds [[STRUCT_S:%.*]], ptr [[S1]], i64 0, i32 2
+; CHECK-NEXT: [[GEP2:%.*]] = getelementptr inbounds i32, ptr [[S1]], i32 [[ARG1]]
+; CHECK-NEXT: [[GEP3:%.*]] = getelementptr inbounds i32, ptr [[S1]], i32 [[ARG2]]
+; CHECK-NEXT: [[GEP4:%.*]] = getelementptr inbounds i8, ptr [[S1]], i32 [[ARG3]]
+; CHECK-NEXT: [[NEWGEP:%.*]] = getelementptr ptr, ptr [[GEP1]], i64 -8
+; CHECK-NEXT: store i32 7, ptr [[NEWGEP]], align 4
; CHECK-NEXT: store i32 7, ptr [[GEP2]], align 4
; CHECK-NEXT: store i32 7, ptr [[GEP3]], align 4
; CHECK-NEXT: store i32 7, ptr [[GEP4]], align 4
-; CHECK-NEXT: [[L1:%.*]] = load i32, ptr [[GEP1]], align 4
+; CHECK-NEXT: [[NEWGEP2:%.*]] = getelementptr ptr, ptr [[GEP1]], i64 -8
+; CHECK-NEXT: [[L13:%.*]] = load i32, ptr [[NEWGEP2]], align 4
; CHECK-NEXT: [[L2:%.*]] = load i32, ptr [[GEP2]], align 4
; CHECK-NEXT: [[L3:%.*]] = load i32, ptr [[GEP3]], align 4
; CHECK-NEXT: [[L4:%.*]] = load i32, ptr [[GEP4]], align 4
-; CHECK-NEXT: [[ADD1:%.*]] = add i32 [[L1]], [[L2]]
+; CHECK-NEXT: [[ADD1:%.*]] = add i32 [[L13]], [[L2]]
; CHECK-NEXT: [[ADD2:%.*]] = add i32 [[ADD1]], [[L3]]
; CHECK-NEXT: [[ADD3:%.*]] = add i32 [[ADD2]], [[L4]]
; CHECK-NEXT: ret i32 [[ADD3]]
@@ -2666,18 +2692,19 @@ define dso_local void @test_nested_memory(ptr %dst, ptr %src) {
; TUNIT-SAME: (ptr nocapture nofree writeonly [[DST:%.*]], ptr nocapture nofree readonly [[SRC:%.*]]) {
; TUNIT-NEXT: entry:
; TUNIT-NEXT: [[CALL_H2S:%.*]] = alloca i8, i64 24, align 1
-; TUNIT-NEXT: [[LOCAL:%.*]] = alloca [[STRUCT_STY:%.*]], align 8
-; TUNIT-NEXT: [[INNER:%.*]] = getelementptr inbounds [[STRUCT_STY]], ptr [[LOCAL]], i64 0, i32 2
-; TUNIT-NEXT: store ptr @global, ptr [[INNER]], align 8
+; TUNIT-NEXT: [[LOCAL1:%.*]] = alloca [8 x i8], align 1
+; TUNIT-NEXT: [[INNER:%.*]] = getelementptr inbounds [[STRUCT_STY:%.*]], ptr [[LOCAL1]], i64 0, i32 2
+; TUNIT-NEXT: [[NEWGEP:%.*]] = getelementptr ptr, ptr [[INNER]], i64 -16
+; TUNIT-NEXT: store ptr @global, ptr [[NEWGEP]], align 8
; TUNIT-NEXT: store ptr [[DST]], ptr [[CALL_H2S]], align 8
; TUNIT-NEXT: [[SRC2:%.*]] = getelementptr inbounds i8, ptr [[CALL_H2S]], i64 8
; TUNIT-NEXT: store ptr [[SRC]], ptr [[SRC2]], align 8
; TUNIT-NEXT: store ptr [[CALL_H2S]], ptr getelementptr inbounds ([[STRUCT_STY]], ptr @global, i64 0, i32 2), align 8
-; TUNIT-NEXT: [[TMP0:%.*]] = load ptr, ptr [[LOCAL]], align 8
-; TUNIT-NEXT: [[LOCAL_B8:%.*]] = getelementptr i8, ptr [[LOCAL]], i64 8
-; TUNIT-NEXT: [[TMP1:%.*]] = load ptr, ptr [[LOCAL_B8]], align 8
-; TUNIT-NEXT: [[LOCAL_B16:%.*]] = getelementptr i8, ptr [[LOCAL]], i64 16
-; TUNIT-NEXT: [[TMP2:%.*]] = load ptr, ptr [[LOCAL_B16]], align 8
+; TUNIT-NEXT: [[TMP0:%.*]] = load ptr, ptr [[LOCAL1]], align 8
+; TUNIT-NEXT: [[LOCAL1_B8:%.*]] = getelementptr i8, ptr [[LOCAL1]], i64 8
+; TUNIT-NEXT: [[TMP1:%.*]] = load ptr, ptr [[LOCAL1_B8]], align 8
+; TUNIT-NEXT: [[LOCAL1_B16:%.*]] = getelementptr i8, ptr [[LOCAL1]], i64 16
+; TUNIT-NEXT: [[TMP2:%.*]] = load ptr, ptr [[LOCAL1_B16]], align 8
; TUNIT-NEXT: call fastcc void @nested_memory_callee(ptr [[TMP0]], ptr [[TMP1]], ptr [[TMP2]]) #[[ATTR21:[0-9]+]]
; TUNIT-NEXT: ret void
;
@@ -2773,8 +2800,8 @@ define hidden void @no_propagation_of_unknown_index_access(ptr %in, ptr %out, i3
; TUNIT-LABEL: define {{[^@]+}}@no_propagation_of_unknown_index_access
; TUNIT-SAME: (ptr nocapture nofree readonly [[IN:%.*]], ptr nocapture nofree writeonly [[OUT:%.*]], i32 [[IDX:%.*]]) #[[ATTR1]] {
; TUNIT-NEXT: entry:
-; TUNIT-NEXT: [[BUF:%.*]] = alloca [128 x i32], align 16
-; TUNIT-NEXT: call void @llvm.lifetime.start.p0(i64 noundef 512, ptr noalias nocapture nofree noundef nonnull align 16 dereferenceable(512) [[BUF]]) #[[ATTR17]]
+; TUNIT-NEXT: [[BUF1:%.*]] = alloca [4 x i8], align 1
+; TUNIT-NEXT: call void @llvm.lifetime.start.p0(i64 noundef 512, ptr noalias nocapture nofree noundef nonnull align 16 dereferenceable(512) [[BUF1]]) #[[ATTR17]]
; TUNIT-NEXT: br label [[FOR_COND:%.*]]
; TUNIT: for.cond:
; TUNIT-NEXT: [[I_0:%.*]] = phi i32 [ 0, [[ENTRY:%.*]] ], [ [[INC:%.*]], [[FOR_BODY:%.*]] ]
@@ -2786,7 +2813,7 @@ define hidden void @no_propagation_of_unknown_index_access(ptr %in, ptr %out, i3
; TUNIT-NEXT: [[IDXPROM:%.*]] = sext i32 [[I_0]] to i64
; TUNIT-NEXT: [[ARRAYIDX:%.*]] = getelementptr inbounds i32, ptr [[IN]], i64 [[IDXPROM]]
; TUNIT-NEXT: [[TMP0:%.*]] = load i32, ptr [[ARRAYIDX]], align 4
-; TUNIT-NEXT: [[ARRAYIDX2:%.*]] = getelementptr inbounds [128 x i32], ptr [[BUF]], i64 0, i64 [[IDXPROM]]
+; TUNIT-NEXT: [[ARRAYIDX2:%.*]] = getelementptr inbounds [128 x i32], ptr [[BUF1]], i64 0, i64 [[IDXPROM]]
; TUNIT-NEXT: store i32 [[TMP0]], ptr [[ARRAYIDX2]], align 4
; TUNIT-NEXT: [[INC]] = add nsw i32 [[I_0]], 1
; TUNIT-NEXT: br label [[FOR_COND]], !llvm.loop [[TBAA10]]
@@ -2795,14 +2822,14 @@ define hidden void @no_propagation_of_unknown_index_access(ptr %in, ptr %out, i3
; TUNIT-NEXT: [[CMP5:%.*]] = icmp slt i32 [[I3_0]], 128
; TUNIT-NEXT: br i1 [[CMP5]], label [[FOR_BODY7]], label [[FOR_COND_CLEANUP6:%.*]]
; TUNIT: for.cond.cleanup6:
-; TUNIT-NEXT: call void @llvm.lifetime.end.p0(i64 noundef 512, ptr noalias nocapture nofree noundef nonnull align 16 dereferenceable(512) [[BUF]]) #[[ATTR17]]
+; TUNIT-NEXT: call void @llvm.lifetime.end.p0(i64 noundef 512, ptr noalias nocapture nofree noundef nonnull align 16 dereferenceable(512) [[BUF1]]) #[[ATTR17]]
; TUNIT-NEXT: ret void
; TUNIT: for.body7:
; TUNIT-NEXT: [[IDXPROM8:%.*]] = sext i32 [[I3_0]] to i64
-; TUNIT-NEXT: [[ARRAYIDX9:%.*]] = getelementptr inbounds [128 x i32], ptr [[BUF]], i64 0, i64 [[IDXPROM8]]
+; TUNIT-NEXT: [[ARRAYIDX9:%.*]] = getelementptr inbounds [128 x i32], ptr [[BUF1]], i64 0, i64 [[IDXPROM8]]
; TUNIT-NEXT: [[TMP1:%.*]] = load i32, ptr [[ARRAYIDX9]], align 4
; TUNIT-NEXT: [[IDXPROM10:%.*]] = sext i32 [[IDX]] to i64
-; TUNIT-NEXT: [[ARRAYIDX11:%.*]] = getelementptr inbounds [128 x i32], ptr [[BUF]], i64 0, i64 [[IDXPROM10]]
+; TUNIT-NEXT: [[ARRAYIDX11:%.*]] = getelementptr inbounds [128 x i32], ptr [[BUF1]], i64 0, i64 [[IDXPROM10]]
; TUNIT-NEXT: [[TMP2:%.*]] = load i32, ptr [[ARRAYIDX11]], align 4
; TUNIT-NEXT: [[CMP12:%.*]] = icmp sle i32 [[TMP1]], [[TMP2]]
; TUNIT-NEXT: [[CONV:%.*]] = zext i1 [[CMP12]] to i32
@@ -2815,8 +2842,8 @@ define hidden void @no_propagation_of_unknown_index_access(ptr %in, ptr %out, i3
; CGSCC-LABEL: define {{[^@]+}}@no_propagation_of_unknown_index_access
; CGSCC-SAME: (ptr nocapture nofree readonly [[IN:%.*]], ptr nocapture nofree writeonly [[OUT:%.*]], i32 [[IDX:%.*]]) #[[ATTR13:[0-9]+]] {
; CGSCC-NEXT: entry:
-; CGSCC-NEXT: [[BUF:%.*]] = alloca [128 x i32], align 16
-; CGSCC-NEXT: call void @llvm.lifetime.start.p0(i64 noundef 512, ptr noalias nocapture nofree noundef nonnull align 16 dereferenceable(512) [[BUF]]) #[[ATTR20]]
+; CGSCC-NEXT: [[BUF1:%.*]] = alloca [4 x i8], align 1
+; CGSCC-NEXT: call void @llvm.lifetime.start.p0(i64 noundef 512, ptr noalias nocapture nofree noundef nonnull align 16 dereferenceable(512) [[BUF1]]) #[[ATTR20]]
; CGSCC-NEXT: br label [[FOR_COND:%.*]]
; CGSCC: for.cond:
; CGSCC-NEXT: [[I_0:%.*]] = phi i32 [ 0, [[ENTRY:%.*]] ], [ [[INC:%.*]], [[FOR_BODY:%.*]] ]
@@ -2828,7 +2855,7 @@ define hidden void @no_propagation_of_unknown_index_access(ptr %in, ptr %out, i3
; CGSCC-NEXT: [[IDXPROM:%.*]] = sext i32 [[I_0]] to i64
; CGSCC-NEXT: [[ARRAYIDX:%.*]] = getelementptr inbounds i32, ptr [[IN]], i64 [[IDXPROM]]
; CGSCC-NEXT: [[TMP0:%.*]] = load i32, ptr [[ARRAYIDX]], align 4
-; CGSCC-NEXT: [[ARRAYIDX2:%.*]] = getelementptr inbounds [128 x i32], ptr [[BUF]], i64 0, i64 [[IDXPROM]]
+; CGSCC-NEXT: [[ARRAYIDX2:%.*]] = getelementptr inbounds [128 x i32], ptr [[BUF1]], i64 0, i64 [[IDXPROM]]
; CGSCC-NEXT: store i32 [[TMP0]], ptr [[ARRAYIDX2]], align 4
; CGSCC-NEXT: [[INC]] = add nsw i32 [[I_0]], 1
; CGSCC-NEXT: br label [[FOR_COND]], !llvm.loop [[TBAA10]]
@@ -2837,14 +2864,14 @@ define hidden void @no_propagation_of_unknown_index_access(ptr %in, ptr %out, i3
; CGSCC-NEXT: [[CMP5:%.*]] = icmp slt i32 [[I3_0]], 128
; CGSCC-NEXT: br i1 [[CMP5]], label [[FOR_BODY7]], label [[FOR_COND_CLEANUP6:%.*]]
; CGSCC: for.cond.cleanup6:
-; CGSCC-NEXT: call void @llvm.lifetime.end.p0(i64 noundef 512, ptr noalias nocapture nofree noundef nonnull align 16 dereferenceable(512) [[BUF]]) #[[ATTR20]]
+; CGSCC-NEXT: call void @llvm.lifetime.end.p0(i64 noundef 512, ptr noalias nocapture nofree noundef nonnull align 16 dereferenceable(512) [[BUF1]]) #[[ATTR20]]
; CGSCC-NEXT: ret void
; CGSCC: for.body7:
; CGSCC-NEXT: [[IDXPROM8:%.*]] = sext i32 [[I3_0]] to i64
-; CGSCC-NEXT: [[ARRAYIDX9:%.*]] = getelementptr inbounds [128 x i32], ptr [[BUF]], i64 0, i64 [[IDXPROM8]]
+; CGSCC-NEXT: [[ARRAYIDX9:%.*]] = getelementptr inbounds [128 x i32], ptr [[BUF1]], i64 0, i64 [[IDXPROM8]]
; CGSCC-NEXT: [[TMP1:%.*]] = load i32, ptr [[ARRAYIDX9]], align 4
; CGSCC-NEXT: [[IDXPROM10:%.*]] = sext i32 [[IDX]] to i64
-; CGSCC-NEXT: [[ARRAYIDX11:%.*]] = getelementptr inbounds [128 x i32], ptr [[BUF]], i64 0, i64 [[IDXPROM10]]
+; CGSCC-NEXT: [[ARRAYIDX11:%.*]] = getelementptr inbounds [128 x i32], ptr [[BUF1]], i64 0, i64 [[IDXPROM10]]
; CGSCC-NEXT: [[TMP2:%.*]] = load i32, ptr [[ARRAYIDX11]], align 4
; CGSCC-NEXT: [[CMP12:%.*]] = icmp sle i32 [[TMP1]], [[TMP2]]
; CGSCC-NEXT: [[CONV:%.*]] = zext i1 [[CMP12]] to i32
@@ -3017,8 +3044,10 @@ define i8 @gep_index_from_binary_operator(i1 %cnd1, i1 %cnd2) {
; CHECK-LABEL: define {{[^@]+}}@gep_index_from_binary_operator
; CHECK-SAME: (i1 [[CND1:%.*]], i1 [[CND2:%.*]]) #[[ATTR4]] {
; CHECK-NEXT: entry:
-; CHECK-NEXT: [[BYTES:%.*]] = alloca [1024 x i8], align 16
-; CHECK-NEXT: [[GEP_FIXED:%.*]] = getelementptr inbounds [1024 x i8], ptr [[BYTES]], i64 0, i64 12
+; CHECK-NEXT: [[BYTES1:%.*]] = alloca [1 x i8], align 1
+; CHECK-NEXT: [[GEP_FIXED:%.*]] = getelementptr inbounds [1024 x i8], ptr [[BYTES1]], i64 0, i64 12
+; CHECK-NEXT: [[NEWGEP:%.*]] = getelementptr ptr, ptr [[GEP_FIXED]], i64 -12
+; CHECK-NEXT: store i8 100, ptr [[NEWGEP]], align 4
; CHECK-NEXT: ret i8 100
;
entry:
@@ -3036,8 +3065,10 @@ define i8 @gep_index_from_memory(i1 %cnd1, i1 %cnd2) {
; CHECK-LABEL: define {{[^@]+}}@gep_index_from_memory
; CHECK-SAME: (i1 [[CND1:%.*]], i1 [[CND2:%.*]]) #[[ATTR4]] {
; CHECK-NEXT: entry:
-; CHECK-NEXT: [[BYTES:%.*]] = alloca [1024 x i8], align 16
-; CHECK-NEXT: [[GEP_LOADED:%.*]] = getelementptr inbounds [1024 x i8], ptr [[BYTES]], i64 0, i64 12
+; CHECK-NEXT: [[BYTES1:%.*]] = alloca [1 x i8], align 1
+; CHECK-NEXT: [[GEP_LOADED:%.*]] = getelementptr inbounds [1024 x i8], ptr [[BYTES1]], i64 0, i64 12
+; CHECK-NEXT: [[NEWGEP:%.*]] = getelementptr ptr, ptr [[GEP_LOADED]], i64 -12
+; CHECK-NEXT: store i8 100, ptr [[NEWGEP]], align 4
; CHECK-NEXT: ret i8 100
;
entry:
diff --git a/llvm/test/Transforms/Attributor/wrapper.ll b/llvm/test/Transforms/Attributor/wrapper.ll
index ebc2719416221..906952919289b 100644
--- a/llvm/test/Transforms/Attributor/wrapper.ll
+++ b/llvm/test/Transforms/Attributor/wrapper.ll
@@ -81,5 +81,4 @@ entry:
9:
%10 = load i32, ptr %1
ret i32 %10
-}
-
+}
\ No newline at end of file
diff --git a/llvm/test/Transforms/OpenMP/parallel_deletion.ll b/llvm/test/Transforms/OpenMP/parallel_deletion.ll
index 4619da1206092..771374a1363b7 100644
--- a/llvm/test/Transforms/OpenMP/parallel_deletion.ll
+++ b/llvm/test/Transforms/OpenMP/parallel_deletion.ll
@@ -1,4 +1,4 @@
-; NOTE: Assertions have been autogenerated by utils/update_test_checks.py UTC_ARGS: --function-signature
+; NOTE: Assertions have been autogenerated by utils/update_test_checks.py UTC_ARGS: --function-signature --check-attributes --check-globals
; RUN: opt -S -passes='attributor,cgscc(openmp-opt-cgscc)' < %s | FileCheck %s
;
target datalayout = "e-m:e-p270:32:32-p271:32:32-p272:64:64-i64:64-f80:128-n8:16:32:64-S128"
@@ -23,10 +23,17 @@ target datalayout = "e-m:e-p270:32:32-p271:32:32-p272:64:64-i64:64-f80:128-n8:16
; }
;
; We delete all but the first of the parallel regions in this test.
+;.
+; CHECK: @.str = private unnamed_addr constant [23 x i8] c"
+; CHECK: @[[GLOB0:[0-9]+]] = private unnamed_addr global %struct.ident_t { i32 0, i32 2, i32 0, i32 0, ptr @.str }, align 8
+; CHECK: @[[GLOB1:[0-9]+]] = private unnamed_addr global %struct.ident_t { i32 0, i32 322, i32 0, i32 0, ptr @.str }, align 8
+; CHECK: @.gomp_critical_user_.reduction.var = common global [8 x i32] zeroinitializer
+; CHECK: @[[GLOB2:[0-9]+]] = private unnamed_addr global %struct.ident_t { i32 0, i32 18, i32 0, i32 0, ptr @.str }, align 8
+;.
define void @delete_parallel_0() {
; CHECK-LABEL: define {{[^@]+}}@delete_parallel_0() {
; CHECK-NEXT: entry:
-; CHECK-NEXT: call void (ptr, i32, ptr, ...) @__kmpc_fork_call(ptr noundef nonnull align 8 dereferenceable(24) @[[GLOB0:[0-9]+]], i32 noundef 0, ptr noundef nonnull @.omp_outlined.willreturn)
+; CHECK-NEXT: call void (ptr, i32, ptr, ...) @__kmpc_fork_call(ptr noundef nonnull align 8 dereferenceable(24) @[[GLOB0]], i32 noundef 0, ptr noundef nonnull @.omp_outlined.willreturn)
; CHECK-NEXT: ret void
;
; CHECK1-LABEL: define {{[^@]+}}@delete_parallel_0() {
@@ -46,6 +53,7 @@ entry:
}
define internal void @.omp_outlined.willreturn(ptr noalias %.global_tid., ptr noalias %.bound_tid.) {
+; CHECK: Function Attrs: mustprogress willreturn
; CHECK-LABEL: define {{[^@]+}}@.omp_outlined.willreturn
; CHECK-SAME: (ptr noalias nocapture nofree readnone [[DOTGLOBAL_TID_:%.*]], ptr noalias nocapture nofree readnone [[DOTBOUND_TID_:%.*]]) #[[ATTR0:[0-9]+]] {
; CHECK-NEXT: entry:
@@ -68,6 +76,7 @@ entry:
}
define internal void @.omp_outlined.willreturn.0(ptr noalias %.global_tid., ptr noalias %.bound_tid.) willreturn {
+; CHECK: Function Attrs: mustprogress nosync willreturn memory(read)
; CHECK-LABEL: define {{[^@]+}}@.omp_outlined.willreturn.0
; CHECK-SAME: (ptr noalias nocapture nofree readnone [[DOTGLOBAL_TID_:%.*]], ptr noalias nocapture nofree readnone [[DOTBOUND_TID_:%.*]]) #[[ATTR1:[0-9]+]] {
; CHECK-NEXT: entry:
@@ -90,6 +99,7 @@ entry:
}
define internal void @.omp_outlined.willreturn.1(ptr noalias %.global_tid., ptr noalias %.bound_tid.) {
+; CHECK: Function Attrs: mustprogress nosync willreturn memory(none)
; CHECK-LABEL: define {{[^@]+}}@.omp_outlined.willreturn.1
; CHECK-SAME: (ptr noalias nocapture nofree readnone [[DOTGLOBAL_TID_:%.*]], ptr noalias nocapture nofree readnone [[DOTBOUND_TID_:%.*]]) #[[ATTR2:[0-9]+]] {
; CHECK-NEXT: entry:
@@ -112,6 +122,7 @@ entry:
}
define internal void @.omp_outlined.willreturn.2(ptr noalias %.global_tid., ptr noalias %.bound_tid.) {
+; CHECK: Function Attrs: mustprogress nofree norecurse nosync nounwind willreturn memory(none)
; CHECK-LABEL: define {{[^@]+}}@.omp_outlined.willreturn.2
; CHECK-SAME: (ptr noalias nocapture nofree readnone [[DOTGLOBAL_TID_:%.*]], ptr noalias nocapture nofree readnone [[DOTBOUND_TID_:%.*]]) #[[ATTR3:[0-9]+]] {
; CHECK-NEXT: entry:
@@ -192,6 +203,7 @@ entry:
}
define internal void @.omp_outlined..0(ptr noalias %.global_tid., ptr noalias %.bound_tid.) {
+; CHECK: Function Attrs: nosync memory(read)
; CHECK-LABEL: define {{[^@]+}}@.omp_outlined..0
; CHECK-SAME: (ptr noalias nocapture nofree readnone [[DOTGLOBAL_TID_:%.*]], ptr noalias nocapture nofree readnone [[DOTBOUND_TID_:%.*]]) #[[ATTR4]] {
; CHECK-NEXT: entry:
@@ -214,6 +226,7 @@ entry:
}
define internal void @.omp_outlined..1(ptr noalias %.global_tid., ptr noalias %.bound_tid.) {
+; CHECK: Function Attrs: nosync memory(none)
; CHECK-LABEL: define {{[^@]+}}@.omp_outlined..1
; CHECK-SAME: (ptr noalias nocapture nofree readnone [[DOTGLOBAL_TID_:%.*]], ptr noalias nocapture nofree readnone [[DOTBOUND_TID_:%.*]]) #[[ATTR5:[0-9]+]] {
; CHECK-NEXT: entry:
@@ -236,6 +249,7 @@ entry:
}
define internal void @.omp_outlined..2(ptr noalias %.global_tid., ptr noalias %.bound_tid.) {
+; CHECK: Function Attrs: mustprogress nofree norecurse nosync nounwind willreturn memory(none)
; CHECK-LABEL: define {{[^@]+}}@.omp_outlined..2
; CHECK-SAME: (ptr noalias nocapture nofree readnone [[DOTGLOBAL_TID_:%.*]], ptr noalias nocapture nofree readnone [[DOTBOUND_TID_:%.*]]) #[[ATTR3]] {
; CHECK-NEXT: entry:
@@ -326,6 +340,7 @@ entry:
}
define internal void @.omp_outlined..3(ptr noalias %.global_tid., ptr noalias %.bound_tid., ptr dereferenceable(4) %a) {
+; CHECK: Function Attrs: nofree nosync nounwind memory(argmem: readwrite, inaccessiblemem: readwrite)
; CHECK-LABEL: define {{[^@]+}}@.omp_outlined..3
; CHECK-SAME: (ptr noalias nocapture nofree readnone [[DOTGLOBAL_TID_:%.*]], ptr noalias nocapture nofree readnone [[DOTBOUND_TID_:%.*]], ptr nocapture nofree noundef nonnull align 4 dereferenceable(4) [[A:%.*]]) #[[ATTR6:[0-9]+]] {
; CHECK-NEXT: entry:
@@ -469,7 +484,7 @@ define internal void @.omp_outlined..5(ptr noalias %.global_tid., ptr noalias %.
; CHECK-NEXT: call void @__kmpc_end_single(ptr noundef nonnull @[[GLOB0]], i32 [[TMP]])
; CHECK-NEXT: br label [[OMP_IF_END]]
; CHECK: omp_if.end:
-; CHECK-NEXT: call void @__kmpc_barrier(ptr noundef nonnull @[[GLOB1:[0-9]+]], i32 [[OMP_GLOBAL_THREAD_NUM]])
+; CHECK-NEXT: call void @__kmpc_barrier(ptr noundef nonnull @[[GLOB1]], i32 [[OMP_GLOBAL_THREAD_NUM]])
; CHECK-NEXT: ret void
;
; CHECK1-LABEL: define {{[^@]+}}@.omp_outlined..5
@@ -535,7 +550,7 @@ define internal void @.omp_outlined..6(ptr noalias %.global_tid., ptr noalias %.
; CHECK-NEXT: store i32 1, ptr [[A1]], align 4
; CHECK-NEXT: store ptr [[A1]], ptr [[DOTOMP_REDUCTION_RED_LIST]], align 8
; CHECK-NEXT: [[TMP2:%.*]] = load i32, ptr [[DOTGLOBAL_TID_]], align 4
-; CHECK-NEXT: [[TMP4:%.*]] = call i32 @__kmpc_reduce_nowait(ptr noundef nonnull @[[GLOB2:[0-9]+]], i32 [[TMP2]], i32 noundef 1, i64 noundef 8, ptr noundef nonnull align 8 [[DOTOMP_REDUCTION_RED_LIST]], ptr noundef nonnull @.omp.reduction.reduction_func, ptr noundef nonnull @.gomp_critical_user_.reduction.var)
+; CHECK-NEXT: [[TMP4:%.*]] = call i32 @__kmpc_reduce_nowait(ptr noundef nonnull @[[GLOB2]], i32 [[TMP2]], i32 noundef 1, i64 noundef 8, ptr noundef nonnull align 8 [[DOTOMP_REDUCTION_RED_LIST]], ptr noundef nonnull @.omp.reduction.reduction_func, ptr noundef nonnull @.gomp_critical_user_.reduction.var)
; CHECK-NEXT: switch i32 [[TMP4]], label [[DOTOMP_REDUCTION_DEFAULT:%.*]] [
; CHECK-NEXT: i32 1, label [[DOTOMP_REDUCTION_CASE1:%.*]]
; CHECK-NEXT: i32 2, label [[DOTOMP_REDUCTION_CASE2:%.*]]
@@ -643,6 +658,7 @@ entry:
}
define internal void @.omp.reduction.reduction_func(ptr %arg, ptr %arg1) {
+; CHECK: Function Attrs: mustprogress nofree norecurse nosync nounwind willreturn
; CHECK-LABEL: define {{[^@]+}}@.omp.reduction.reduction_func
; CHECK-SAME: (ptr nocapture nofree noundef nonnull readonly align 8 dereferenceable(8) [[ARG:%.*]], ptr nocapture nofree noundef nonnull readonly align 8 dereferenceable(8) [[ARG1:%.*]]) #[[ATTR10:[0-9]+]] {
; CHECK-NEXT: entry:
@@ -717,3 +733,30 @@ declare void @readnone() readnone
!6 = !{!"omnipotent char", !7, i64 0}
!7 = !{!"Simple C/C++ TBAA"}
!8 = !{i32 7, !"openmp", i32 50}
+;.
+; CHECK: attributes #[[ATTR0]] = { mustprogress willreturn }
+; CHECK: attributes #[[ATTR1]] = { mustprogress nosync willreturn memory(read) }
+; CHECK: attributes #[[ATTR2]] = { mustprogress nosync willreturn memory(none) }
+; CHECK: attributes #[[ATTR3]] = { mustprogress nofree norecurse nosync nounwind willreturn memory(none) }
+; CHECK: attributes #[[ATTR4]] = { nosync memory(read) }
+; CHECK: attributes #[[ATTR5]] = { nosync memory(none) }
+; CHECK: attributes #[[ATTR6]] = { nofree nosync nounwind memory(argmem: readwrite, inaccessiblemem: readwrite) }
+; CHECK: attributes #[[ATTR7:[0-9]+]] = { nocallback nofree nosync nounwind willreturn memory(argmem: readwrite) }
+; CHECK: attributes #[[ATTR8:[0-9]+]] = { nofree nosync nounwind memory(inaccessiblemem: read) }
+; CHECK: attributes #[[ATTR9:[0-9]+]] = { nounwind }
+; CHECK: attributes #[[ATTR10]] = { mustprogress nofree norecurse nosync nounwind willreturn }
+; CHECK: attributes #[[ATTR11:[0-9]+]] = { convergent nounwind }
+; CHECK: attributes #[[ATTR12:[0-9]+]] = { nofree nosync nounwind memory(read) }
+; CHECK: attributes #[[ATTR13:[0-9]+]] = { memory(read) }
+; CHECK: attributes #[[ATTR14:[0-9]+]] = { memory(none) }
+; CHECK: attributes #[[ATTR15]] = { willreturn }
+; CHECK: attributes #[[ATTR16]] = { nosync willreturn }
+; CHECK: attributes #[[ATTR17]] = { nosync }
+; CHECK: attributes #[[ATTR18]] = { nofree willreturn }
+; CHECK: attributes #[[ATTR19]] = { nofree nounwind memory(read) }
+; CHECK: attributes #[[ATTR20]] = { nofree willreturn memory(readwrite) }
+;.
+; CHECK: [[META0:![0-9]+]] = !{i32 7, !"openmp", i32 50}
+; CHECK: [[META1:![0-9]+]] = !{[[META2:![0-9]+]]}
+; CHECK: [[META2]] = !{i64 2, i64 -1, i64 -1, i1 true}
+;.
diff --git a/llvm/test/Transforms/OpenMP/parallel_region_merging.ll b/llvm/test/Transforms/OpenMP/parallel_region_merging.ll
index f169fea09d0ea..c4e9fc44d7c48 100644
--- a/llvm/test/Transforms/OpenMP/parallel_region_merging.ll
+++ b/llvm/test/Transforms/OpenMP/parallel_region_merging.ll
@@ -1,4 +1,4 @@
-; NOTE: Assertions have been autogenerated by utils/update_test_checks.py UTC_ARGS: --function-signature --include-generated-funcs
+; NOTE: Assertions have been autogenerated by utils/update_test_checks.py UTC_ARGS: --function-signature --check-attributes --check-globals --include-generated-funcs
; RUN: opt -S -aa-pipeline= -passes='attributor,cgscc(openmp-opt-cgscc)' -openmp-opt-enable-merging < %s | FileCheck %s --check-prefix=CHECK2
; #include <omp.h>
; void foo();
@@ -4670,13 +4670,19 @@ entry:
; CHECK-NEXT: call void @use(i32 [[TMP0]])
; CHECK-NEXT: ret void
+;.
+; CHECK2: @[[GLOB0:[0-9]+]] = private unnamed_addr constant [23 x i8] c"
+; CHECK2: @[[GLOB1:[0-9]+]] = private unnamed_addr constant %struct.ident_t { i32 0, i32 2, i32 0, i32 0, ptr @[[GLOB0]] }, align 8
+; CHECK2: @[[GLOB2:[0-9]+]] = private unnamed_addr constant %struct.ident_t { i32 0, i32 2, i32 0, i32 22, ptr @[[GLOB0]] }, align 8
+; CHECK2: @[[GLOB3:[0-9]+]] = private unnamed_addr constant %struct.ident_t { i32 0, i32 66, i32 0, i32 22, ptr @[[GLOB0]] }, align 8
+;.
; CHECK2-LABEL: define {{[^@]+}}@merge
; CHECK2-SAME: (i32 [[A:%.*]]) local_unnamed_addr {
; CHECK2-NEXT: entry:
; CHECK2-NEXT: [[STRUCTARG:%.*]] = alloca { ptr }, align 8
; CHECK2-NEXT: [[A_ADDR:%.*]] = alloca i32, align 4
; CHECK2-NEXT: store i32 [[A]], ptr [[A_ADDR]], align 4
-; CHECK2-NEXT: [[OMP_GLOBAL_THREAD_NUM:%.*]] = call i32 @__kmpc_global_thread_num(ptr @[[GLOB2:[0-9]+]])
+; CHECK2-NEXT: [[OMP_GLOBAL_THREAD_NUM:%.*]] = call i32 @__kmpc_global_thread_num(ptr @[[GLOB2]])
; CHECK2-NEXT: br label [[OMP_PARALLEL:%.*]]
; CHECK2: omp_parallel:
; CHECK2-NEXT: [[GEP_A_ADDR:%.*]] = getelementptr { ptr }, ptr [[STRUCTARG]], i32 0, i32 0
@@ -4691,6 +4697,7 @@ entry:
; CHECK2-NEXT: ret void
;
;
+; CHECK2: Function Attrs: nounwind
; CHECK2-LABEL: define {{[^@]+}}@merge..omp_par
; CHECK2-SAME: (ptr noalias [[TID_ADDR:%.*]], ptr noalias [[ZERO_ADDR:%.*]], ptr [[TMP0:%.*]]) #[[ATTR0:[0-9]+]] {
; CHECK2-NEXT: omp.par.entry:
@@ -4706,7 +4713,7 @@ entry:
; CHECK2: omp.par.merged:
; CHECK2-NEXT: call void (ptr, ptr, ...) @.omp_outlined.(ptr [[TID_ADDR]], ptr [[ZERO_ADDR]], ptr nocapture nofree noundef nonnull readonly align 4 dereferenceable(4) [[LOADGEP_A_ADDR]])
; CHECK2-NEXT: [[OMP_GLOBAL_THREAD_NUM:%.*]] = call i32 @__kmpc_global_thread_num(ptr @[[GLOB2]])
-; CHECK2-NEXT: call void @__kmpc_barrier(ptr @[[GLOB3:[0-9]+]], i32 [[OMP_GLOBAL_THREAD_NUM]])
+; CHECK2-NEXT: call void @__kmpc_barrier(ptr @[[GLOB3]], i32 [[OMP_GLOBAL_THREAD_NUM]])
; CHECK2-NEXT: call void (ptr, ptr, ...) @.omp_outlined..1(ptr [[TID_ADDR]], ptr [[ZERO_ADDR]], ptr nocapture nofree noundef nonnull readonly align 4 dereferenceable(4) [[LOADGEP_A_ADDR]])
; CHECK2-NEXT: br label [[ENTRY_SPLIT:%.*]]
; CHECK2: entry.split:
@@ -4739,7 +4746,7 @@ entry:
; CHECK2-SAME: (i32 [[A:%.*]]) local_unnamed_addr {
; CHECK2-NEXT: entry:
; CHECK2-NEXT: [[A_ADDR:%.*]] = alloca i32, align 4
-; CHECK2-NEXT: [[TMP0:%.*]] = call i32 @__kmpc_global_thread_num(ptr noundef nonnull align 8 dereferenceable(24) @[[GLOB1:[0-9]+]])
+; CHECK2-NEXT: [[TMP0:%.*]] = call i32 @__kmpc_global_thread_num(ptr noundef nonnull align 8 dereferenceable(24) @[[GLOB1]])
; CHECK2-NEXT: store i32 [[A]], ptr [[A_ADDR]], align 4
; CHECK2-NEXT: call void @__kmpc_push_proc_bind(ptr noundef nonnull align 8 dereferenceable(24) @[[GLOB1]], i32 [[TMP0]], i32 noundef 3)
; CHECK2-NEXT: call void (ptr, i32, ptr, ...) @__kmpc_fork_call(ptr noundef nonnull align 8 dereferenceable(24) @[[GLOB1]], i32 noundef 1, ptr noundef nonnull @.omp_outlined..2, ptr nocapture nofree noundef nonnull readonly align 4 dereferenceable(4) [[A_ADDR]])
@@ -4841,6 +4848,7 @@ entry:
; CHECK2-NEXT: ret void
;
;
+; CHECK2: Function Attrs: nounwind
; CHECK2-LABEL: define {{[^@]+}}@merge_seq..omp_par
; CHECK2-SAME: (ptr noalias [[TID_ADDR:%.*]], ptr noalias [[ZERO_ADDR:%.*]], ptr [[TMP0:%.*]]) #[[ATTR0]] {
; CHECK2-NEXT: omp.par.entry:
@@ -4933,6 +4941,7 @@ entry:
; CHECK2-NEXT: ret void
;
;
+; CHECK2: Function Attrs: nounwind
; CHECK2-LABEL: define {{[^@]+}}@merge_seq_float..omp_par
; CHECK2-SAME: (ptr noalias [[TID_ADDR:%.*]], ptr noalias [[ZERO_ADDR:%.*]], ptr [[TMP0:%.*]]) #[[ATTR0]] {
; CHECK2-NEXT: omp.par.entry:
@@ -5030,6 +5039,7 @@ entry:
; CHECK2-NEXT: ret void
;
;
+; CHECK2: Function Attrs: nounwind
; CHECK2-LABEL: define {{[^@]+}}@merge_seq_firstprivate..omp_par
; CHECK2-SAME: (ptr noalias [[TID_ADDR:%.*]], ptr noalias [[ZERO_ADDR:%.*]], ptr [[TMP0:%.*]]) #[[ATTR0]] {
; CHECK2-NEXT: omp.par.entry:
@@ -5121,6 +5131,7 @@ entry:
; CHECK2-NEXT: ret void
;
;
+; CHECK2: Function Attrs: nounwind
; CHECK2-LABEL: define {{[^@]+}}@merge_seq_sink_lt..omp_par
; CHECK2-SAME: (ptr noalias [[TID_ADDR:%.*]], ptr noalias [[ZERO_ADDR:%.*]], ptr [[TMP0:%.*]]) #[[ATTR0]] {
; CHECK2-NEXT: omp.par.entry:
@@ -5219,6 +5230,7 @@ entry:
; CHECK2-NEXT: ret void
;
;
+; CHECK2: Function Attrs: nounwind
; CHECK2-LABEL: define {{[^@]+}}@merge_seq_par_use..omp_par
; CHECK2-SAME: (ptr noalias [[TID_ADDR:%.*]], ptr noalias [[ZERO_ADDR:%.*]], ptr [[TMP0:%.*]]) #[[ATTR0]] {
; CHECK2-NEXT: omp.par.entry:
@@ -5315,6 +5327,7 @@ entry:
; CHECK2-NEXT: ret void
;
;
+; CHECK2: Function Attrs: nounwind
; CHECK2-LABEL: define {{[^@]+}}@merge_cancellable_regions..omp_par
; CHECK2-SAME: (ptr noalias [[TID_ADDR:%.*]], ptr noalias [[ZERO_ADDR:%.*]], ptr [[TMP0:%.*]]) #[[ATTR0]] {
; CHECK2-NEXT: omp.par.entry:
@@ -5402,6 +5415,7 @@ entry:
; CHECK2-NEXT: ret void
;
;
+; CHECK2: Function Attrs: nounwind
; CHECK2-LABEL: define {{[^@]+}}@merge_cancellable_regions_seq..omp_par
; CHECK2-SAME: (ptr noalias [[TID_ADDR:%.*]], ptr noalias [[ZERO_ADDR:%.*]], ptr [[TMP0:%.*]]) #[[ATTR0]] {
; CHECK2-NEXT: omp.par.entry:
@@ -5505,6 +5519,7 @@ entry:
; CHECK2-NEXT: ret void
;
;
+; CHECK2: Function Attrs: nounwind
; CHECK2-LABEL: define {{[^@]+}}@merge_3..omp_par
; CHECK2-SAME: (ptr noalias [[TID_ADDR:%.*]], ptr noalias [[ZERO_ADDR:%.*]], ptr [[TMP0:%.*]]) #[[ATTR0]] {
; CHECK2-NEXT: omp.par.entry:
@@ -5593,6 +5608,7 @@ entry:
; CHECK2-NEXT: ret void
;
;
+; CHECK2: Function Attrs: nounwind
; CHECK2-LABEL: define {{[^@]+}}@merge_3_seq..omp_par
; CHECK2-SAME: (ptr noalias [[TID_ADDR:%.*]], ptr noalias [[ZERO_ADDR:%.*]], ptr [[TMP0:%.*]]) #[[ATTR0]] {
; CHECK2-NEXT: omp.par.entry:
@@ -5830,6 +5846,7 @@ entry:
; CHECK2-NEXT: ret void
;
;
+; CHECK2: Function Attrs: nounwind
; CHECK2-LABEL: define {{[^@]+}}@merge_2_unmergable_1..omp_par
; CHECK2-SAME: (ptr noalias [[TID_ADDR:%.*]], ptr noalias [[ZERO_ADDR:%.*]], ptr [[TMP0:%.*]]) #[[ATTR0]] {
; CHECK2-NEXT: omp.par.entry:
@@ -5881,3 +5898,13 @@ entry:
; CHECK2-NEXT: call void @use(i32 [[TMP0]])
; CHECK2-NEXT: ret void
;
+;.
+; CHECK2: attributes #[[ATTR0]] = { nounwind }
+; CHECK2: attributes #[[ATTR1:[0-9]+]] = { nocallback nofree nosync nounwind willreturn memory(argmem: readwrite) }
+; CHECK2: attributes #[[ATTR2:[0-9]+]] = { convergent nounwind }
+;.
+; CHECK2: [[META0:![0-9]+]] = !{i32 1, !"wchar_size", i32 4}
+; CHECK2: [[META1:![0-9]+]] = !{i32 7, !"openmp", i32 50}
+; CHECK2: [[META2:![0-9]+]] = !{[[META3:![0-9]+]]}
+; CHECK2: [[META3]] = !{i64 2, i64 -1, i64 -1, i1 true}
+;.
More information about the llvm-commits
mailing list