Skip to content

Commit

Permalink
[Attributor] Port AANoUndef to the isImpliedByIR interface
Browse files Browse the repository at this point in the history
  • Loading branch information
jdoerfert committed Jul 9, 2023
1 parent aae749b commit 59fd610
Show file tree
Hide file tree
Showing 40 changed files with 271 additions and 212 deletions.
12 changes: 12 additions & 0 deletions llvm/include/llvm/Transforms/IPO/Attributor.h
Original file line number Diff line number Diff line change
Expand Up @@ -5136,6 +5136,17 @@ struct AANoUndef
AANoUndef> {
AANoUndef(const IRPosition &IRP, Attributor &A) : IRAttribute(IRP) {}

/// See IRAttribute::isImpliedByUndef
static bool isImpliedByUndef() { return false; }

/// See IRAttribute::isImpliedByPoison
static bool isImpliedByPoison() { return false; }

/// See IRAttribute::isImpliedByIR
static bool isImpliedByIR(Attributor &A, const IRPosition &IRP,
Attribute::AttrKind ImpliedAttributeKind,
bool IgnoreSubsumingPositions = false);

/// Return true if we assume that the underlying value is noundef.
bool isAssumedNoUndef() const { return getAssumed(); }

Expand Down Expand Up @@ -6024,6 +6035,7 @@ bool hasAssumedIRAttr(Attributor &A, const AbstractAttribute *QueryingAA,
CASE(NoAlias, AANoAlias, );
CASE(NonNull, AANonNull, );
CASE(MustProgress, AAMustProgress, );
CASE(NoUndef, AANoUndef, );
CASE(ReadNone, AAMemoryBehavior, AAMemoryBehavior::NO_ACCESSES);
CASE(ReadOnly, AAMemoryBehavior, AAMemoryBehavior::NO_WRITES);
CASE(WriteOnly, AAMemoryBehavior, AAMemoryBehavior::NO_READS);
Expand Down
9 changes: 3 additions & 6 deletions llvm/lib/Transforms/IPO/Attributor.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -3331,8 +3331,7 @@ void Attributor::identifyDefaultAbstractAttributes(Function &F) {
AA::Intraprocedural);

// Every returned value might be marked noundef.
if (!Attrs.hasRetAttr(Attribute::NoUndef))
getOrCreateAAFor<AANoUndef>(RetPos);
checkAndQueryIRAttr<Attribute::NoUndef, AANoUndef>(RetPos, RetAttrs);

if (ReturnType->isPointerTy()) {

Expand Down Expand Up @@ -3369,8 +3368,7 @@ void Attributor::identifyDefaultAbstractAttributes(Function &F) {
getOrCreateAAFor<AAIsDead>(ArgPos);

// Every argument might be marked noundef.
if (!Attrs.hasParamAttr(ArgNo, Attribute::NoUndef))
getOrCreateAAFor<AANoUndef>(ArgPos);
checkAndQueryIRAttr<Attribute::NoUndef, AANoUndef>(ArgPos, ArgAttrs);

if (Arg.getType()->isPointerTy()) {
// Every argument with pointer type might be marked nonnull.
Expand Down Expand Up @@ -3457,8 +3455,7 @@ void Attributor::identifyDefaultAbstractAttributes(Function &F) {
AA::Intraprocedural);

// Every call site argument might be marked "noundef".
if (!CBAttrs.hasParamAttr(I, Attribute::NoUndef))
getOrCreateAAFor<AANoUndef>(CBArgPos);
checkAndQueryIRAttr<Attribute::NoUndef, AANoUndef>(CBArgPos, CBArgAttrs);

Type *ArgTy = CB.getArgOperand(I)->getType();

Expand Down
117 changes: 75 additions & 42 deletions llvm/lib/Transforms/IPO/AttributorAttributes.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -54,6 +54,7 @@
#include "llvm/IR/IntrinsicInst.h"
#include "llvm/IR/IntrinsicsAMDGPU.h"
#include "llvm/IR/IntrinsicsNVPTX.h"
#include "llvm/IR/LLVMContext.h"
#include "llvm/IR/NoFolder.h"
#include "llvm/IR/Value.h"
#include "llvm/IR/ValueHandle.h"
Expand Down Expand Up @@ -3230,9 +3231,10 @@ struct AAUndefinedBehaviorImpl : public AAUndefinedBehavior {
// (3) Simplified to null pointer where known to be nonnull.
// The argument is a poison value and violate noundef attribute.
IRPosition CalleeArgumentIRP = IRPosition::callsite_argument(CB, idx);
auto *NoUndefAA =
A.getAAFor<AANoUndef>(*this, CalleeArgumentIRP, DepClassTy::NONE);
if (!NoUndefAA || !NoUndefAA->isKnownNoUndef())
bool IsKnownNoUndef;
AA::hasAssumedIRAttr<Attribute::NoUndef>(
A, this, CalleeArgumentIRP, DepClassTy::NONE, IsKnownNoUndef);
if (!IsKnownNoUndef)
continue;
bool UsedAssumedInformation = false;
std::optional<Value *> SimplifiedVal =
Expand Down Expand Up @@ -3311,9 +3313,10 @@ struct AAUndefinedBehaviorImpl : public AAUndefinedBehavior {
if (!getAnchorScope()->getReturnType()->isVoidTy()) {
const IRPosition &ReturnIRP = IRPosition::returned(*getAnchorScope());
if (!A.isAssumedDead(ReturnIRP, this, nullptr, UsedAssumedInformation)) {
auto *RetPosNoUndefAA =
A.getAAFor<AANoUndef>(*this, ReturnIRP, DepClassTy::NONE);
if (RetPosNoUndefAA && RetPosNoUndefAA->isKnownNoUndef())
bool IsKnownNoUndef;
AA::hasAssumedIRAttr<Attribute::NoUndef>(
A, this, ReturnIRP, DepClassTy::NONE, IsKnownNoUndef);
if (IsKnownNoUndef)
A.checkForAllInstructions(InspectReturnInstForUB, *this,
{Instruction::Ret}, UsedAssumedInformation,
/* CheckBBLivenessOnly */ true);
Expand Down Expand Up @@ -10176,27 +10179,39 @@ struct AAPotentialConstantValuesCallSiteArgument
STATS_DECLTRACK_CSARG_ATTR(potential_values)
}
};
} // namespace

/// ------------------------ NoUndef Attribute ---------------------------------
bool AANoUndef::isImpliedByIR(Attributor &A, const IRPosition &IRP,
Attribute::AttrKind ImpliedAttributeKind,
bool IgnoreSubsumingPositions) {
assert(ImpliedAttributeKind == Attribute::NoUndef &&
"Unexpected attribute kind");
if (A.hasAttr(IRP, {Attribute::NoUndef}, IgnoreSubsumingPositions,
Attribute::NoUndef))
return true;

Value &Val = IRP.getAssociatedValue();
if (IRP.getPositionKind() != IRPosition::IRP_RETURNED &&
isGuaranteedNotToBeUndefOrPoison(&Val)) {
LLVMContext &Ctx = Val.getContext();
A.manifestAttrs(IRP, Attribute::get(Ctx, Attribute::NoUndef));
return true;
}

return false;
}

namespace {
struct AANoUndefImpl : AANoUndef {
AANoUndefImpl(const IRPosition &IRP, Attributor &A) : AANoUndef(IRP, A) {}

/// See AbstractAttribute::initialize(...).
void initialize(Attributor &A) override {
if (A.hasAttr(getIRPosition(), {Attribute::NoUndef})) {
indicateOptimisticFixpoint();
return;
}
Value &V = getAssociatedValue();
if (isa<UndefValue>(V))
indicatePessimisticFixpoint();
else if (isa<FreezeInst>(V))
indicateOptimisticFixpoint();
else if (getPositionKind() != IRPosition::IRP_RETURNED &&
isGuaranteedNotToBeUndefOrPoison(&V))
indicateOptimisticFixpoint();
else
AANoUndef::initialize(A);
assert(!isImpliedByIR(A, getIRPosition(), Attribute::NoUndef));
}

/// See followUsesInMBEC
Expand Down Expand Up @@ -10257,52 +10272,66 @@ struct AANoUndefFloating : public AANoUndefImpl {

/// See AbstractAttribute::updateImpl(...).
ChangeStatus updateImpl(Attributor &A) override {
auto VisitValueCB = [&](const IRPosition &IRP) -> bool {
bool IsKnownNoUndef;
return AA::hasAssumedIRAttr<Attribute::NoUndef>(
A, this, IRP, DepClassTy::REQUIRED, IsKnownNoUndef);
};

SmallVector<AA::ValueAndContext> Values;
bool Stripped;
bool UsedAssumedInformation = false;
Value *AssociatedValue = &getAssociatedValue();
SmallVector<AA::ValueAndContext> Values;
if (!A.getAssumedSimplifiedValues(getIRPosition(), *this, Values,
AA::AnyScope, UsedAssumedInformation)) {
Values.push_back({getAssociatedValue(), getCtxI()});
}
AA::AnyScope, UsedAssumedInformation))
Stripped = false;
else
Stripped =
Values.size() != 1 || Values.front().getValue() != AssociatedValue;

StateType T;
auto VisitValueCB = [&](Value &V, const Instruction *CtxI) -> bool {
const auto *AA = A.getAAFor<AANoUndef>(*this, IRPosition::value(V),
DepClassTy::REQUIRED);
if (!AA || this == AA) {
T.indicatePessimisticFixpoint();
} else {
const AANoUndef::StateType &S =
static_cast<const AANoUndef::StateType &>(AA->getState());
T ^= S;
}
return T.isValidState();
};
if (!Stripped) {
// If we haven't stripped anything we might still be able to use a
// different AA, but only if the IRP changes. Effectively when we
// interpret this not as a call site value but as a floating/argument
// value.
const IRPosition AVIRP = IRPosition::value(*AssociatedValue);
if (AVIRP == getIRPosition() || !VisitValueCB(AVIRP))
return indicatePessimisticFixpoint();
return ChangeStatus::UNCHANGED;
}

for (const auto &VAC : Values)
if (!VisitValueCB(*VAC.getValue(), VAC.getCtxI()))
if (!VisitValueCB(IRPosition::value(*VAC.getValue())))
return indicatePessimisticFixpoint();

return clampStateAndIndicateChange(getState(), T);
return ChangeStatus::UNCHANGED;
}

/// See AbstractAttribute::trackStatistics()
void trackStatistics() const override { STATS_DECLTRACK_FNRET_ATTR(noundef) }
};

struct AANoUndefReturned final
: AAReturnedFromReturnedValues<AANoUndef, AANoUndefImpl> {
: AAReturnedFromReturnedValues<AANoUndef, AANoUndefImpl,
AANoUndef::StateType, false,
Attribute::NoUndef> {
AANoUndefReturned(const IRPosition &IRP, Attributor &A)
: AAReturnedFromReturnedValues<AANoUndef, AANoUndefImpl>(IRP, A) {}
: AAReturnedFromReturnedValues<AANoUndef, AANoUndefImpl,
AANoUndef::StateType, false,
Attribute::NoUndef>(IRP, A) {}

/// See AbstractAttribute::trackStatistics()
void trackStatistics() const override { STATS_DECLTRACK_FNRET_ATTR(noundef) }
};

struct AANoUndefArgument final
: AAArgumentFromCallSiteArguments<AANoUndef, AANoUndefImpl> {
: AAArgumentFromCallSiteArguments<AANoUndef, AANoUndefImpl,
AANoUndef::StateType, false,
Attribute::NoUndef> {
AANoUndefArgument(const IRPosition &IRP, Attributor &A)
: AAArgumentFromCallSiteArguments<AANoUndef, AANoUndefImpl>(IRP, A) {}
: AAArgumentFromCallSiteArguments<AANoUndef, AANoUndefImpl,
AANoUndef::StateType, false,
Attribute::NoUndef>(IRP, A) {}

/// See AbstractAttribute::trackStatistics()
void trackStatistics() const override { STATS_DECLTRACK_ARG_ATTR(noundef) }
Expand All @@ -10317,9 +10346,13 @@ struct AANoUndefCallSiteArgument final : AANoUndefFloating {
};

struct AANoUndefCallSiteReturned final
: AACallSiteReturnedFromReturned<AANoUndef, AANoUndefImpl> {
: AACallSiteReturnedFromReturned<AANoUndef, AANoUndefImpl,
AANoUndef::StateType, false,
Attribute::NoUndef> {
AANoUndefCallSiteReturned(const IRPosition &IRP, Attributor &A)
: AACallSiteReturnedFromReturned<AANoUndef, AANoUndefImpl>(IRP, A) {}
: AACallSiteReturnedFromReturned<AANoUndef, AANoUndefImpl,
AANoUndef::StateType, false,
Attribute::NoUndef>(IRP, A) {}

/// See AbstractAttribute::trackStatistics()
void trackStatistics() const override { STATS_DECLTRACK_CSRET_ATTR(noundef) }
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -39,7 +39,7 @@ define i32 @foo(ptr %A) {
; TUNIT: Function Attrs: mustprogress nofree norecurse nosync nounwind willreturn memory(argmem: read)
; TUNIT-LABEL: define {{[^@]+}}@foo
; TUNIT-SAME: (ptr nocapture nofree readonly [[A:%.*]]) #[[ATTR0]] {
; TUNIT-NEXT: [[X:%.*]] = call i32 @callee(ptr nocapture nofree readonly align 4 [[A]]) #[[ATTR1:[0-9]+]]
; TUNIT-NEXT: [[X:%.*]] = call i32 @callee(ptr nocapture nofree noundef readonly align 4 [[A]]) #[[ATTR1:[0-9]+]]
; TUNIT-NEXT: ret i32 [[X]]
;
; CGSCC: Function Attrs: mustprogress nofree nosync nounwind willreturn memory(argmem: read)
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -31,7 +31,7 @@ define i32 @foo(i1 %C, ptr %P) {
; TUNIT-LABEL: define {{[^@]+}}@foo
; TUNIT-SAME: (i1 [[C:%.*]], ptr nocapture nofree readonly [[P:%.*]]) #[[ATTR0]] {
; TUNIT-NEXT: entry:
; TUNIT-NEXT: [[X:%.*]] = call i32 @callee(i1 [[C]], ptr nocapture nofree readonly [[P]]) #[[ATTR1:[0-9]+]]
; TUNIT-NEXT: [[X:%.*]] = call i32 @callee(i1 noundef [[C]], ptr nocapture nofree readonly [[P]]) #[[ATTR1:[0-9]+]]
; TUNIT-NEXT: ret i32 [[X]]
;
; CGSCC: Function Attrs: mustprogress nofree nosync nounwind willreturn memory(argmem: read)
Expand Down
2 changes: 1 addition & 1 deletion llvm/test/Transforms/Attributor/ArgumentPromotion/dbg.ll
Original file line number Diff line number Diff line change
Expand Up @@ -32,7 +32,7 @@ define internal void @test_byval(ptr byval(%struct.pair) %P) {
define void @caller(ptr %Y, ptr %P) {
; TUNIT-LABEL: define {{[^@]+}}@caller
; TUNIT-SAME: (ptr nocapture nofree readonly [[Y:%.*]], ptr nocapture nofree readnone [[P:%.*]]) {
; TUNIT-NEXT: call void @test(ptr nocapture nofree readonly align 8 [[Y]]), !dbg [[DBG4:![0-9]+]]
; TUNIT-NEXT: call void @test(ptr nocapture nofree noundef readonly align 8 [[Y]]), !dbg [[DBG4:![0-9]+]]
; TUNIT-NEXT: call void @test_byval(), !dbg [[DBG5:![0-9]+]]
; TUNIT-NEXT: ret void
;
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -62,7 +62,7 @@ entry:
define internal i1 @g(ptr %a, ptr inalloca(%struct.ss) %b) nounwind {
; CGSCC: Function Attrs: mustprogress nofree norecurse nosync nounwind willreturn memory(none)
; CGSCC-LABEL: define {{[^@]+}}@g
; CGSCC-SAME: (ptr noalias nocapture nofree nonnull readnone align 4 dereferenceable(8) [[A:%.*]], ptr noalias nocapture nofree nonnull writeonly inalloca([[STRUCT_SS:%.*]]) align 4 dereferenceable(8) [[B:%.*]]) #[[ATTR2:[0-9]+]] {
; CGSCC-SAME: (ptr noalias nocapture nofree noundef nonnull readnone align 4 dereferenceable(8) [[A:%.*]], ptr noalias nocapture nofree noundef nonnull writeonly inalloca([[STRUCT_SS:%.*]]) align 4 dereferenceable(8) [[B:%.*]]) #[[ATTR2:[0-9]+]] {
; CGSCC-NEXT: entry:
; CGSCC-NEXT: ret i1 undef
;
Expand Down
27 changes: 19 additions & 8 deletions llvm/test/Transforms/Attributor/ArgumentPromotion/tail.ll
Original file line number Diff line number Diff line change
Expand Up @@ -10,14 +10,23 @@ target datalayout = "e-m:e-i64:64-f80:128-n8:16:32:64-S128"
declare ptr @foo(ptr)

define internal void @bar(ptr byval(%pair) %Data) {
; CHECK-LABEL: define {{[^@]+}}@bar
; CHECK-SAME: (i32 [[TMP0:%.*]], i32 [[TMP1:%.*]]) {
; CHECK-NEXT: [[DATA_PRIV:%.*]] = alloca [[PAIR:%.*]], align 8
; CHECK-NEXT: store i32 [[TMP0]], ptr [[DATA_PRIV]], align 4
; CHECK-NEXT: [[DATA_PRIV_0_1:%.*]] = getelementptr [[PAIR]], ptr [[DATA_PRIV]], i64 0, i32 1
; CHECK-NEXT: store i32 [[TMP1]], ptr [[DATA_PRIV_0_1]], align 4
; CHECK-NEXT: [[TMP3:%.*]] = call ptr @foo(ptr nonnull dereferenceable(8) [[DATA_PRIV]])
; CHECK-NEXT: ret void
; TUNIT-LABEL: define {{[^@]+}}@bar
; TUNIT-SAME: (i32 [[TMP0:%.*]], i32 [[TMP1:%.*]]) {
; TUNIT-NEXT: [[DATA_PRIV:%.*]] = alloca [[PAIR:%.*]], align 8
; TUNIT-NEXT: store i32 [[TMP0]], ptr [[DATA_PRIV]], align 4
; TUNIT-NEXT: [[DATA_PRIV_0_1:%.*]] = getelementptr [[PAIR]], ptr [[DATA_PRIV]], i64 0, i32 1
; TUNIT-NEXT: store i32 [[TMP1]], ptr [[DATA_PRIV_0_1]], align 4
; TUNIT-NEXT: [[TMP3:%.*]] = call ptr @foo(ptr nonnull dereferenceable(8) [[DATA_PRIV]])
; TUNIT-NEXT: ret void
;
; CGSCC-LABEL: define {{[^@]+}}@bar
; CGSCC-SAME: (i32 [[TMP0:%.*]], i32 [[TMP1:%.*]]) {
; CGSCC-NEXT: [[DATA_PRIV:%.*]] = alloca [[PAIR:%.*]], align 8
; CGSCC-NEXT: store i32 [[TMP0]], ptr [[DATA_PRIV]], align 4
; CGSCC-NEXT: [[DATA_PRIV_0_1:%.*]] = getelementptr [[PAIR]], ptr [[DATA_PRIV]], i64 0, i32 1
; CGSCC-NEXT: store i32 [[TMP1]], ptr [[DATA_PRIV_0_1]], align 4
; CGSCC-NEXT: [[TMP3:%.*]] = call ptr @foo(ptr noundef nonnull dereferenceable(8) [[DATA_PRIV]])
; CGSCC-NEXT: ret void
;
tail call ptr @foo(ptr %Data)
ret void
Expand All @@ -43,3 +52,5 @@ define void @zed(ptr byval(%pair) %Data) {
call void @bar(ptr byval(%pair) %Data)
ret void
}
;; NOTE: These prefixes are unused and the list is autogenerated. Do not add tests below this line:
; CHECK: {{.*}}
Original file line number Diff line number Diff line change
Expand Up @@ -14,7 +14,7 @@ define dso_local i16 @foo(i16 %a) {
; CGSCC: Function Attrs: mustprogress nofree nosync nounwind willreturn memory(none)
; CGSCC-LABEL: define {{[^@]+}}@foo
; CGSCC-SAME: (i16 [[A:%.*]]) #[[ATTR0:[0-9]+]] {
; CGSCC-NEXT: [[CALL:%.*]] = call i16 @bar(i16 [[A]], i32 noundef 7) #[[ATTR2:[0-9]+]]
; CGSCC-NEXT: [[CALL:%.*]] = call noundef i16 @bar(i16 [[A]], i32 noundef 7) #[[ATTR2:[0-9]+]]
; CGSCC-NEXT: ret i16 [[CALL]]
;
%call = call i16 @bar(i16 %a, i32 7)
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -62,7 +62,7 @@ entry:

define internal void @.omp_outlined.(ptr noalias %.global_tid., ptr noalias %.bound_tid., ptr dereferenceable(4) %N, ptr dereferenceable(4) %p, i64 %q) {
; TUNIT-LABEL: define {{[^@]+}}@.omp_outlined.
; TUNIT-SAME: (ptr noalias nocapture nofree readonly [[DOTGLOBAL_TID_:%.*]], ptr noalias nocapture nofree readnone [[DOTBOUND_TID_:%.*]], ptr noalias nocapture nofree nonnull readnone align 4 dereferenceable(4) [[N:%.*]], ptr noalias nocapture nofree nonnull readnone align 4 dereferenceable(4) [[P:%.*]], i64 [[Q:%.*]]) {
; TUNIT-SAME: (ptr noalias nocapture nofree readonly [[DOTGLOBAL_TID_:%.*]], ptr noalias nocapture nofree readnone [[DOTBOUND_TID_:%.*]], ptr noalias nocapture nofree noundef nonnull readnone align 4 dereferenceable(4) [[N:%.*]], ptr noalias nocapture nofree noundef nonnull readnone align 4 dereferenceable(4) [[P:%.*]], i64 [[Q:%.*]]) {
; TUNIT-NEXT: entry:
; TUNIT-NEXT: [[Q_ADDR:%.*]] = alloca i64, align 8
; TUNIT-NEXT: [[DOTOMP_LB:%.*]] = alloca i32, align 4
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -63,7 +63,7 @@ define void @caller(i1 %C) personality ptr @__gxx_personality_v0 {
; TUNIT-LABEL: define {{[^@]+}}@caller
; TUNIT-SAME: (i1 [[C:%.*]]) #[[ATTR1:[0-9]+]] personality ptr @__gxx_personality_v0 {
; TUNIT-NEXT: [[Q:%.*]] = alloca i32, align 4
; TUNIT-NEXT: [[W:%.*]] = call align 4 ptr @incdec(i1 [[C]], ptr noalias nofree noundef nonnull writeonly align 4 dereferenceable(4) "no-capture-maybe-returned" [[Q]]) #[[ATTR2:[0-9]+]]
; TUNIT-NEXT: [[W:%.*]] = call align 4 ptr @incdec(i1 noundef [[C]], ptr noalias nofree noundef nonnull writeonly align 4 dereferenceable(4) "no-capture-maybe-returned" [[Q]]) #[[ATTR2:[0-9]+]]
; TUNIT-NEXT: br label [[OK:%.*]]
; TUNIT: OK:
; TUNIT-NEXT: br label [[RET:%.*]]
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -8,7 +8,7 @@ define i1 @invokecaller(i1 %C) personality ptr @__gxx_personality_v0 {
; TUNIT: Function Attrs: mustprogress nofree norecurse nosync nounwind willreturn memory(none)
; TUNIT-LABEL: define {{[^@]+}}@invokecaller
; TUNIT-SAME: (i1 [[C:%.*]]) #[[ATTR0:[0-9]+]] personality ptr @__gxx_personality_v0 {
; TUNIT-NEXT: [[X:%.*]] = call i32 @foo(i1 [[C]]) #[[ATTR1:[0-9]+]]
; TUNIT-NEXT: [[X:%.*]] = call i32 @foo(i1 noundef [[C]]) #[[ATTR1:[0-9]+]]
; TUNIT-NEXT: br label [[OK:%.*]]
; TUNIT: OK:
; TUNIT-NEXT: ret i1 true
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -62,7 +62,7 @@ define %0 @caller(i1 %Q) {
; TUNIT: Function Attrs: mustprogress nofree norecurse nosync nounwind willreturn memory(none)
; TUNIT-LABEL: define {{[^@]+}}@caller
; TUNIT-SAME: (i1 [[Q:%.*]]) #[[ATTR0]] {
; TUNIT-NEXT: [[X:%.*]] = call [[TMP0:%.*]] @foo(i1 [[Q]]) #[[ATTR1:[0-9]+]]
; TUNIT-NEXT: [[X:%.*]] = call [[TMP0:%.*]] @foo(i1 noundef [[Q]]) #[[ATTR1:[0-9]+]]
; TUNIT-NEXT: ret [[TMP0]] [[X]]
;
; CGSCC: Function Attrs: mustprogress nofree nosync nounwind willreturn memory(none)
Expand All @@ -87,10 +87,10 @@ define i32 @caller2(i1 %Q) {
; TUNIT: Function Attrs: mustprogress nofree norecurse nosync nounwind willreturn memory(none)
; TUNIT-LABEL: define {{[^@]+}}@caller2
; TUNIT-SAME: (i1 [[Q:%.*]]) #[[ATTR0]] {
; TUNIT-NEXT: [[X:%.*]] = call [[TMP0:%.*]] @foo(i1 [[Q]]) #[[ATTR1]]
; TUNIT-NEXT: [[X:%.*]] = call [[TMP0:%.*]] @foo(i1 noundef [[Q]]) #[[ATTR1]]
; TUNIT-NEXT: [[A:%.*]] = extractvalue [[TMP0]] [[X]], 0
; TUNIT-NEXT: [[B:%.*]] = extractvalue [[TMP0]] [[X]], 1
; TUNIT-NEXT: [[Y:%.*]] = call [[TMP0]] @bar(i1 [[Q]]) #[[ATTR1]]
; TUNIT-NEXT: [[Y:%.*]] = call [[TMP0]] @bar(i1 noundef [[Q]]) #[[ATTR1]]
; TUNIT-NEXT: [[C:%.*]] = extractvalue [[TMP0]] [[Y]], 0
; TUNIT-NEXT: [[D:%.*]] = extractvalue [[TMP0]] [[Y]], 1
; TUNIT-NEXT: [[M:%.*]] = add i32 [[A]], [[C]]
Expand Down
Loading

0 comments on commit 59fd610

Please sign in to comment.