68 changes: 36 additions & 32 deletions llvm/lib/Transforms/IPO/AttributorAttributes.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -720,7 +720,7 @@ struct DenseMapInfo<AAPointerInfo::Access> : DenseMapInfo<Instruction *> {

/// Helper that allows OffsetAndSize as a key in a DenseMap.
template <>
struct DenseMapInfo<AAPointerInfo ::OffsetAndSize>
struct DenseMapInfo<AA::OffsetAndSize>
: DenseMapInfo<std::pair<int64_t, int64_t>> {};

/// Helper for AA::PointerInfo::Access DenseMap/Set usage ignoring everythign
Expand Down Expand Up @@ -847,7 +847,7 @@ struct AA::PointerInfo::State : public AbstractState {
};

/// We store all accesses in bins denoted by their offset and size.
using AccessBinsTy = DenseMap<AAPointerInfo::OffsetAndSize, Accesses *>;
using AccessBinsTy = DenseMap<AA::OffsetAndSize, Accesses *>;

AccessBinsTy::const_iterator begin() const { return AccessBins.begin(); }
AccessBinsTy::const_iterator end() const { return AccessBins.end(); }
Expand All @@ -865,7 +865,7 @@ struct AA::PointerInfo::State : public AbstractState {
AAPointerInfo::AccessKind Kind, Type *Ty,
Instruction *RemoteI = nullptr,
Accesses *BinPtr = nullptr) {
AAPointerInfo::OffsetAndSize Key{Offset, Size};
AA::OffsetAndSize Key{Offset, Size};
Accesses *&Bin = BinPtr ? BinPtr : AccessBins[Key];
if (!Bin)
Bin = new (A.Allocator) Accesses;
Expand All @@ -887,13 +887,13 @@ struct AA::PointerInfo::State : public AbstractState {

/// See AAPointerInfo::forallInterferingAccesses.
bool forallInterferingAccesses(
AAPointerInfo::OffsetAndSize OAS,
AA::OffsetAndSize OAS,
function_ref<bool(const AAPointerInfo::Access &, bool)> CB) const {
if (!isValidState())
return false;

for (const auto &It : AccessBins) {
AAPointerInfo::OffsetAndSize ItOAS = It.getFirst();
AA::OffsetAndSize ItOAS = It.getFirst();
if (!OAS.mayOverlap(ItOAS))
continue;
bool IsExact = OAS == ItOAS && !OAS.offsetOrSizeAreUnknown();
Expand All @@ -907,24 +907,29 @@ struct AA::PointerInfo::State : public AbstractState {
/// See AAPointerInfo::forallInterferingAccesses.
bool forallInterferingAccesses(
Instruction &I,
function_ref<bool(const AAPointerInfo::Access &, bool)> CB) const {
function_ref<bool(const AAPointerInfo::Access &, bool)> CB,
AA::OffsetAndSize *OASPtr) const {
if (!isValidState())
return false;

// First find the offset and size of I.
AAPointerInfo::OffsetAndSize OAS(-1, -1);
AA::OffsetAndSize OAS = AA::OffsetAndSize::getUnassigned();
for (const auto &It : AccessBins) {
for (auto &Access : *It.getSecond()) {
if (Access.getRemoteInst() == &I) {
OAS = It.getFirst();
break;
}
}
if (OAS.getSize() != -1)
if (OAS.getSize() != AA::OffsetAndSize::Unassigned)
break;
}

if (OASPtr)
*OASPtr = OAS;

// No access for I was found, we are done.
if (OAS.getSize() == -1)
if (OAS.getSize() == AA::OffsetAndSize::Unassigned)
return true;

// Now that we have an offset and size, find all overlapping ones and use
Expand Down Expand Up @@ -957,17 +962,16 @@ struct AAPointerInfoImpl
}

bool forallInterferingAccesses(
OffsetAndSize OAS,
AA::OffsetAndSize OAS,
function_ref<bool(const AAPointerInfo::Access &, bool)> CB)
const override {
return State::forallInterferingAccesses(OAS, CB);
}

bool
forallInterferingAccesses(Attributor &A, const AbstractAttribute &QueryingAA,
Instruction &I,
function_ref<bool(const Access &, bool)> UserCB,
bool &HasBeenWrittenTo) const override {
bool forallInterferingAccesses(
Attributor &A, const AbstractAttribute &QueryingAA, Instruction &I,
function_ref<bool(const Access &, bool)> UserCB, bool &HasBeenWrittenTo,
AA::OffsetAndSize *OASPtr = nullptr) const override {
HasBeenWrittenTo = false;

SmallPtrSet<const Access *, 8> DominatingWrites;
Expand Down Expand Up @@ -1082,7 +1086,7 @@ struct AAPointerInfoImpl
InterferingAccesses.push_back({&Acc, Exact});
return true;
};
if (!State::forallInterferingAccesses(I, AccessCB))
if (!State::forallInterferingAccesses(I, AccessCB, OASPtr))
return false;

if (HasBeenWrittenTo) {
Expand Down Expand Up @@ -1150,9 +1154,10 @@ struct AAPointerInfoImpl
// Combine the accesses bin by bin.
ChangeStatus Changed = ChangeStatus::UNCHANGED;
for (const auto &It : OtherAAImpl.getState()) {
OffsetAndSize OAS = OffsetAndSize::getUnknown();
if (Offset != OffsetAndSize::Unknown)
OAS = OffsetAndSize(It.first.getOffset() + Offset, It.first.getSize());
AA::OffsetAndSize OAS = AA::OffsetAndSize::getUnknown();
if (Offset != AA::OffsetAndSize::Unknown)
OAS = AA::OffsetAndSize(It.first.getOffset() + Offset,
It.first.getSize());
Accesses *Bin = AccessBins.lookup(OAS);
for (const AAPointerInfo::Access &RAcc : *It.second) {
if (IsByval && !RAcc.isRead())
Expand Down Expand Up @@ -1210,11 +1215,10 @@ struct AAPointerInfoFloating : public AAPointerInfoImpl {
bool handleAccess(Attributor &A, Instruction &I, Value &Ptr,
Optional<Value *> Content, AccessKind Kind, int64_t Offset,
ChangeStatus &Changed, Type *Ty,
int64_t Size = OffsetAndSize::Unknown) {
int64_t Size = AA::OffsetAndSize::Unknown) {
using namespace AA::PointerInfo;
// No need to find a size if one is given or the offset is unknown.
if (Offset != OffsetAndSize::Unknown && Size == OffsetAndSize::Unknown &&
Ty) {
// No need to find a size if one is given.
if (Size == AA::OffsetAndSize::Unknown && Ty) {
const DataLayout &DL = A.getDataLayout();
TypeSize AccessSize = DL.getTypeStoreSize(Ty);
if (!AccessSize.isScalable())
Expand All @@ -1226,7 +1230,7 @@ struct AAPointerInfoFloating : public AAPointerInfoImpl {

/// Helper struct, will support ranges eventually.
struct OffsetInfo {
int64_t Offset = OffsetAndSize::Unassigned;
int64_t Offset = AA::OffsetAndSize::Unassigned;

bool operator==(const OffsetInfo &OI) const { return Offset == OI.Offset; }
};
Expand All @@ -1243,7 +1247,7 @@ struct AAPointerInfoFloating : public AAPointerInfoImpl {

auto HandlePassthroughUser = [&](Value *Usr, OffsetInfo PtrOI,
bool &Follow) {
assert(PtrOI.Offset != OffsetAndSize::Unassigned &&
assert(PtrOI.Offset != AA::OffsetAndSize::Unassigned &&
"Cannot pass through if the input Ptr was not visited!");
OffsetInfo &UsrOI = OffsetInfoMap[Usr];
UsrOI = PtrOI;
Expand Down Expand Up @@ -1283,11 +1287,11 @@ struct AAPointerInfoFloating : public AAPointerInfoImpl {

// TODO: Use range information.
APInt GEPOffset(DL.getIndexTypeSizeInBits(GEP->getType()), 0);
if (PtrOI.Offset == OffsetAndSize::Unknown ||
if (PtrOI.Offset == AA::OffsetAndSize::Unknown ||
!GEP->accumulateConstantOffset(DL, GEPOffset)) {
LLVM_DEBUG(dbgs() << "[AAPointerInfo] GEP offset not constant "
<< *GEP << "\n");
UsrOI.Offset = OffsetAndSize::Unknown;
UsrOI.Offset = AA::OffsetAndSize::Unknown;
Follow = true;
return true;
}
Expand Down Expand Up @@ -1315,17 +1319,17 @@ struct AAPointerInfoFloating : public AAPointerInfoImpl {

// Check if the PHI operand has already an unknown offset as we can't
// improve on that anymore.
if (PtrOI.Offset == OffsetAndSize::Unknown) {
if (PtrOI.Offset == AA::OffsetAndSize::Unknown) {
LLVM_DEBUG(dbgs() << "[AAPointerInfo] PHI operand offset unknown "
<< *CurPtr << " in " << *Usr << "\n");
Follow = UsrOI.Offset != OffsetAndSize::Unknown;
Follow = UsrOI.Offset != AA::OffsetAndSize::Unknown;
UsrOI = PtrOI;
return true;
}

// Check if the PHI is invariant (so far).
if (UsrOI == PtrOI) {
assert(PtrOI.Offset != OffsetAndSize::Unassigned &&
assert(PtrOI.Offset != AA::OffsetAndSize::Unassigned &&
"Cannot assign if the current Ptr was not visited!");
LLVM_DEBUG(dbgs() << "[AAPointerInfo] PHI is invariant (so far)");
return true;
Expand All @@ -1352,7 +1356,7 @@ struct AAPointerInfoFloating : public AAPointerInfoImpl {

// TODO: Approximate in case we know the direction of the recurrence.
UsrOI = PtrOI;
UsrOI.Offset = OffsetAndSize::Unknown;
UsrOI.Offset = AA::OffsetAndSize::Unknown;
Follow = true;
return true;
}
Expand Down Expand Up @@ -1495,7 +1499,7 @@ struct AAPointerInfoCallSiteArgument final : AAPointerInfoFloating {
// accessed.
if (auto *MI = dyn_cast_or_null<MemIntrinsic>(getCtxI())) {
ConstantInt *Length = dyn_cast<ConstantInt>(MI->getLength());
int64_t LengthVal = OffsetAndSize::Unknown;
int64_t LengthVal = AA::OffsetAndSize::Unknown;
if (Length)
LengthVal = Length->getSExtValue();
Value &Ptr = getAssociatedValue();
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -44,7 +44,7 @@ entry:
;.
; TUNIT: attributes #[[ATTR0]] = { nofree norecurse nosync nounwind readnone willreturn }
;.
; CGSCC: attributes #[[ATTR0:[0-9]+]] = { argmemonly nofree norecurse nosync nounwind readonly willreturn }
; CGSCC: attributes #[[ATTR1:[0-9]+]] = { nofree nosync nounwind readnone willreturn }
; CGSCC: attributes #[[ATTR2:[0-9]+]] = { nounwind readonly willreturn }
; CGSCC: attributes #[[ATTR0]] = { argmemonly nofree norecurse nosync nounwind readonly willreturn }
; CGSCC: attributes #[[ATTR1]] = { nofree nosync nounwind readnone willreturn }
; CGSCC: attributes #[[ATTR2]] = { nounwind readonly willreturn }
;.
Original file line number Diff line number Diff line change
Expand Up @@ -123,15 +123,15 @@ attributes #0 = { inlinehint norecurse nounwind uwtable "target-features"="+avx2
attributes #1 = { nounwind uwtable }
attributes #2 = { argmemonly nounwind }
;.
; TUNIT: attributes #[[ATTR0:[0-9]+]] = { argmemonly inlinehint nofree norecurse nosync nounwind willreturn uwtable "target-features"="+avx2" }
; TUNIT: attributes #[[ATTR1:[0-9]+]] = { argmemonly nofree norecurse nosync nounwind willreturn uwtable }
; TUNIT: attributes #[[ATTR0]] = { argmemonly inlinehint nofree norecurse nosync nounwind willreturn uwtable "target-features"="+avx2" }
; TUNIT: attributes #[[ATTR1]] = { argmemonly nofree norecurse nosync nounwind willreturn uwtable }
; TUNIT: attributes #[[ATTR2:[0-9]+]] = { argmemonly nocallback nofree nounwind willreturn writeonly }
; TUNIT: attributes #[[ATTR3:[0-9]+]] = { willreturn writeonly }
; TUNIT: attributes #[[ATTR4:[0-9]+]] = { nofree nosync nounwind willreturn }
; TUNIT: attributes #[[ATTR3]] = { willreturn writeonly }
; TUNIT: attributes #[[ATTR4]] = { nofree nosync nounwind willreturn }
;.
; CGSCC: attributes #[[ATTR0:[0-9]+]] = { argmemonly inlinehint nofree norecurse nosync nounwind willreturn uwtable "target-features"="+avx2" }
; CGSCC: attributes #[[ATTR1:[0-9]+]] = { argmemonly nofree nosync nounwind willreturn uwtable }
; CGSCC: attributes #[[ATTR0]] = { argmemonly inlinehint nofree norecurse nosync nounwind willreturn uwtable "target-features"="+avx2" }
; CGSCC: attributes #[[ATTR1]] = { argmemonly nofree nosync nounwind willreturn uwtable }
; CGSCC: attributes #[[ATTR2:[0-9]+]] = { argmemonly nocallback nofree nounwind willreturn writeonly }
; CGSCC: attributes #[[ATTR3:[0-9]+]] = { willreturn writeonly }
; CGSCC: attributes #[[ATTR4:[0-9]+]] = { nounwind willreturn }
; CGSCC: attributes #[[ATTR3]] = { willreturn writeonly }
; CGSCC: attributes #[[ATTR4]] = { nounwind willreturn }
;.
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
; 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-max-iterations-verify -attributor-annotate-decl-cs -attributor-max-iterations=5 -S < %s | FileCheck %s --check-prefixes=CHECK,TUNIT
; RUN: opt -aa-pipeline=basic-aa -passes=attributor -attributor-manifest-internal -attributor-max-iterations-verify -attributor-annotate-decl-cs -attributor-max-iterations=2 -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

%T = type { i32, i32, i32, i32 }
Expand All @@ -9,14 +9,11 @@
; CHECK: @[[G:[a-zA-Z0-9_$"\\.-]+]] = constant [[T:%.*]] { i32 0, i32 0, i32 17, i32 25 }
;.
define internal i32 @test(%T* %p) {
; CHECK: Function Attrs: nofree norecurse nosync nounwind readnone willreturn
; CHECK-LABEL: define {{[^@]+}}@test
; CHECK-SAME: () #[[ATTR0:[0-9]+]] {
; CHECK-NEXT: entry:
; CHECK-NEXT: [[A:%.*]] = load i32, i32* getelementptr inbounds ([[T:%.*]], %T* @G, i64 0, i32 3), align 4
; CHECK-NEXT: [[B:%.*]] = load i32, i32* getelementptr inbounds ([[T]], %T* @G, i64 0, i32 2), align 8
; CHECK-NEXT: [[V:%.*]] = add i32 [[A]], [[B]]
; CHECK-NEXT: ret i32 [[V]]
; CGSCC: Function Attrs: nofree norecurse nosync nounwind readnone willreturn
; CGSCC-LABEL: define {{[^@]+}}@test
; CGSCC-SAME: () #[[ATTR0:[0-9]+]] {
; CGSCC-NEXT: entry:
; CGSCC-NEXT: ret i32 42
;
entry:
%a.gep = getelementptr %T, %T* %p, i64 0, i32 3
Expand All @@ -28,18 +25,18 @@ entry:
}

define i32 @caller() {
;
; TUNIT: Function Attrs: nofree norecurse nosync nounwind readnone willreturn
; TUNIT-LABEL: define {{[^@]+}}@caller
; TUNIT-SAME: () #[[ATTR0]] {
; TUNIT-SAME: () #[[ATTR0:[0-9]+]] {
; TUNIT-NEXT: entry:
; TUNIT-NEXT: [[V:%.*]] = call i32 @test() #[[ATTR1:[0-9]+]]
; TUNIT-NEXT: ret i32 [[V]]
; TUNIT-NEXT: ret i32 42
;
; CGSCC: Function Attrs: nofree nosync nounwind readnone willreturn
; CGSCC-LABEL: define {{[^@]+}}@caller
; CGSCC-SAME: () #[[ATTR1:[0-9]+]] {
; CGSCC-NEXT: entry:
; CGSCC-NEXT: [[V:%.*]] = call i32 @test() #[[ATTR2:[0-9]+]]
; CGSCC-NEXT: [[V:%.*]] = call noundef i32 @test() #[[ATTR2:[0-9]+]]
; CGSCC-NEXT: ret i32 [[V]]
;
entry:
Expand All @@ -48,7 +45,6 @@ entry:
}
;.
; TUNIT: attributes #[[ATTR0]] = { nofree norecurse nosync nounwind readnone willreturn }
; TUNIT: attributes #[[ATTR1]] = { nofree nosync nounwind readnone willreturn }
;.
; CGSCC: attributes #[[ATTR0]] = { nofree norecurse nosync nounwind readnone willreturn }
; CGSCC: attributes #[[ATTR1]] = { nofree nosync nounwind readnone willreturn }
Expand Down
10 changes: 5 additions & 5 deletions llvm/test/Transforms/Attributor/ArgumentPromotion/alignment.ll
Original file line number Diff line number Diff line change
Expand Up @@ -104,9 +104,9 @@ define i32 @callercaller() {
;.
; TUNIT: attributes #[[ATTR0]] = { nofree norecurse nosync nounwind readnone willreturn }
;.
; CGSCC: attributes #[[ATTR0:[0-9]+]] = { argmemonly nofree norecurse nosync nounwind readonly willreturn }
; CGSCC: attributes #[[ATTR1:[0-9]+]] = { argmemonly nofree nosync nounwind willreturn }
; CGSCC: attributes #[[ATTR2:[0-9]+]] = { nofree nosync nounwind readnone willreturn }
; CGSCC: attributes #[[ATTR3:[0-9]+]] = { readonly willreturn }
; CGSCC: attributes #[[ATTR4:[0-9]+]] = { nounwind willreturn }
; CGSCC: attributes #[[ATTR0]] = { argmemonly nofree norecurse nosync nounwind readonly willreturn }
; CGSCC: attributes #[[ATTR1]] = { argmemonly nofree nosync nounwind willreturn }
; CGSCC: attributes #[[ATTR2]] = { nofree nosync nounwind readnone willreturn }
; CGSCC: attributes #[[ATTR3]] = { readonly willreturn }
; CGSCC: attributes #[[ATTR4]] = { nounwind willreturn }
;.
10 changes: 5 additions & 5 deletions llvm/test/Transforms/Attributor/ArgumentPromotion/attrs.ll
Original file line number Diff line number Diff line change
Expand Up @@ -82,10 +82,10 @@ entry:
ret i32 %c
}
;.
; TUNIT: attributes #[[ATTR0:[0-9]+]] = { argmemonly nofree norecurse nosync nounwind willreturn }
; TUNIT: attributes #[[ATTR1:[0-9]+]] = { nofree nosync nounwind willreturn }
; TUNIT: attributes #[[ATTR0]] = { argmemonly nofree norecurse nosync nounwind willreturn }
; TUNIT: attributes #[[ATTR1]] = { nofree nosync nounwind willreturn }
;.
; CGSCC: attributes #[[ATTR0:[0-9]+]] = { argmemonly nofree norecurse nosync nounwind willreturn }
; CGSCC: attributes #[[ATTR1:[0-9]+]] = { argmemonly nofree nosync nounwind willreturn }
; CGSCC: attributes #[[ATTR2:[0-9]+]] = { nounwind willreturn }
; CGSCC: attributes #[[ATTR0]] = { argmemonly nofree norecurse nosync nounwind willreturn }
; CGSCC: attributes #[[ATTR1]] = { argmemonly nofree nosync nounwind willreturn }
; CGSCC: attributes #[[ATTR2]] = { nounwind willreturn }
;.
10 changes: 5 additions & 5 deletions llvm/test/Transforms/Attributor/ArgumentPromotion/basictest.ll
Original file line number Diff line number Diff line change
Expand Up @@ -57,9 +57,9 @@ define i32 @callercaller() {
;.
; TUNIT: attributes #[[ATTR0]] = { nofree norecurse nosync nounwind readnone willreturn }
;.
; CGSCC: attributes #[[ATTR0:[0-9]+]] = { argmemonly nofree norecurse nosync nounwind readonly willreturn }
; CGSCC: attributes #[[ATTR1:[0-9]+]] = { argmemonly nofree nosync nounwind willreturn }
; CGSCC: attributes #[[ATTR2:[0-9]+]] = { nofree nosync nounwind readnone willreturn }
; CGSCC: attributes #[[ATTR3:[0-9]+]] = { readonly willreturn }
; CGSCC: attributes #[[ATTR4:[0-9]+]] = { nounwind willreturn }
; CGSCC: attributes #[[ATTR0]] = { argmemonly nofree norecurse nosync nounwind readonly willreturn }
; CGSCC: attributes #[[ATTR1]] = { argmemonly nofree nosync nounwind willreturn }
; CGSCC: attributes #[[ATTR2]] = { nofree nosync nounwind readnone willreturn }
; CGSCC: attributes #[[ATTR3]] = { readonly willreturn }
; CGSCC: attributes #[[ATTR4]] = { nounwind willreturn }
;.
10 changes: 5 additions & 5 deletions llvm/test/Transforms/Attributor/ArgumentPromotion/byval-2.ll
Original file line number Diff line number Diff line change
Expand Up @@ -72,10 +72,10 @@ entry:
ret i32 0
}
;.
; TUNIT: attributes #[[ATTR0:[0-9]+]] = { argmemonly nofree norecurse nosync nounwind willreturn }
; TUNIT: attributes #[[ATTR1:[0-9]+]] = { nofree nosync nounwind willreturn }
; TUNIT: attributes #[[ATTR0]] = { argmemonly nofree norecurse nosync nounwind willreturn }
; TUNIT: attributes #[[ATTR1]] = { nofree nosync nounwind willreturn }
;.
; CGSCC: attributes #[[ATTR0:[0-9]+]] = { argmemonly nofree norecurse nosync nounwind willreturn }
; CGSCC: attributes #[[ATTR1:[0-9]+]] = { argmemonly nofree nosync nounwind willreturn }
; CGSCC: attributes #[[ATTR2:[0-9]+]] = { nounwind willreturn }
; CGSCC: attributes #[[ATTR0]] = { argmemonly nofree norecurse nosync nounwind willreturn }
; CGSCC: attributes #[[ATTR1]] = { argmemonly nofree nosync nounwind willreturn }
; CGSCC: attributes #[[ATTR2]] = { nounwind willreturn }
;.
12 changes: 6 additions & 6 deletions llvm/test/Transforms/Attributor/ArgumentPromotion/byval.ll
Original file line number Diff line number Diff line change
Expand Up @@ -104,11 +104,11 @@ entry:


;.
; TUNIT: attributes #[[ATTR0:[0-9]+]] = { argmemonly nofree norecurse nosync nounwind willreturn }
; TUNIT: attributes #[[ATTR1:[0-9]+]] = { nofree norecurse nosync nounwind readnone willreturn }
; TUNIT: attributes #[[ATTR2:[0-9]+]] = { nofree nosync nounwind willreturn }
; TUNIT: attributes #[[ATTR0]] = { argmemonly nofree norecurse nosync nounwind willreturn }
; TUNIT: attributes #[[ATTR1]] = { nofree norecurse nosync nounwind readnone willreturn }
; TUNIT: attributes #[[ATTR2]] = { nofree nosync nounwind willreturn }
;.
; CGSCC: attributes #[[ATTR0:[0-9]+]] = { argmemonly nofree norecurse nosync nounwind willreturn }
; CGSCC: attributes #[[ATTR1:[0-9]+]] = { nofree nosync nounwind readnone willreturn }
; CGSCC: attributes #[[ATTR2:[0-9]+]] = { nounwind willreturn }
; CGSCC: attributes #[[ATTR0]] = { argmemonly nofree norecurse nosync nounwind willreturn }
; CGSCC: attributes #[[ATTR1]] = { nofree nosync nounwind readnone willreturn }
; CGSCC: attributes #[[ATTR2]] = { nounwind willreturn }
;.
Original file line number Diff line number Diff line change
Expand Up @@ -49,7 +49,7 @@ define i32 @foo() {
;.
; TUNIT: attributes #[[ATTR0]] = { nofree norecurse nosync nounwind readnone willreturn }
;.
; CGSCC: attributes #[[ATTR0:[0-9]+]] = { argmemonly nofree norecurse nosync nounwind readonly willreturn }
; CGSCC: attributes #[[ATTR1:[0-9]+]] = { nofree nosync nounwind readnone willreturn }
; CGSCC: attributes #[[ATTR2:[0-9]+]] = { readonly willreturn }
; CGSCC: attributes #[[ATTR0]] = { argmemonly nofree norecurse nosync nounwind readonly willreturn }
; CGSCC: attributes #[[ATTR1]] = { nofree nosync nounwind readnone willreturn }
; CGSCC: attributes #[[ATTR2]] = { readonly willreturn }
;.
7 changes: 2 additions & 5 deletions llvm/test/Transforms/Attributor/ArgumentPromotion/fp80.ll
Original file line number Diff line number Diff line change
Expand Up @@ -25,13 +25,10 @@ define void @run() {
; TUNIT-NEXT: entry:
; TUNIT-NEXT: unreachable
;
; CGSCC: Function Attrs: nofree nosync nounwind readonly willreturn
; CGSCC: Function Attrs: nofree nosync nounwind readnone willreturn
; CGSCC-LABEL: define {{[^@]+}}@run
; CGSCC-SAME: () #[[ATTR0:[0-9]+]] {
; CGSCC-NEXT: entry:
; CGSCC-NEXT: [[TMP0:%.*]] = load i32, i32* getelementptr inbounds ([[STRUCT_FOO:%.*]], %struct.Foo* @a, i32 0, i32 0), align 8
; CGSCC-NEXT: [[A_0_1:%.*]] = getelementptr [[STRUCT_FOO]], %struct.Foo* @a, i64 0, i32 1
; CGSCC-NEXT: [[TMP1:%.*]] = load i64, i64* [[A_0_1]], align 8
; CGSCC-NEXT: unreachable
;
entry:
Expand Down Expand Up @@ -109,7 +106,7 @@ loop:
;.
; TUNIT: attributes #[[ATTR0]] = { nofree norecurse nosync nounwind readnone willreturn }
;.
; CGSCC: attributes #[[ATTR0]] = { nofree nosync nounwind readonly willreturn }
; CGSCC: attributes #[[ATTR0]] = { nofree nosync nounwind readnone willreturn }
; CGSCC: attributes #[[ATTR1]] = { nofree norecurse nosync nounwind readnone willreturn }
; CGSCC: attributes #[[ATTR2]] = { nofree norecurse noreturn nosync nounwind readnone }
;.
Original file line number Diff line number Diff line change
Expand Up @@ -61,7 +61,7 @@ declare void @llvm.dbg.value(metadata, metadata, metadata)
; CGSCC: [[META0:![0-9]+]] = distinct !DICompileUnit(language: DW_LANG_C, file: !1, isOptimized: false, runtimeVersion: 0, emissionKind: NoDebug)
; CGSCC: [[META1:![0-9]+]] = !DIFile(filename: "test.c", directory: "")
; CGSCC: [[META2:![0-9]+]] = !{i32 2, !"Debug Info Version", i32 3}
; CGSCC: [[META3:![0-9]+]] = !DILocalVariable(name: "p", scope: !4)
; CGSCC: [[META3]] = !DILocalVariable(name: "p", scope: !4)
; CGSCC: [[META4:![0-9]+]] = distinct !DISubprogram(name: "bar", scope: null, spFlags: DISPFlagDefinition, unit: !0)
; CGSCC: [[META5:![0-9]+]] = !DILocation(line: 1, column: 1, scope: !4)
; CGSCC: [[DBG5]] = !DILocation(line: 1, column: 1, scope: !4)
;.
6 changes: 3 additions & 3 deletions llvm/test/Transforms/Attributor/ArgumentPromotion/sret.ll
Original file line number Diff line number Diff line change
Expand Up @@ -60,7 +60,7 @@ define void @f() {
; TUNIT: attributes #[[ATTR1]] = { nofree norecurse nosync nounwind readnone willreturn }
; TUNIT: attributes #[[ATTR2]] = { nofree nosync nounwind willreturn writeonly }
;.
; CGSCC: attributes #[[ATTR0:[0-9]+]] = { argmemonly nofree norecurse nosync nounwind willreturn }
; CGSCC: attributes #[[ATTR1:[0-9]+]] = { nofree nosync nounwind readnone willreturn }
; CGSCC: attributes #[[ATTR2:[0-9]+]] = { nounwind willreturn }
; CGSCC: attributes #[[ATTR0]] = { argmemonly nofree norecurse nosync nounwind willreturn }
; CGSCC: attributes #[[ATTR1]] = { nofree nosync nounwind readnone willreturn }
; CGSCC: attributes #[[ATTR2]] = { nounwind willreturn }
;.
Original file line number Diff line number Diff line change
Expand Up @@ -172,10 +172,10 @@ entry:
ret i32 %result
}
;.
; TUNIT: attributes #[[ATTR0:[0-9]+]] = { nounwind }
; TUNIT: attributes #[[ATTR1:[0-9]+]] = { argmemonly nofree norecurse nosync nounwind readonly willreturn }
; TUNIT: attributes #[[ATTR2:[0-9]+]] = { nounwind readonly }
; TUNIT: attributes #[[ATTR0]] = { nounwind }
; TUNIT: attributes #[[ATTR1]] = { argmemonly nofree norecurse nosync nounwind readonly willreturn }
; TUNIT: attributes #[[ATTR2]] = { nounwind readonly }
;.
; CGSCC: attributes #[[ATTR0:[0-9]+]] = { nounwind }
; CGSCC: attributes #[[ATTR1:[0-9]+]] = { argmemonly nofree norecurse nosync nounwind readonly willreturn }
; CGSCC: attributes #[[ATTR0]] = { nounwind }
; CGSCC: attributes #[[ATTR1]] = { argmemonly nofree norecurse nosync nounwind readonly willreturn }
;.
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
; 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-max-iterations-verify -attributor-annotate-decl-cs -attributor-max-iterations=15 -S < %s | FileCheck %s --check-prefixes=CHECK,TUNIT
; RUN: opt -aa-pipeline=basic-aa -passes=attributor -attributor-manifest-internal -attributor-max-iterations-verify -attributor-annotate-decl-cs -attributor-max-iterations=16 -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
;
; void bar(int, float, double);
Expand Down Expand Up @@ -107,7 +107,7 @@ define internal void @.omp_outlined.(i32* noalias %.global_tid., i32* noalias %.
; TUNIT: omp.inner.for.body:
; TUNIT-NEXT: [[ADD10:%.*]] = add nsw i32 [[DOTOMP_IV_0]], 2
; TUNIT-NEXT: [[TMP11:%.*]] = load double, double* [[CONV]], align 8
; TUNIT-NEXT: call void @bar(i32 [[ADD10]], float 3.000000e+00, double [[TMP11]])
; TUNIT-NEXT: call void @bar(i32 [[ADD10]], float 3.000000e+00, double noundef [[TMP11]])
; TUNIT-NEXT: br label [[OMP_BODY_CONTINUE:%.*]]
; TUNIT: omp.body.continue:
; TUNIT-NEXT: br label [[OMP_INNER_FOR_INC]]
Expand Down Expand Up @@ -168,7 +168,7 @@ define internal void @.omp_outlined.(i32* noalias %.global_tid., i32* noalias %.
; CGSCC-NEXT: [[ADD10:%.*]] = add nsw i32 [[DOTOMP_IV_0]], 2
; CGSCC-NEXT: [[TMP10:%.*]] = load float, float* [[P]], align 4
; CGSCC-NEXT: [[TMP11:%.*]] = load double, double* [[CONV]], align 8
; CGSCC-NEXT: call void @bar(i32 [[ADD10]], float [[TMP10]], double [[TMP11]])
; CGSCC-NEXT: call void @bar(i32 [[ADD10]], float [[TMP10]], double noundef [[TMP11]])
; CGSCC-NEXT: br label [[OMP_BODY_CONTINUE:%.*]]
; CGSCC: omp.body.continue:
; CGSCC-NEXT: br label [[OMP_INNER_FOR_INC]]
Expand Down
2 changes: 1 addition & 1 deletion llvm/test/Transforms/Attributor/align.ll
Original file line number Diff line number Diff line change
Expand Up @@ -1110,7 +1110,7 @@ define i8* @aligned_8_return_caller(i8* align(16) %a, i1 %c1, i1 %c2) {
; CGSCC: Function Attrs: nofree nosync nounwind readnone willreturn
; CGSCC-LABEL: define {{[^@]+}}@aligned_8_return_caller
; CGSCC-SAME: (i8* nofree readnone align 16 [[A:%.*]], i1 [[C1:%.*]], i1 [[C2:%.*]]) #[[ATTR12:[0-9]+]] {
; CGSCC-NEXT: [[R:%.*]] = call align 8 i8* @aligned_8_return(i8* noalias nofree readnone align 16 [[A]], i1 [[C1]], i1 [[C2]]) #[[ATTR13:[0-9]+]]
; CGSCC-NEXT: [[R:%.*]] = call align 8 i8* @aligned_8_return(i8* noalias nofree readnone align 16 [[A]], i1 [[C1]], i1 [[C2]]) #[[ATTR13]]
; CGSCC-NEXT: ret i8* [[R]]
;
%r = call i8* @aligned_8_return(i8* %a, i1 %c1, i1 %c2)
Expand Down
2 changes: 1 addition & 1 deletion llvm/test/Transforms/Attributor/heap_to_stack_gpu.ll
Original file line number Diff line number Diff line change
Expand Up @@ -625,7 +625,7 @@ define void @test17() {
define void @test17b() {
; CHECK-LABEL: define {{[^@]+}}@test17b() {
; CHECK-NEXT: [[TMP1:%.*]] = tail call noalias i8* @__kmpc_alloc_shared(i64 noundef 4)
; CHECK-NEXT: tail call void @usei8(i8* nofree [[TMP1]]) #[[ATTR6:[0-9]+]]
; CHECK-NEXT: tail call void @usei8(i8* nofree [[TMP1]]) #[[ATTR6]]
; CHECK-NEXT: tail call void @__kmpc_free_shared(i8* nocapture [[TMP1]], i64 noundef 4)
; CHECK-NEXT: ret void
;
Expand Down
4 changes: 2 additions & 2 deletions llvm/test/Transforms/Attributor/internal-noalias.ll
Original file line number Diff line number Diff line change
Expand Up @@ -187,7 +187,7 @@ define i32 @visible_local_3() {
;
; CGSCC: Function Attrs: nofree nosync nounwind readnone willreturn
; CGSCC-LABEL: define {{[^@]+}}@visible_local_3
; CGSCC-SAME: () #[[ATTR3:[0-9]+]] {
; CGSCC-SAME: () #[[ATTR3]] {
; CGSCC-NEXT: [[B:%.*]] = alloca i32, align 4
; CGSCC-NEXT: store i32 5, i32* [[B]], align 4
; CGSCC-NEXT: [[CALL:%.*]] = call i32 @noalias_args_argmem_rn(i32* noalias nocapture nofree noundef nonnull align 4 dereferenceable(4) [[B]]) #[[ATTR7:[0-9]+]]
Expand All @@ -214,6 +214,6 @@ attributes #1 = { argmemonly noinline nounwind uwtable willreturn}
; CGSCC: attributes #[[ATTR3]] = { nofree nosync nounwind readnone willreturn }
; CGSCC: attributes #[[ATTR4]] = { argmemonly nofree noinline norecurse nosync nounwind willreturn uwtable }
; CGSCC: attributes #[[ATTR5]] = { readonly }
; CGSCC: attributes #[[ATTR6:[0-9]+]] = { readonly willreturn }
; CGSCC: attributes #[[ATTR6]] = { readonly willreturn }
; CGSCC: attributes #[[ATTR7]] = { nounwind willreturn }
;.
2 changes: 1 addition & 1 deletion llvm/test/Transforms/Attributor/nocapture-2.ll
Original file line number Diff line number Diff line change
Expand Up @@ -259,7 +259,7 @@ cond.end: ; preds = %cond.false, %cond.t
define i8* @scc_C(i16* dereferenceable_or_null(2) %a) {
; CHECK: Function Attrs: nofree nosync nounwind readnone
; CHECK-LABEL: define {{[^@]+}}@scc_C
; CHECK-SAME: (i16* nofree readnone dereferenceable_or_null(4) "no-capture-maybe-returned" [[A:%.*]]) #[[ATTR2:[0-9]+]] {
; CHECK-SAME: (i16* nofree readnone dereferenceable_or_null(4) "no-capture-maybe-returned" [[A:%.*]]) #[[ATTR2]] {
; CHECK-NEXT: entry:
; CHECK-NEXT: [[BC:%.*]] = bitcast i16* [[A]] to i32*
; CHECK-NEXT: [[CALL:%.*]] = call dereferenceable_or_null(4) float* @scc_A(i32* noalias nofree readnone dereferenceable_or_null(4) "no-capture-maybe-returned" [[BC]]) #[[ATTR2]]
Expand Down
6 changes: 3 additions & 3 deletions llvm/test/Transforms/Attributor/potential.ll
Original file line number Diff line number Diff line change
Expand Up @@ -698,7 +698,7 @@ define i1 @potential_test16(i1 %c0, i1 %c1) {
; CGSCC: attributes #[[ATTR1]] = { nofree nosync nounwind readnone willreturn }
; CGSCC: attributes #[[ATTR2]] = { readnone willreturn }
;.
; TUNIT: [[META0:![0-9]+]] = !{i32 0, i32 2}
; TUNIT: [[META1:![0-9]+]] = !{i32 0, i32 3}
; TUNIT: [[META2:![0-9]+]] = !{i32 -1, i32 1}
; TUNIT: [[RNG0]] = !{i32 0, i32 2}
; TUNIT: [[RNG1]] = !{i32 0, i32 3}
; TUNIT: [[RNG2]] = !{i32 -1, i32 1}
;.
Original file line number Diff line number Diff line change
Expand Up @@ -481,7 +481,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:[0-9]+]]
; TUNIT-NEXT: [[CALL:%.*]] = call [[S:%.*]] @t4a(ptr nofree noundef nonnull writeonly align 8 dereferenceable(8) [[THIS]]) #[[ATTR5]]
; TUNIT-NEXT: ret double 0.000000e+00
;
; CGSCC: Function Attrs: argmemonly nofree nosync nounwind willreturn
Expand Down Expand Up @@ -613,7 +613,7 @@ entry:
;.
; TUNIT: attributes #[[ATTR0]] = { argmemonly nofree norecurse nosync nounwind willreturn writeonly }
; TUNIT: attributes #[[ATTR1]] = { argmemonly nofree norecurse nosync nounwind willreturn }
; TUNIT: attributes #[[ATTR2:[0-9]+]] = { nofree norecurse noreturn nosync nounwind readnone }
; TUNIT: attributes #[[ATTR2]] = { nofree norecurse noreturn nosync nounwind readnone }
; TUNIT: attributes #[[ATTR3]] = { nofree norecurse nosync nounwind willreturn writeonly }
; TUNIT: attributes #[[ATTR4]] = { nofree nosync nounwind willreturn }
; TUNIT: attributes #[[ATTR5]] = { nofree nosync nounwind willreturn writeonly }
Expand All @@ -623,7 +623,7 @@ entry:
; CGSCC: attributes #[[ATTR2]] = { argmemonly nofree nosync nounwind willreturn }
; CGSCC: attributes #[[ATTR3]] = { argmemonly nofree norecurse nosync nounwind willreturn writeonly }
; CGSCC: attributes #[[ATTR4]] = { argmemonly nofree norecurse nosync nounwind willreturn }
; CGSCC: attributes #[[ATTR5:[0-9]+]] = { nofree norecurse noreturn nosync nounwind readnone }
; CGSCC: attributes #[[ATTR5]] = { nofree norecurse noreturn nosync nounwind readnone }
; CGSCC: attributes #[[ATTR6]] = { nounwind willreturn writeonly }
; CGSCC: attributes #[[ATTR7]] = { readnone willreturn }
; CGSCC: attributes #[[ATTR8]] = { nounwind willreturn }
Expand Down
221 changes: 221 additions & 0 deletions llvm/test/Transforms/Attributor/value-simplify-pointer-info-struct.ll
Original file line number Diff line number Diff line change
@@ -0,0 +1,221 @@
; NOTE: Assertions have been autogenerated by utils/update_test_checks.py UTC_ARGS: --function-signature --check-attributes --check-globals
; RUN: opt -attributor -enable-new-pm=0 -attributor-manifest-internal -attributor-max-iterations-verify -attributor-annotate-decl-cs -attributor-max-iterations=9 -S < %s | FileCheck %s --check-prefixes=CHECK,NOT_CGSCC_NPM,NOT_CGSCC_OPM,NOT_TUNIT_NPM,IS__TUNIT____,IS________OPM,IS__TUNIT_OPM
; RUN: opt -aa-pipeline=basic-aa -passes=attributor -attributor-manifest-internal -attributor-max-iterations-verify -attributor-annotate-decl-cs -attributor-max-iterations=9 -S < %s | FileCheck %s --check-prefixes=CHECK,NOT_CGSCC_OPM,NOT_CGSCC_NPM,NOT_TUNIT_OPM,IS__TUNIT____,IS________NPM,IS__TUNIT_NPM
; RUN: opt -attributor-cgscc -enable-new-pm=0 -attributor-manifest-internal -attributor-annotate-decl-cs -S < %s | FileCheck %s --check-prefixes=CHECK,NOT_TUNIT_NPM,NOT_TUNIT_OPM,NOT_CGSCC_NPM,IS__CGSCC____,IS________OPM,IS__CGSCC_OPM
; RUN: opt -aa-pipeline=basic-aa -passes=attributor-cgscc -attributor-manifest-internal -attributor-annotate-decl-cs -S < %s | FileCheck %s --check-prefixes=CHECK,NOT_TUNIT_NPM,NOT_TUNIT_OPM,NOT_CGSCC_OPM,IS__CGSCC____,IS________NPM,IS__CGSCC_NPM
;
target datalayout = "e-m:e-p270:32:32-p271:32:32-p272:64:64-i64:64-f80:128-n8:16:32:64-S128"

%struct.S = type { i32, double, ptr }

; struct S {
; int a;
; double b;
; struct S* c;
; };
;
; static const struct S GlobalS = {42, 3.14, 0};
;
; int testOneFieldGlobalS() {
; int r = 0;
; if (GlobalS.a != 42)
; r += 1;
; if (GlobalS.b == 3.14)
; r += 2;
; if (GlobalS.c)
; r += 4;
; return r;
; }
;
@GlobalS = internal constant %struct.S { i32 42, double 3.140000e+00, ptr null }, align 8

;.
; CHECK: @[[GLOBALS:[a-zA-Z0-9_$"\\.-]+]] = internal constant [[STRUCT_S:%.*]] { i32 42, double 3.140000e+00, ptr null }, align 8
;.
define i32 @testOneFieldGlobalS() {
; CHECK: Function Attrs: nofree norecurse nosync nounwind readnone willreturn
; CHECK-LABEL: define {{[^@]+}}@testOneFieldGlobalS
; CHECK-SAME: () #[[ATTR0:[0-9]+]] {
; CHECK-NEXT: entry:
; CHECK-NEXT: br label [[IF_END:%.*]]
; CHECK: if.then:
; CHECK-NEXT: unreachable
; CHECK: if.end:
; CHECK-NEXT: br label [[IF_THEN2:%.*]]
; CHECK: if.then2:
; CHECK-NEXT: [[ADD3:%.*]] = add nsw i32 0, 2
; CHECK-NEXT: br label [[IF_END4:%.*]]
; CHECK: if.end4:
; CHECK-NEXT: br label [[IF_END7:%.*]]
; CHECK: if.then5:
; CHECK-NEXT: unreachable
; CHECK: if.end7:
; CHECK-NEXT: ret i32 2
;
entry:
%i = load i32, ptr @GlobalS, align 8
%cmp = icmp ne i32 %i, 42
br i1 %cmp, label %if.then, label %if.end

if.then: ; preds = %entry
%add = add nsw i32 0, 1
br label %if.end

if.end: ; preds = %if.then, %entry
%r.0 = phi i32 [ %add, %if.then ], [ 0, %entry ]
%i1 = load double, ptr getelementptr inbounds (%struct.S, ptr @GlobalS, i32 0, i32 1), align 8
%cmp1 = fcmp oeq double %i1, 3.140000e+00
br i1 %cmp1, label %if.then2, label %if.end4

if.then2: ; preds = %if.end
%add3 = add nsw i32 %r.0, 2
br label %if.end4

if.end4: ; preds = %if.then2, %if.end
%r.1 = phi i32 [ %add3, %if.then2 ], [ %r.0, %if.end ]
%i2 = load ptr, ptr getelementptr inbounds (%struct.S, ptr @GlobalS, i32 0, i32 2), align 8
%tobool = icmp ne ptr %i2, null
br i1 %tobool, label %if.then5, label %if.end7

if.then5: ; preds = %if.end4
%add6 = add nsw i32 %r.1, 4
br label %if.end7

if.end7: ; preds = %if.then5, %if.end4
%r.2 = phi i32 [ %add6, %if.then5 ], [ %r.1, %if.end4 ]
ret i32 %r.2
}

define i32 @testOneFieldGlobalS_type_mismatch() {
; CHECK: Function Attrs: nofree norecurse nosync nounwind readnone willreturn
; CHECK-LABEL: define {{[^@]+}}@testOneFieldGlobalS_type_mismatch
; CHECK-SAME: () #[[ATTR0]] {
; CHECK-NEXT: entry:
; CHECK-NEXT: [[I:%.*]] = load double, ptr @GlobalS, align 8
; CHECK-NEXT: [[IC:%.*]] = fptosi double [[I]] to i32
; CHECK-NEXT: [[CMP:%.*]] = icmp ne i32 [[IC]], 42
; CHECK-NEXT: br i1 [[CMP]], label [[IF_THEN:%.*]], label [[IF_END:%.*]]
; CHECK: if.then:
; CHECK-NEXT: [[ADD:%.*]] = add nsw i32 0, 1
; CHECK-NEXT: br label [[IF_END]]
; CHECK: if.end:
; CHECK-NEXT: [[R_0:%.*]] = phi i32 [ [[ADD]], [[IF_THEN]] ], [ 0, [[ENTRY:%.*]] ]
; CHECK-NEXT: [[I1:%.*]] = load i64, ptr getelementptr inbounds ([[STRUCT_S:%.*]], ptr @GlobalS, i32 0, i32 1), align 8
; CHECK-NEXT: [[I1C:%.*]] = sitofp i64 [[I1]] to double
; CHECK-NEXT: [[CMP1:%.*]] = fcmp oeq double [[I1C]], 3.140000e+00
; CHECK-NEXT: br i1 [[CMP1]], label [[IF_THEN2:%.*]], label [[IF_END4:%.*]]
; CHECK: if.then2:
; CHECK-NEXT: [[ADD3:%.*]] = add nsw i32 [[R_0]], 2
; CHECK-NEXT: br label [[IF_END4]]
; CHECK: if.end4:
; CHECK-NEXT: [[R_1:%.*]] = phi i32 [ [[ADD3]], [[IF_THEN2]] ], [ [[R_0]], [[IF_END]] ]
; CHECK-NEXT: br label [[IF_END7:%.*]]
; CHECK: if.then5:
; CHECK-NEXT: unreachable
; CHECK: if.end7:
; CHECK-NEXT: ret i32 [[R_1]]
;
entry:
%i = load double, ptr @GlobalS, align 8
%ic = fptosi double %i to i32
%cmp = icmp ne i32 %ic, 42
br i1 %cmp, label %if.then, label %if.end

if.then: ; preds = %entry
%add = add nsw i32 0, 1
br label %if.end

if.end: ; preds = %if.then, %entry
%r.0 = phi i32 [ %add, %if.then ], [ 0, %entry ]
%i1 = load i64, ptr getelementptr inbounds (%struct.S, ptr @GlobalS, i32 0, i32 1), align 8
%i1c = sitofp i64 %i1 to double
%cmp1 = fcmp oeq double %i1c, 3.140000e+00
br i1 %cmp1, label %if.then2, label %if.end4

if.then2: ; preds = %if.end
%add3 = add nsw i32 %r.0, 2
br label %if.end4

if.end4: ; preds = %if.then2, %if.end
%r.1 = phi i32 [ %add3, %if.then2 ], [ %r.0, %if.end ]
%i2 = load i64, ptr getelementptr inbounds (%struct.S, ptr @GlobalS, i32 0, i32 2), align 8
%i2c = inttoptr i64 %i2 to ptr
%tobool = icmp ne ptr %i2c, null
br i1 %tobool, label %if.then5, label %if.end7

if.then5: ; preds = %if.end4
%add6 = add nsw i32 %r.1, 4
br label %if.end7

if.end7: ; preds = %if.then5, %if.end4
%r.2 = phi i32 [ %add6, %if.then5 ], [ %r.1, %if.end4 ]
ret i32 %r.2
}

define i32 @testOneFieldGlobalS_byte_offset_wrong() {
; CHECK: Function Attrs: nofree norecurse nosync nounwind readnone willreturn
; CHECK-LABEL: define {{[^@]+}}@testOneFieldGlobalS_byte_offset_wrong
; CHECK-SAME: () #[[ATTR0]] {
; CHECK-NEXT: entry:
; CHECK-NEXT: [[I:%.*]] = load i32, ptr getelementptr inbounds (i32, ptr @GlobalS, i32 1), align 8
; CHECK-NEXT: [[CMP:%.*]] = icmp ne i32 [[I]], 42
; CHECK-NEXT: br i1 [[CMP]], label [[IF_THEN:%.*]], label [[IF_END:%.*]]
; CHECK: if.then:
; CHECK-NEXT: [[ADD:%.*]] = add nsw i32 0, 1
; CHECK-NEXT: br label [[IF_END]]
; CHECK: if.end:
; CHECK-NEXT: [[R_0:%.*]] = phi i32 [ [[ADD]], [[IF_THEN]] ], [ 0, [[ENTRY:%.*]] ]
; CHECK-NEXT: [[I1:%.*]] = load double, ptr getelementptr (double, ptr @GlobalS, i32 3), align 8
; CHECK-NEXT: [[CMP1:%.*]] = fcmp oeq double [[I1]], 3.140000e+00
; CHECK-NEXT: br i1 [[CMP1]], label [[IF_THEN2:%.*]], label [[IF_END4:%.*]]
; CHECK: if.then2:
; CHECK-NEXT: [[ADD3:%.*]] = add nsw i32 [[R_0]], 2
; CHECK-NEXT: br label [[IF_END4]]
; CHECK: if.end4:
; CHECK-NEXT: [[R_1:%.*]] = phi i32 [ [[ADD3]], [[IF_THEN2]] ], [ [[R_0]], [[IF_END]] ]
; CHECK-NEXT: [[I2:%.*]] = load ptr, ptr getelementptr (ptr, ptr @GlobalS, i32 11), align 8
; CHECK-NEXT: [[TOBOOL:%.*]] = icmp ne ptr [[I2]], null
; CHECK-NEXT: br i1 [[TOBOOL]], label [[IF_THEN5:%.*]], label [[IF_END7:%.*]]
; CHECK: if.then5:
; CHECK-NEXT: [[ADD6:%.*]] = add nsw i32 [[R_1]], 4
; CHECK-NEXT: br label [[IF_END7]]
; CHECK: if.end7:
; CHECK-NEXT: [[R_2:%.*]] = phi i32 [ [[ADD6]], [[IF_THEN5]] ], [ [[R_1]], [[IF_END4]] ]
; CHECK-NEXT: ret i32 [[R_2]]
;
entry:
%i = load i32, ptr getelementptr (i32, ptr @GlobalS, i32 1), align 8
%cmp = icmp ne i32 %i, 42
br i1 %cmp, label %if.then, label %if.end

if.then: ; preds = %entry
%add = add nsw i32 0, 1
br label %if.end

if.end: ; preds = %if.then, %entry
%r.0 = phi i32 [ %add, %if.then ], [ 0, %entry ]
%i1 = load double, ptr getelementptr (double, ptr @GlobalS, i32 3), align 8
%cmp1 = fcmp oeq double %i1, 3.140000e+00
br i1 %cmp1, label %if.then2, label %if.end4

if.then2: ; preds = %if.end
%add3 = add nsw i32 %r.0, 2
br label %if.end4

if.end4: ; preds = %if.then2, %if.end
%r.1 = phi i32 [ %add3, %if.then2 ], [ %r.0, %if.end ]
%i2 = load ptr, ptr getelementptr (ptr, ptr @GlobalS, i32 11), align 8
%tobool = icmp ne ptr %i2, null
br i1 %tobool, label %if.then5, label %if.end7

if.then5: ; preds = %if.end4
%add6 = add nsw i32 %r.1, 4
br label %if.end7

if.end7: ; preds = %if.then5, %if.end4
%r.2 = phi i32 [ %add6, %if.then5 ], [ %r.1, %if.end4 ]
ret i32 %r.2
}
;.
; CHECK: attributes #[[ATTR0]] = { nofree norecurse nosync nounwind readnone willreturn }
;.
4 changes: 2 additions & 2 deletions llvm/test/Transforms/Attributor/value-simplify.ll
Original file line number Diff line number Diff line change
Expand Up @@ -786,7 +786,7 @@ define internal i8 @callee(i8 %a) {
define void @user_as3() {
; TUNIT: Function Attrs: nofree norecurse nosync nounwind willreturn writeonly
; TUNIT-LABEL: define {{[^@]+}}@user_as3
; TUNIT-SAME: () #[[ATTR4:[0-9]+]] {
; TUNIT-SAME: () #[[ATTR4]] {
; TUNIT-NEXT: store i32 0, i32 addrspace(3)* @ConstAS3Ptr, align 4
; TUNIT-NEXT: ret void
;
Expand Down Expand Up @@ -839,7 +839,7 @@ define i1 @test_merge_with_undef_values_ptr(i1 %c) {
define internal i1 @undef_then_null(i1 %c, i32* %i32Aptr, i32* %i32Bptr) {
; CGSCC: Function Attrs: nofree nosync nounwind readnone willreturn
; CGSCC-LABEL: define {{[^@]+}}@undef_then_null
; CGSCC-SAME: (i1 [[C:%.*]]) #[[ATTR2:[0-9]+]] {
; CGSCC-SAME: (i1 [[C:%.*]]) #[[ATTR2]] {
; CGSCC-NEXT: br i1 [[C]], label [[A:%.*]], label [[B:%.*]]
; CGSCC: a:
; CGSCC-NEXT: ret i1 false
Expand Down
4 changes: 2 additions & 2 deletions llvm/test/Transforms/Attributor/willreturn.ll
Original file line number Diff line number Diff line change
Expand Up @@ -344,8 +344,8 @@ define void @f1() #0 {
define void @f2() #0 {
; CHECK: Function Attrs: noinline nounwind willreturn uwtable
; CHECK-LABEL: define {{[^@]+}}@f2
; CHECK-SAME: () #[[ATTR10:[0-9]+]] {
; CHECK-NEXT: tail call void @f1() #[[ATTR12:[0-9]+]]
; CHECK-SAME: () #[[ATTR10]] {
; CHECK-NEXT: tail call void @f1() #[[ATTR12]]
; CHECK-NEXT: ret void
;
tail call void @f1()
Expand Down