diff --git a/llvm/lib/Transforms/IPO/AttributorAttributes.cpp b/llvm/lib/Transforms/IPO/AttributorAttributes.cpp index ca3059a280085..60dca479fa06a 100644 --- a/llvm/lib/Transforms/IPO/AttributorAttributes.cpp +++ b/llvm/lib/Transforms/IPO/AttributorAttributes.cpp @@ -10889,64 +10889,104 @@ struct AAPotentialValuesFloating : AAPotentialValuesImpl { // Simplify the operands first. bool UsedAssumedInformation = false; - const auto &SimplifiedLHS = A.getAssumedSimplified( - IRPosition::value(*LHS, getCallBaseContext()), *this, - UsedAssumedInformation, AA::Intraprocedural); - if (!SimplifiedLHS.has_value()) + SmallVector LHSValues, RHSValues; + auto GetSimplifiedValues = [&](Value &V, + SmallVector &Values) { + if (!A.getAssumedSimplifiedValues( + IRPosition::value(V, getCallBaseContext()), this, Values, + AA::Intraprocedural, UsedAssumedInformation)) { + Values.clear(); + Values.push_back(AA::ValueAndContext{V, II.I.getCtxI()}); + } + return Values.empty(); + }; + if (GetSimplifiedValues(*LHS, LHSValues)) return true; - if (!*SimplifiedLHS) - return false; - LHS = *SimplifiedLHS; - - const auto &SimplifiedRHS = A.getAssumedSimplified( - IRPosition::value(*RHS, getCallBaseContext()), *this, - UsedAssumedInformation, AA::Intraprocedural); - if (!SimplifiedRHS.has_value()) + if (GetSimplifiedValues(*RHS, RHSValues)) return true; - if (!*SimplifiedRHS) - return false; - RHS = *SimplifiedRHS; LLVMContext &Ctx = LHS->getContext(); - // Handle the trivial case first in which we don't even need to think about - // null or non-null. - if (LHS == RHS && - (CmpInst::isTrueWhenEqual(Pred) || CmpInst::isFalseWhenEqual(Pred))) { - Constant *NewV = ConstantInt::get(Type::getInt1Ty(Ctx), - CmpInst::isTrueWhenEqual(Pred)); - addValue(A, getState(), *NewV, /* CtxI */ nullptr, II.S, - getAnchorScope()); - return true; - } - // From now on we only handle equalities (==, !=). - if (!CmpInst::isEquality(Pred)) - return false; + InformationCache &InfoCache = A.getInfoCache(); + Instruction *CmpI = dyn_cast(&Cmp); + Function *F = CmpI ? CmpI->getFunction() : nullptr; + const auto *DT = + F ? InfoCache.getAnalysisResultForFunction(*F) + : nullptr; + const auto *TLI = + F ? A.getInfoCache().getTargetLibraryInfoForFunction(*F) : nullptr; + auto *AC = + F ? InfoCache.getAnalysisResultForFunction(*F) + : nullptr; - bool LHSIsNull = isa(LHS); - bool RHSIsNull = isa(RHS); - if (!LHSIsNull && !RHSIsNull) - return false; + const DataLayout &DL = A.getDataLayout(); + SimplifyQuery Q(DL, TLI, DT, AC, CmpI); - // Left is the nullptr ==/!= non-nullptr case. We'll use AANonNull on the - // non-nullptr operand and if we assume it's non-null we can conclude the - // result of the comparison. - assert((LHSIsNull || RHSIsNull) && - "Expected nullptr versus non-nullptr comparison at this point"); + auto CheckPair = [&](Value &LHSV, Value &RHSV) { + if (isa(LHSV) || isa(RHSV)) { + addValue(A, getState(), *UndefValue::get(Cmp.getType()), + /* CtxI */ nullptr, II.S, getAnchorScope()); + return true; + } - // The index is the operand that we assume is not null. - unsigned PtrIdx = LHSIsNull; - bool IsKnownNonNull; - bool IsAssumedNonNull = AA::hasAssumedIRAttr( - A, this, IRPosition::value(*(PtrIdx ? RHS : LHS)), DepClassTy::REQUIRED, - IsKnownNonNull); - if (!IsAssumedNonNull) - return false; + // Handle the trivial case first in which we don't even need to think + // about null or non-null. + if (&LHSV == &RHSV && + (CmpInst::isTrueWhenEqual(Pred) || CmpInst::isFalseWhenEqual(Pred))) { + Constant *NewV = ConstantInt::get(Type::getInt1Ty(Ctx), + CmpInst::isTrueWhenEqual(Pred)); + addValue(A, getState(), *NewV, /* CtxI */ nullptr, II.S, + getAnchorScope()); + return true; + } + + auto *TypedLHS = AA::getWithType(LHSV, *LHS->getType()); + auto *TypedRHS = AA::getWithType(RHSV, *RHS->getType()); + if (TypedLHS && TypedRHS) { + Value *NewV = simplifyCmpInst(Pred, TypedLHS, TypedRHS, Q); + if (NewV && NewV != &Cmp) { + addValue(A, getState(), *NewV, /* CtxI */ nullptr, II.S, + getAnchorScope()); + return true; + } + } + + // From now on we only handle equalities (==, !=). + if (!CmpInst::isEquality(Pred)) + return false; - // The new value depends on the predicate, true for != and false for ==. - Constant *NewV = - ConstantInt::get(Type::getInt1Ty(Ctx), Pred == CmpInst::ICMP_NE); - addValue(A, getState(), *NewV, /* CtxI */ nullptr, II.S, getAnchorScope()); + bool LHSIsNull = isa(LHSV); + bool RHSIsNull = isa(RHSV); + if (!LHSIsNull && !RHSIsNull) + return false; + + // Left is the nullptr ==/!= non-nullptr case. We'll use AANonNull on the + // non-nullptr operand and if we assume it's non-null we can conclude the + // result of the comparison. + assert((LHSIsNull || RHSIsNull) && + "Expected nullptr versus non-nullptr comparison at this point"); + + // The index is the operand that we assume is not null. + unsigned PtrIdx = LHSIsNull; + bool IsKnownNonNull; + bool IsAssumedNonNull = AA::hasAssumedIRAttr( + A, this, IRPosition::value(*(PtrIdx ? &RHSV : &LHSV)), + DepClassTy::REQUIRED, IsKnownNonNull); + if (!IsAssumedNonNull) + return false; + + // The new value depends on the predicate, true for != and false for ==. + Constant *NewV = + ConstantInt::get(Type::getInt1Ty(Ctx), Pred == CmpInst::ICMP_NE); + addValue(A, getState(), *NewV, /* CtxI */ nullptr, II.S, + getAnchorScope()); + return true; + }; + + for (auto &LHSValue : LHSValues) + for (auto &RHSValue : RHSValues) + if (!CheckPair(*LHSValue.getValue(), *RHSValue.getValue())) + return false; return true; } @@ -11161,9 +11201,8 @@ struct AAPotentialValuesFloating : AAPotentialValuesImpl { SmallVectorImpl &Worklist, SmallMapVector &LivenessAAs) { if (auto *CI = dyn_cast(&I)) - if (handleCmp(A, *CI, CI->getOperand(0), CI->getOperand(1), - CI->getPredicate(), II, Worklist)) - return true; + return handleCmp(A, *CI, CI->getOperand(0), CI->getOperand(1), + CI->getPredicate(), II, Worklist); switch (I.getOpcode()) { case Instruction::Select: diff --git a/llvm/test/Transforms/Attributor/assumes_info.ll b/llvm/test/Transforms/Attributor/assumes_info.ll index e4099b576cde1..51b6a0e62151b 100644 --- a/llvm/test/Transforms/Attributor/assumes_info.ll +++ b/llvm/test/Transforms/Attributor/assumes_info.ll @@ -3,13 +3,21 @@ ; RUN: opt -aa-pipeline=basic-aa -passes=attributor-cgscc -attributor-manifest-internal -attributor-annotate-decl-cs -S < %s | FileCheck %s --check-prefixes=CHECK,CGSCC define dso_local void @entry(i1 %cond) #0 { -; CHECK-LABEL: define {{[^@]+}}@entry -; CHECK-SAME: (i1 [[COND:%.*]]) #[[ATTR0:[0-9]+]] { -; CHECK-NEXT: entry: -; CHECK-NEXT: call void @foo(i1 [[COND]]) #[[ATTR1:[0-9]+]] -; CHECK-NEXT: call void @bar() #[[ATTR2:[0-9]+]] -; CHECK-NEXT: call void @qux() #[[ATTR1]] -; CHECK-NEXT: ret void +; TUNIT-LABEL: define {{[^@]+}}@entry +; TUNIT-SAME: (i1 [[COND:%.*]]) #[[ATTR0:[0-9]+]] { +; TUNIT-NEXT: entry: +; TUNIT-NEXT: call void @foo(i1 [[COND]]) #[[ATTR1:[0-9]+]] +; TUNIT-NEXT: call void @bar() #[[ATTR2:[0-9]+]] +; TUNIT-NEXT: call void @qux() #[[ATTR1]] +; TUNIT-NEXT: ret void +; +; CGSCC-LABEL: define {{[^@]+}}@entry +; CGSCC-SAME: (i1 noundef [[COND:%.*]]) #[[ATTR0:[0-9]+]] { +; CGSCC-NEXT: entry: +; CGSCC-NEXT: call void @foo(i1 noundef [[COND]]) #[[ATTR1:[0-9]+]] +; CGSCC-NEXT: call void @bar() #[[ATTR2:[0-9]+]] +; CGSCC-NEXT: call void @qux() #[[ATTR1]] +; CGSCC-NEXT: ret void ; entry: call void @foo(i1 %cond) @@ -19,11 +27,17 @@ entry: } define internal void @foo(i1 %cond) #1 { -; CHECK-LABEL: define {{[^@]+}}@foo -; CHECK-SAME: (i1 [[COND:%.*]]) #[[ATTR1]] { -; CHECK-NEXT: entry: -; CHECK-NEXT: call void @baz(i1 [[COND]]) #[[ATTR1]] -; CHECK-NEXT: ret void +; TUNIT-LABEL: define {{[^@]+}}@foo +; TUNIT-SAME: (i1 [[COND:%.*]]) #[[ATTR1]] { +; TUNIT-NEXT: entry: +; TUNIT-NEXT: call void @baz(i1 [[COND]]) #[[ATTR1]] +; TUNIT-NEXT: ret void +; +; CGSCC-LABEL: define {{[^@]+}}@foo +; CGSCC-SAME: (i1 noundef [[COND:%.*]]) #[[ATTR1]] { +; CGSCC-NEXT: entry: +; CGSCC-NEXT: call void @baz(i1 noundef [[COND]]) #[[ATTR1]] +; CGSCC-NEXT: ret void ; entry: call void @baz(i1 %cond) @@ -32,7 +46,7 @@ entry: define internal void @bar() #2 { ; CHECK-LABEL: define {{[^@]+}}@bar -; CHECK-SAME: () #[[ATTR2]] { +; CHECK-SAME: () #[[ATTR2:[0-9]+]] { ; CHECK-NEXT: entry: ; CHECK-NEXT: call void @baz(i1 noundef false) #[[ATTR2]] ; CHECK-NEXT: ret void @@ -46,8 +60,7 @@ define internal void @baz(i1 %Cond) { ; TUNIT-LABEL: define {{[^@]+}}@baz ; TUNIT-SAME: (i1 [[COND:%.*]]) #[[ATTR1]] { ; TUNIT-NEXT: entry: -; TUNIT-NEXT: [[TOBOOL:%.*]] = icmp ne i1 [[COND]], false -; TUNIT-NEXT: br i1 [[TOBOOL]], label [[IF_THEN:%.*]], label [[IF_END:%.*]] +; TUNIT-NEXT: br i1 [[COND]], label [[IF_THEN:%.*]], label [[IF_END:%.*]] ; TUNIT: if.then: ; TUNIT-NEXT: call void @baz(i1 noundef false) #[[ATTR1]] ; TUNIT-NEXT: br label [[IF_END]] @@ -56,10 +69,9 @@ define internal void @baz(i1 %Cond) { ; TUNIT-NEXT: ret void ; ; CGSCC-LABEL: define {{[^@]+}}@baz -; CGSCC-SAME: (i1 [[COND:%.*]]) #[[ATTR3:[0-9]+]] { +; CGSCC-SAME: (i1 noundef [[COND:%.*]]) #[[ATTR3:[0-9]+]] { ; CGSCC-NEXT: entry: -; CGSCC-NEXT: [[TOBOOL:%.*]] = icmp ne i1 [[COND]], false -; CGSCC-NEXT: br i1 [[TOBOOL]], label [[IF_THEN:%.*]], label [[IF_END:%.*]] +; CGSCC-NEXT: br i1 [[COND]], label [[IF_THEN:%.*]], label [[IF_END:%.*]] ; CGSCC: if.then: ; CGSCC-NEXT: call void @baz(i1 noundef false) #[[ATTR3]] ; CGSCC-NEXT: br label [[IF_END]] diff --git a/llvm/test/Transforms/Attributor/dereferenceable-2-inseltpoison.ll b/llvm/test/Transforms/Attributor/dereferenceable-2-inseltpoison.ll index f3c2cf8c0c7e5..67f1f1be1646c 100644 --- a/llvm/test/Transforms/Attributor/dereferenceable-2-inseltpoison.ll +++ b/llvm/test/Transforms/Attributor/dereferenceable-2-inseltpoison.ll @@ -517,11 +517,10 @@ define i32 @require_cfg_analysis(i32 %c, ptr %p) { ; CHECK-NEXT: [[TOBOOL1:%.*]] = icmp eq i32 [[C]], 0 ; CHECK-NEXT: br i1 [[TOBOOL1]], label [[L1:%.*]], label [[L2:%.*]] ; CHECK: l1: -; CHECK-NEXT: [[TOBOOL2:%.*]] = icmp eq i32 [[C]], 1 -; CHECK-NEXT: br i1 [[TOBOOL2]], label [[L3:%.*]], label [[L4:%.*]] +; CHECK-NEXT: br label [[L4:%.*]] ; CHECK: l2: ; CHECK-NEXT: [[TOBOOL3:%.*]] = icmp eq i32 [[C]], 2 -; CHECK-NEXT: br i1 [[TOBOOL3]], label [[L3]], label [[L4]] +; CHECK-NEXT: br i1 [[TOBOOL3]], label [[L3:%.*]], label [[L4]] ; CHECK: l3: ; CHECK-NEXT: br label [[L5:%.*]] ; CHECK: l4: diff --git a/llvm/test/Transforms/Attributor/dereferenceable-2.ll b/llvm/test/Transforms/Attributor/dereferenceable-2.ll index e2b7d64242058..4f48703e35de7 100644 --- a/llvm/test/Transforms/Attributor/dereferenceable-2.ll +++ b/llvm/test/Transforms/Attributor/dereferenceable-2.ll @@ -517,11 +517,10 @@ define i32 @require_cfg_analysis(i32 %c, ptr %p) { ; CHECK-NEXT: [[TOBOOL1:%.*]] = icmp eq i32 [[C]], 0 ; CHECK-NEXT: br i1 [[TOBOOL1]], label [[L1:%.*]], label [[L2:%.*]] ; CHECK: l1: -; CHECK-NEXT: [[TOBOOL2:%.*]] = icmp eq i32 [[C]], 1 -; CHECK-NEXT: br i1 [[TOBOOL2]], label [[L3:%.*]], label [[L4:%.*]] +; CHECK-NEXT: br label [[L4:%.*]] ; CHECK: l2: ; CHECK-NEXT: [[TOBOOL3:%.*]] = icmp eq i32 [[C]], 2 -; CHECK-NEXT: br i1 [[TOBOOL3]], label [[L3]], label [[L4]] +; CHECK-NEXT: br i1 [[TOBOOL3]], label [[L3:%.*]], label [[L4]] ; CHECK: l3: ; CHECK-NEXT: br label [[L5:%.*]] ; CHECK: l4: diff --git a/llvm/test/Transforms/Attributor/lvi-after-jumpthreading.ll b/llvm/test/Transforms/Attributor/lvi-after-jumpthreading.ll index 89b0f9591396b..05523936fd848 100644 --- a/llvm/test/Transforms/Attributor/lvi-after-jumpthreading.ll +++ b/llvm/test/Transforms/Attributor/lvi-after-jumpthreading.ll @@ -10,12 +10,11 @@ define i8 @test1(i32 %a, i32 %length) { ; CHECK-NEXT: br label [[LOOP:%.*]] ; CHECK: loop: ; CHECK-NEXT: [[IV:%.*]] = phi i32 [ 0, [[ENTRY:%.*]] ], [ [[IV_NEXT:%.*]], [[BACKEDGE:%.*]] ] -; CHECK-NEXT: [[CND:%.*]] = icmp sge i32 [[IV]], 0 -; CHECK-NEXT: br i1 [[CND]], label [[BACKEDGE]], label [[EXIT:%.*]] +; CHECK-NEXT: br label [[BACKEDGE]] ; CHECK: backedge: ; CHECK-NEXT: [[IV_NEXT]] = add nsw i32 [[IV]], 1 ; CHECK-NEXT: [[CONT:%.*]] = icmp slt i32 [[IV_NEXT]], 400 -; CHECK-NEXT: br i1 [[CONT]], label [[LOOP]], label [[EXIT]] +; CHECK-NEXT: br i1 [[CONT]], label [[LOOP]], label [[EXIT:%.*]] ; CHECK: exit: ; CHECK-NEXT: ret i8 0 ; @@ -45,10 +44,8 @@ define i8 @test2(i32 %n) { ; CHECK: loop: ; CHECK-NEXT: [[IV:%.*]] = phi i32 [ 0, [[ENTRY:%.*]] ], [ [[IV_NEXT:%.*]], [[BACKEDGE:%.*]] ] ; CHECK-NEXT: [[IV2:%.*]] = phi i32 [ [[N]], [[ENTRY]] ], [ [[IV2_NEXT:%.*]], [[BACKEDGE]] ] -; CHECK-NEXT: [[CND1:%.*]] = icmp sge i32 [[IV]], 0 ; CHECK-NEXT: [[CND2:%.*]] = icmp sgt i32 [[IV2]], 0 -; CHECK-NEXT: [[CND:%.*]] = and i1 [[CND1]], [[CND2]] -; CHECK-NEXT: br i1 [[CND]], label [[BACKEDGE]], label [[EXIT:%.*]] +; CHECK-NEXT: br i1 [[CND2]], label [[BACKEDGE]], label [[EXIT:%.*]] ; CHECK: backedge: ; CHECK-NEXT: [[IV_NEXT]] = add nsw i32 [[IV]], 1 ; CHECK-NEXT: [[IV2_NEXT]] = sub nsw i32 [[IV2]], 1 diff --git a/llvm/test/Transforms/Attributor/nocapture-2.ll b/llvm/test/Transforms/Attributor/nocapture-2.ll index 7b962864f89c9..f7a4942091251 100644 --- a/llvm/test/Transforms/Attributor/nocapture-2.ll +++ b/llvm/test/Transforms/Attributor/nocapture-2.ll @@ -53,11 +53,9 @@ define i32 @is_null_control(ptr %p) #0 { ; CHECK-NEXT: store i32 1, ptr [[RETVAL]], align 4 ; CHECK-NEXT: br label [[RETURN:%.*]] ; CHECK: if.end: -; CHECK-NEXT: [[CMP1:%.*]] = icmp eq ptr null, [[P]] -; CHECK-NEXT: br i1 [[CMP1]], label [[IF_THEN2:%.*]], label [[IF_END3:%.*]] +; CHECK-NEXT: br label [[IF_END3:%.*]] ; CHECK: if.then2: -; CHECK-NEXT: store i32 1, ptr [[RETVAL]], align 4 -; CHECK-NEXT: br label [[RETURN]] +; CHECK-NEXT: unreachable ; CHECK: if.end3: ; CHECK-NEXT: store i32 0, ptr [[RETVAL]], align 4 ; CHECK-NEXT: br label [[RETURN]] diff --git a/llvm/test/Transforms/Attributor/potential.ll b/llvm/test/Transforms/Attributor/potential.ll index 2f6a945ac1114..02b139e8377a7 100644 --- a/llvm/test/Transforms/Attributor/potential.ll +++ b/llvm/test/Transforms/Attributor/potential.ll @@ -11,7 +11,7 @@ define internal i1 @iszero1(i32 %c) { ; CGSCC: Function Attrs: mustprogress nofree norecurse nosync nounwind willreturn memory(none) ; CGSCC-LABEL: define {{[^@]+}}@iszero1 -; CGSCC-SAME: (i32 noundef [[C:%.*]]) #[[ATTR0:[0-9]+]] { +; CGSCC-SAME: () #[[ATTR0:[0-9]+]] { ; CGSCC-NEXT: ret i1 false ; %cmp = icmp eq i32 %c, 0 @@ -27,8 +27,7 @@ define i1 @potential_test1(i1 %c) { ; CGSCC: Function Attrs: mustprogress nofree nosync nounwind willreturn memory(none) ; CGSCC-LABEL: define {{[^@]+}}@potential_test1 ; CGSCC-SAME: (i1 [[C:%.*]]) #[[ATTR1:[0-9]+]] { -; CGSCC-NEXT: [[ARG:%.*]] = select i1 [[C]], i32 -1, i32 1 -; CGSCC-NEXT: [[RET:%.*]] = call noundef i1 @iszero1(i32 noundef [[ARG]]) #[[ATTR2:[0-9]+]] +; CGSCC-NEXT: [[RET:%.*]] = call noundef i1 @iszero1() #[[ATTR2:[0-9]+]] ; CGSCC-NEXT: ret i1 [[RET]] ; %arg = select i1 %c, i32 -1, i32 1 @@ -46,12 +45,12 @@ define i1 @potential_test1(i1 %c) { ; int potential_test2(int x) { return call_with_two_values(1) + call_with_two_values(-1); } define internal i32 @iszero2(i32 %c) { -; CHECK: Function Attrs: mustprogress nofree norecurse nosync nounwind willreturn memory(none) -; CHECK-LABEL: define {{[^@]+}}@iszero2 -; CHECK-SAME: (i32 [[C:%.*]]) #[[ATTR0:[0-9]+]] { -; CHECK-NEXT: [[CMP:%.*]] = icmp eq i32 [[C]], 0 -; CHECK-NEXT: [[RET:%.*]] = zext i1 [[CMP]] to i32 -; CHECK-NEXT: ret i32 [[RET]] +; CGSCC: Function Attrs: mustprogress nofree norecurse nosync nounwind willreturn memory(none) +; CGSCC-LABEL: define {{[^@]+}}@iszero2 +; CGSCC-SAME: (i32 [[C:%.*]]) #[[ATTR0]] { +; CGSCC-NEXT: [[CMP:%.*]] = icmp eq i32 [[C]], 0 +; CGSCC-NEXT: [[RET:%.*]] = zext i1 [[CMP]] to i32 +; CGSCC-NEXT: ret i32 [[RET]] ; %cmp = icmp eq i32 %c, 0 %ret = zext i1 %cmp to i32 @@ -59,15 +58,6 @@ define internal i32 @iszero2(i32 %c) { } define internal i32 @call_with_two_values(i32 %c) { -; TUNIT: Function Attrs: mustprogress nofree norecurse nosync nounwind willreturn memory(none) -; TUNIT-LABEL: define {{[^@]+}}@call_with_two_values -; TUNIT-SAME: (i32 noundef [[C:%.*]]) #[[ATTR0]] { -; TUNIT-NEXT: [[CSRET1:%.*]] = call i32 @iszero2(i32 noundef [[C]]) #[[ATTR1:[0-9]+]], !range [[RNG0:![0-9]+]] -; TUNIT-NEXT: [[MINUSC:%.*]] = sub i32 0, [[C]] -; TUNIT-NEXT: [[CSRET2:%.*]] = call i32 @iszero2(i32 [[MINUSC]]) #[[ATTR1]], !range [[RNG0]] -; TUNIT-NEXT: [[RET:%.*]] = add i32 [[CSRET1]], [[CSRET2]] -; TUNIT-NEXT: ret i32 [[RET]] -; ; CGSCC: Function Attrs: mustprogress nofree nosync nounwind willreturn memory(none) ; CGSCC-LABEL: define {{[^@]+}}@call_with_two_values ; CGSCC-SAME: (i32 noundef [[C:%.*]]) #[[ATTR1]] { @@ -88,10 +78,7 @@ define i32 @potential_test2(i1 %c) { ; TUNIT: Function Attrs: mustprogress nofree norecurse nosync nounwind willreturn memory(none) ; TUNIT-LABEL: define {{[^@]+}}@potential_test2 ; TUNIT-SAME: (i1 [[C:%.*]]) #[[ATTR0]] { -; TUNIT-NEXT: [[CSRET1:%.*]] = call i32 @call_with_two_values(i32 noundef 1) #[[ATTR1]], !range [[RNG1:![0-9]+]] -; TUNIT-NEXT: [[CSRET2:%.*]] = call i32 @call_with_two_values(i32 noundef -1) #[[ATTR1]], !range [[RNG1]] -; TUNIT-NEXT: [[RET:%.*]] = add i32 [[CSRET1]], [[CSRET2]] -; TUNIT-NEXT: ret i32 [[RET]] +; TUNIT-NEXT: ret i32 0 ; ; CGSCC: Function Attrs: mustprogress nofree nosync nounwind willreturn memory(none) ; CGSCC-LABEL: define {{[^@]+}}@potential_test2 @@ -134,7 +121,7 @@ define internal i32 @iszero3(i32 %c) { define internal i32 @less_than_two(i32 %c) { ; CGSCC: Function Attrs: mustprogress nofree norecurse nosync nounwind willreturn memory(none) ; CGSCC-LABEL: define {{[^@]+}}@less_than_two -; CGSCC-SAME: (i32 [[C:%.*]]) #[[ATTR0]] { +; CGSCC-SAME: (i32 noundef [[C:%.*]]) #[[ATTR0]] { ; CGSCC-NEXT: [[CMP:%.*]] = icmp slt i32 [[C]], 2 ; CGSCC-NEXT: [[RET:%.*]] = zext i1 [[CMP]] to i32 ; CGSCC-NEXT: ret i32 [[RET]] @@ -154,9 +141,9 @@ define i32 @potential_test3() { ; CGSCC-LABEL: define {{[^@]+}}@potential_test3 ; CGSCC-SAME: () #[[ATTR1]] { ; CGSCC-NEXT: [[CMP1:%.*]] = call i32 @iszero3(i32 noundef 0) #[[ATTR2]] -; CGSCC-NEXT: [[TRUE1:%.*]] = call i32 @less_than_two(i32 [[CMP1]]) #[[ATTR2]] +; CGSCC-NEXT: [[TRUE1:%.*]] = call i32 @less_than_two(i32 noundef [[CMP1]]) #[[ATTR2]] ; CGSCC-NEXT: [[CMP2:%.*]] = call i32 @iszero3(i32 noundef 1) #[[ATTR2]] -; CGSCC-NEXT: [[TRUE2:%.*]] = call i32 @less_than_two(i32 [[CMP2]]) #[[ATTR2]] +; CGSCC-NEXT: [[TRUE2:%.*]] = call i32 @less_than_two(i32 noundef [[CMP2]]) #[[ATTR2]] ; CGSCC-NEXT: [[RET:%.*]] = add i32 [[TRUE1]], [[TRUE2]] ; CGSCC-NEXT: ret i32 [[RET]] ; @@ -183,10 +170,7 @@ define i32 @potential_test4(i32 %c) { ; TUNIT: Function Attrs: mustprogress nofree norecurse nosync nounwind willreturn memory(none) ; TUNIT-LABEL: define {{[^@]+}}@potential_test4 ; TUNIT-SAME: (i32 [[C:%.*]]) #[[ATTR0]] { -; TUNIT-NEXT: [[CSRET:%.*]] = call i32 @return1or3(i32 [[C]]) #[[ATTR1]] -; TUNIT-NEXT: [[FALSE:%.*]] = icmp eq i32 [[CSRET]], 2 -; TUNIT-NEXT: [[RET:%.*]] = zext i1 [[FALSE]] to i32 -; TUNIT-NEXT: ret i32 [[RET]] +; TUNIT-NEXT: ret i32 0 ; ; CGSCC: Function Attrs: mustprogress nofree nosync nounwind willreturn memory(none) ; CGSCC-LABEL: define {{[^@]+}}@potential_test4 @@ -206,11 +190,7 @@ define i32 @potential_test5(i32 %c) { ; TUNIT: Function Attrs: mustprogress nofree norecurse nosync nounwind willreturn memory(none) ; TUNIT-LABEL: define {{[^@]+}}@potential_test5 ; TUNIT-SAME: (i32 [[C:%.*]]) #[[ATTR0]] { -; TUNIT-NEXT: [[CSRET1:%.*]] = call i32 @return1or3(i32 [[C]]) #[[ATTR1]] -; TUNIT-NEXT: [[CSRET2:%.*]] = call i32 @return2or4(i32 [[C]]) #[[ATTR1]] -; TUNIT-NEXT: [[FALSE:%.*]] = icmp eq i32 [[CSRET1]], [[CSRET2]] -; TUNIT-NEXT: [[RET:%.*]] = zext i1 [[FALSE]] to i32 -; TUNIT-NEXT: ret i32 [[RET]] +; TUNIT-NEXT: ret i32 0 ; ; CGSCC: Function Attrs: mustprogress nofree nosync nounwind willreturn memory(none) ; CGSCC-LABEL: define {{[^@]+}}@potential_test5 @@ -232,7 +212,7 @@ define i1 @potential_test6(i32 %c) { ; TUNIT: Function Attrs: mustprogress nofree norecurse nosync nounwind willreturn memory(none) ; TUNIT-LABEL: define {{[^@]+}}@potential_test6 ; TUNIT-SAME: (i32 [[C:%.*]]) #[[ATTR0]] { -; TUNIT-NEXT: [[CSRET1:%.*]] = call i32 @return1or3(i32 [[C]]) #[[ATTR1]] +; TUNIT-NEXT: [[CSRET1:%.*]] = call i32 @return1or3(i32 [[C]]) #[[ATTR1:[0-9]+]] ; TUNIT-NEXT: [[RET:%.*]] = icmp eq i32 [[CSRET1]], 3 ; TUNIT-NEXT: ret i1 [[RET]] ; @@ -274,7 +254,7 @@ define i1 @potential_test7(i32 %c) { define internal i32 @return1or3(i32 %c) { ; CHECK: Function Attrs: mustprogress nofree norecurse nosync nounwind willreturn memory(none) ; CHECK-LABEL: define {{[^@]+}}@return1or3 -; CHECK-SAME: (i32 [[C:%.*]]) #[[ATTR0]] { +; CHECK-SAME: (i32 [[C:%.*]]) #[[ATTR0:[0-9]+]] { ; CHECK-NEXT: [[CMP:%.*]] = icmp eq i32 [[C]], 0 ; CHECK-NEXT: [[RET:%.*]] = select i1 [[CMP]], i32 1, i32 3 ; CHECK-NEXT: ret i32 [[RET]] @@ -285,12 +265,12 @@ define internal i32 @return1or3(i32 %c) { } define internal i32 @return2or4(i32 %c) { -; CHECK: Function Attrs: mustprogress nofree norecurse nosync nounwind willreturn memory(none) -; CHECK-LABEL: define {{[^@]+}}@return2or4 -; CHECK-SAME: (i32 [[C:%.*]]) #[[ATTR0]] { -; CHECK-NEXT: [[CMP:%.*]] = icmp eq i32 [[C]], 0 -; CHECK-NEXT: [[RET:%.*]] = select i1 [[CMP]], i32 2, i32 4 -; CHECK-NEXT: ret i32 [[RET]] +; CGSCC: Function Attrs: mustprogress nofree norecurse nosync nounwind willreturn memory(none) +; CGSCC-LABEL: define {{[^@]+}}@return2or4 +; CGSCC-SAME: (i32 [[C:%.*]]) #[[ATTR0]] { +; CGSCC-NEXT: [[CMP:%.*]] = icmp eq i32 [[C]], 0 +; CGSCC-NEXT: [[RET:%.*]] = select i1 [[CMP]], i32 2, i32 4 +; CGSCC-NEXT: ret i32 [[RET]] ; %cmp = icmp eq i32 %c, 0 %ret = select i1 %cmp, i32 2, i32 4 @@ -491,9 +471,7 @@ define i32 @optimize_undef_3(i1 %c) { ; CHECK: t: ; CHECK-NEXT: ret i32 0 ; CHECK: f: -; CHECK-NEXT: [[UNDEF:%.*]] = icmp eq i32 undef, 0 -; CHECK-NEXT: [[UNDEF2:%.*]] = zext i1 [[UNDEF]] to i32 -; CHECK-NEXT: ret i32 [[UNDEF2]] +; CHECK-NEXT: ret i32 0 ; br i1 %c, label %t, label %f t: @@ -512,9 +490,8 @@ define i32 @potential_test11(i1 %c) { ; TUNIT-SAME: (i1 [[C:%.*]]) #[[ATTR0]] { ; TUNIT-NEXT: [[ZERO1:%.*]] = call i32 @optimize_undef_1(i1 noundef [[C]]) #[[ATTR1]] ; TUNIT-NEXT: [[ZERO2:%.*]] = call i32 @optimize_undef_2(i1 noundef [[C]]) #[[ATTR1]] -; TUNIT-NEXT: [[ZERO3:%.*]] = call i32 @optimize_undef_3(i1 noundef [[C]]) #[[ATTR1]] ; TUNIT-NEXT: [[ACC1:%.*]] = add i32 [[ZERO1]], [[ZERO2]] -; TUNIT-NEXT: [[ACC2:%.*]] = add i32 [[ACC1]], [[ZERO3]] +; TUNIT-NEXT: [[ACC2:%.*]] = add i32 [[ACC1]], 0 ; TUNIT-NEXT: ret i32 [[ACC2]] ; ; CGSCC: Function Attrs: mustprogress nofree nosync nounwind willreturn memory(none) @@ -688,6 +665,3 @@ define i1 @potential_test16(i1 %c0, i1 %c1) { ; CGSCC: attributes #[[ATTR1]] = { mustprogress nofree nosync nounwind willreturn memory(none) } ; CGSCC: attributes #[[ATTR2]] = { nofree nosync willreturn } ;. -; TUNIT: [[RNG0]] = !{i32 0, i32 2} -; TUNIT: [[RNG1]] = !{i32 0, i32 3} -;. diff --git a/llvm/test/Transforms/Attributor/range.ll b/llvm/test/Transforms/Attributor/range.ll index 8ef0ad090a254..50887ebfb751d 100644 --- a/llvm/test/Transforms/Attributor/range.ll +++ b/llvm/test/Transforms/Attributor/range.ll @@ -70,17 +70,15 @@ define void @test0-icmp-check(ptr %p){ ; TUNIT-NEXT: [[CMP_UGT_3:%.*]] = icmp ugt i32 [[RET]], 8 ; TUNIT-NEXT: [[CMP_UGT_4:%.*]] = icmp ugt i32 [[RET]], 1 ; TUNIT-NEXT: [[CMP_UGT_5:%.*]] = icmp ugt i32 [[RET]], 0 -; TUNIT-NEXT: [[CMP_UGT_6:%.*]] = icmp ugt i32 [[RET]], -1 ; TUNIT-NEXT: tail call void @use3(i1 [[CMP_UGT_1]], i1 [[CMP_UGT_2]], i1 [[CMP_UGT_3]]) -; TUNIT-NEXT: tail call void @use3(i1 [[CMP_UGT_4]], i1 [[CMP_UGT_5]], i1 [[CMP_UGT_6]]) +; TUNIT-NEXT: tail call void @use3(i1 [[CMP_UGT_4]], i1 [[CMP_UGT_5]], i1 noundef false) ; TUNIT-NEXT: [[CMP_UGE_1:%.*]] = icmp uge i32 [[RET]], 10 ; TUNIT-NEXT: [[CMP_UGE_2:%.*]] = icmp uge i32 [[RET]], 9 ; TUNIT-NEXT: [[CMP_UGE_3:%.*]] = icmp uge i32 [[RET]], 8 ; TUNIT-NEXT: [[CMP_UGE_4:%.*]] = icmp uge i32 [[RET]], 1 -; TUNIT-NEXT: [[CMP_UGE_5:%.*]] = icmp uge i32 [[RET]], 0 ; TUNIT-NEXT: [[CMP_UGE_6:%.*]] = icmp uge i32 [[RET]], -1 ; TUNIT-NEXT: tail call void @use3(i1 [[CMP_UGE_1]], i1 [[CMP_UGE_2]], i1 [[CMP_UGE_3]]) -; TUNIT-NEXT: tail call void @use3(i1 [[CMP_UGE_4]], i1 [[CMP_UGE_5]], i1 [[CMP_UGE_6]]) +; TUNIT-NEXT: tail call void @use3(i1 [[CMP_UGE_4]], i1 noundef true, i1 [[CMP_UGE_6]]) ; TUNIT-NEXT: [[CMP_SGT_1:%.*]] = icmp sgt i32 [[RET]], 10 ; TUNIT-NEXT: [[CMP_SGT_2:%.*]] = icmp sgt i32 [[RET]], 9 ; TUNIT-NEXT: [[CMP_SGT_3:%.*]] = icmp sgt i32 [[RET]], 8 @@ -139,17 +137,15 @@ define void @test0-icmp-check(ptr %p){ ; CGSCC-NEXT: [[CMP_UGT_3:%.*]] = icmp ugt i32 [[RET]], 8 ; CGSCC-NEXT: [[CMP_UGT_4:%.*]] = icmp ugt i32 [[RET]], 1 ; CGSCC-NEXT: [[CMP_UGT_5:%.*]] = icmp ugt i32 [[RET]], 0 -; CGSCC-NEXT: [[CMP_UGT_6:%.*]] = icmp ugt i32 [[RET]], -1 ; CGSCC-NEXT: tail call void @use3(i1 [[CMP_UGT_1]], i1 [[CMP_UGT_2]], i1 [[CMP_UGT_3]]) -; CGSCC-NEXT: tail call void @use3(i1 [[CMP_UGT_4]], i1 [[CMP_UGT_5]], i1 [[CMP_UGT_6]]) +; CGSCC-NEXT: tail call void @use3(i1 [[CMP_UGT_4]], i1 [[CMP_UGT_5]], i1 noundef false) ; CGSCC-NEXT: [[CMP_UGE_1:%.*]] = icmp uge i32 [[RET]], 10 ; CGSCC-NEXT: [[CMP_UGE_2:%.*]] = icmp uge i32 [[RET]], 9 ; CGSCC-NEXT: [[CMP_UGE_3:%.*]] = icmp uge i32 [[RET]], 8 ; CGSCC-NEXT: [[CMP_UGE_4:%.*]] = icmp uge i32 [[RET]], 1 -; CGSCC-NEXT: [[CMP_UGE_5:%.*]] = icmp uge i32 [[RET]], 0 ; CGSCC-NEXT: [[CMP_UGE_6:%.*]] = icmp uge i32 [[RET]], -1 ; CGSCC-NEXT: tail call void @use3(i1 [[CMP_UGE_1]], i1 [[CMP_UGE_2]], i1 [[CMP_UGE_3]]) -; CGSCC-NEXT: tail call void @use3(i1 [[CMP_UGE_4]], i1 [[CMP_UGE_5]], i1 [[CMP_UGE_6]]) +; CGSCC-NEXT: tail call void @use3(i1 [[CMP_UGE_4]], i1 noundef true, i1 [[CMP_UGE_6]]) ; CGSCC-NEXT: [[CMP_SGT_1:%.*]] = icmp sgt i32 [[RET]], 10 ; CGSCC-NEXT: [[CMP_SGT_2:%.*]] = icmp sgt i32 [[RET]], 9 ; CGSCC-NEXT: [[CMP_SGT_3:%.*]] = icmp sgt i32 [[RET]], 8 @@ -334,20 +330,17 @@ entry: } define i32 @test2_check(ptr %p) { -; TUNIT: Function Attrs: mustprogress nofree norecurse nosync nounwind willreturn memory(argmem: read) +; TUNIT: Function Attrs: mustprogress nofree norecurse nosync nounwind willreturn memory(none) ; TUNIT-LABEL: define {{[^@]+}}@test2_check -; TUNIT-SAME: (ptr nocapture nofree readonly align 4 [[P:%.*]]) #[[ATTR0]] { +; TUNIT-SAME: (ptr nocapture nofree readnone align 4 [[P:%.*]]) #[[ATTR1:[0-9]+]] { ; TUNIT-NEXT: entry: -; TUNIT-NEXT: [[CALL:%.*]] = tail call i32 @test2(ptr nocapture nofree noundef readonly align 4 [[P]]) #[[ATTR3]] -; TUNIT-NEXT: [[CMP:%.*]] = icmp slt i32 [[CALL]], 5 -; TUNIT-NEXT: br i1 [[CMP]], label [[IF_THEN:%.*]], label [[IF_END:%.*]] +; TUNIT-NEXT: br label [[IF_THEN:%.*]] ; TUNIT: if.then: ; TUNIT-NEXT: br label [[RETURN:%.*]] ; TUNIT: if.end: -; TUNIT-NEXT: br label [[RETURN]] +; TUNIT-NEXT: unreachable ; TUNIT: return: -; TUNIT-NEXT: [[RETVAL_0:%.*]] = phi i32 [ 2, [[IF_THEN]] ], [ 3, [[IF_END]] ] -; TUNIT-NEXT: ret i32 [[RETVAL_0]] +; TUNIT-NEXT: ret i32 2 ; ; CGSCC: Function Attrs: mustprogress nofree nosync nounwind willreturn memory(argmem: read) ; CGSCC-LABEL: define {{[^@]+}}@test2_check @@ -410,7 +403,7 @@ declare dso_local void @unkown() define internal i32 @r1(i32) local_unnamed_addr { ; TUNIT: Function Attrs: mustprogress nofree norecurse nosync nounwind willreturn memory(none) ; TUNIT-LABEL: define {{[^@]+}}@r1 -; TUNIT-SAME: () local_unnamed_addr #[[ATTR1:[0-9]+]] { +; TUNIT-SAME: () local_unnamed_addr #[[ATTR1]] { ; TUNIT-NEXT: br label [[TMP4:%.*]] ; TUNIT: 1: ; TUNIT-NEXT: [[TMP2:%.*]] = icmp sgt i32 [[TMP7:%.*]], 10000 @@ -729,26 +722,20 @@ define dso_local zeroext i1 @phi(i32 %arg) { ; TUNIT: bb2: ; TUNIT-NEXT: br label [[BB3]] ; TUNIT: bb3: -; TUNIT-NEXT: [[DOT02:%.*]] = phi i32 [ 1, [[BB1]] ], [ 2, [[BB2]] ] ; TUNIT-NEXT: [[TRUETMP4:%.*]] = icmp sgt i32 [[ARG]], 10 ; TUNIT-NEXT: br i1 [[TRUETMP4]], label [[BB5:%.*]], label [[BB7:%.*]] ; TUNIT: bb5: -; TUNIT-NEXT: [[TRUETMP6:%.*]] = add nsw i32 [[DOT02]], 1 ; TUNIT-NEXT: br label [[BB9:%.*]] ; TUNIT: bb7: -; TUNIT-NEXT: [[TRUETMP8:%.*]] = add nsw i32 [[DOT02]], 2 ; TUNIT-NEXT: br label [[BB9]] ; TUNIT: bb9: -; TUNIT-NEXT: [[DOT01:%.*]] = phi i32 [ [[TRUETMP6]], [[BB5]] ], [ [[TRUETMP8]], [[BB7]] ] -; TUNIT-NEXT: [[TRUETMP10:%.*]] = icmp eq i32 [[DOT01]], 5 -; TUNIT-NEXT: br i1 [[TRUETMP10]], label [[BB11:%.*]], label [[BB12:%.*]] +; TUNIT-NEXT: br label [[BB12:%.*]] ; TUNIT: bb11: -; TUNIT-NEXT: br label [[BB13:%.*]] +; TUNIT-NEXT: unreachable ; TUNIT: bb12: -; TUNIT-NEXT: br label [[BB13]] +; TUNIT-NEXT: br label [[BB13:%.*]] ; TUNIT: bb13: -; TUNIT-NEXT: [[DOT0:%.*]] = phi i1 [ true, [[BB11]] ], [ false, [[BB12]] ] -; TUNIT-NEXT: ret i1 [[DOT0]] +; TUNIT-NEXT: ret i1 false ; ; CGSCC: Function Attrs: mustprogress nofree norecurse nosync nounwind willreturn memory(none) ; CGSCC-LABEL: define {{[^@]+}}@phi @@ -761,26 +748,20 @@ define dso_local zeroext i1 @phi(i32 %arg) { ; CGSCC: bb2: ; CGSCC-NEXT: br label [[BB3]] ; CGSCC: bb3: -; CGSCC-NEXT: [[DOT02:%.*]] = phi i32 [ 1, [[BB1]] ], [ 2, [[BB2]] ] ; CGSCC-NEXT: [[TRUETMP4:%.*]] = icmp sgt i32 [[ARG]], 10 ; CGSCC-NEXT: br i1 [[TRUETMP4]], label [[BB5:%.*]], label [[BB7:%.*]] ; CGSCC: bb5: -; CGSCC-NEXT: [[TRUETMP6:%.*]] = add nsw i32 [[DOT02]], 1 ; CGSCC-NEXT: br label [[BB9:%.*]] ; CGSCC: bb7: -; CGSCC-NEXT: [[TRUETMP8:%.*]] = add nsw i32 [[DOT02]], 2 ; CGSCC-NEXT: br label [[BB9]] ; CGSCC: bb9: -; CGSCC-NEXT: [[DOT01:%.*]] = phi i32 [ [[TRUETMP6]], [[BB5]] ], [ [[TRUETMP8]], [[BB7]] ] -; CGSCC-NEXT: [[TRUETMP10:%.*]] = icmp eq i32 [[DOT01]], 5 -; CGSCC-NEXT: br i1 [[TRUETMP10]], label [[BB11:%.*]], label [[BB12:%.*]] +; CGSCC-NEXT: br label [[BB12:%.*]] ; CGSCC: bb11: -; CGSCC-NEXT: br label [[BB13:%.*]] +; CGSCC-NEXT: unreachable ; CGSCC: bb12: -; CGSCC-NEXT: br label [[BB13]] +; CGSCC-NEXT: br label [[BB13:%.*]] ; CGSCC: bb13: -; CGSCC-NEXT: [[DOT0:%.*]] = phi i1 [ true, [[BB11]] ], [ false, [[BB12]] ] -; CGSCC-NEXT: ret i1 [[DOT0]] +; CGSCC-NEXT: ret i1 false ; bb: %tmp = icmp sgt i32 %arg, 5 diff --git a/llvm/test/Transforms/Attributor/undefined_behavior.ll b/llvm/test/Transforms/Attributor/undefined_behavior.ll index f14d0201a40aa..7ecd4ce33d495 100644 --- a/llvm/test/Transforms/Attributor/undefined_behavior.ll +++ b/llvm/test/Transforms/Attributor/undefined_behavior.ll @@ -479,15 +479,23 @@ e: ; Branch on undef that depends on propagation of ; undef of a previous instruction. define i32 @cond_br_on_undef3() { -; CHECK: Function Attrs: mustprogress nofree norecurse nosync nounwind willreturn memory(none) -; CHECK-LABEL: define {{[^@]+}}@cond_br_on_undef3 -; CHECK-SAME: () #[[ATTR0]] { -; CHECK-NEXT: [[COND:%.*]] = icmp ne i32 1, undef -; CHECK-NEXT: br i1 [[COND]], label [[T:%.*]], label [[E:%.*]] -; CHECK: t: -; CHECK-NEXT: ret i32 1 -; CHECK: e: -; CHECK-NEXT: ret i32 2 +; TUNIT: Function Attrs: mustprogress nofree norecurse noreturn nosync nounwind willreturn memory(none) +; TUNIT-LABEL: define {{[^@]+}}@cond_br_on_undef3 +; TUNIT-SAME: () #[[ATTR5]] { +; TUNIT-NEXT: unreachable +; TUNIT: t: +; TUNIT-NEXT: unreachable +; TUNIT: e: +; TUNIT-NEXT: unreachable +; +; CGSCC: Function Attrs: mustprogress nofree norecurse noreturn nosync nounwind willreturn memory(none) +; CGSCC-LABEL: define {{[^@]+}}@cond_br_on_undef3 +; CGSCC-SAME: () #[[ATTR8]] { +; CGSCC-NEXT: unreachable +; CGSCC: t: +; CGSCC-NEXT: unreachable +; CGSCC: e: +; CGSCC-NEXT: unreachable ; %cond = icmp ne i32 1, undef br i1 %cond, label %t, label %e diff --git a/llvm/test/Transforms/Attributor/value-simplify-local-remote.ll b/llvm/test/Transforms/Attributor/value-simplify-local-remote.ll index 01d2a356670d7..7d8cf38e25270 100644 --- a/llvm/test/Transforms/Attributor/value-simplify-local-remote.ll +++ b/llvm/test/Transforms/Attributor/value-simplify-local-remote.ll @@ -383,22 +383,15 @@ define dso_local void @spam() { ; TUNIT-NEXT: [[TRUETMP18:%.*]] = icmp eq i32 [[X]], 0 ; TUNIT-NEXT: br i1 [[TRUETMP18]], label [[BB35:%.*]], label [[BB19:%.*]] ; TUNIT: bb19: -; TUNIT-NEXT: [[TRUETMP21:%.*]] = load float, ptr [[TMP]], align 4 -; TUNIT-NEXT: [[TRUETMP22:%.*]] = fadd fast float [[TRUETMP21]], 0.000000e+00 ; TUNIT-NEXT: br label [[BB23:%.*]] ; TUNIT: bb23: -; TUNIT-NEXT: [[TRUETMP24:%.*]] = phi <2 x float> [ undef, [[BB19]] ], [ [[TRUETMP26:%.*]], [[BB34:%.*]] ] ; TUNIT-NEXT: br label [[BB25:%.*]] ; TUNIT: bb25: -; TUNIT-NEXT: [[TRUETMP26]] = phi <2 x float> [ [[TRUETMP30:%.*]], [[BB28:%.*]] ], [ [[TRUETMP24]], [[BB23]] ] -; TUNIT-NEXT: [[TRUETMP27:%.*]] = icmp ult i32 undef, 8 -; TUNIT-NEXT: br i1 [[TRUETMP27]], label [[BB28]], label [[BB34]] +; TUNIT-NEXT: unreachable ; TUNIT: bb28: -; TUNIT-NEXT: [[TRUETMP29:%.*]] = insertelement <2 x float> [[TRUETMP26]], float undef, i32 0 -; TUNIT-NEXT: [[TRUETMP30]] = insertelement <2 x float> [[TRUETMP29]], float [[TRUETMP22]], i32 1 -; TUNIT-NEXT: br label [[BB25]] +; TUNIT-NEXT: unreachable ; TUNIT: bb34: -; TUNIT-NEXT: br label [[BB23]] +; TUNIT-NEXT: unreachable ; TUNIT: bb35: ; TUNIT-NEXT: unreachable ; @@ -414,22 +407,15 @@ define dso_local void @spam() { ; CGSCC-NEXT: [[TRUETMP18:%.*]] = icmp eq i32 [[X]], 0 ; CGSCC-NEXT: br i1 [[TRUETMP18]], label [[BB35:%.*]], label [[BB19:%.*]] ; CGSCC: bb19: -; CGSCC-NEXT: [[TRUETMP21:%.*]] = load float, ptr [[TMP]], align 4 -; CGSCC-NEXT: [[TRUETMP22:%.*]] = fadd fast float [[TRUETMP21]], 0.000000e+00 ; CGSCC-NEXT: br label [[BB23:%.*]] ; CGSCC: bb23: -; CGSCC-NEXT: [[TRUETMP24:%.*]] = phi <2 x float> [ undef, [[BB19]] ], [ [[TRUETMP26:%.*]], [[BB34:%.*]] ] ; CGSCC-NEXT: br label [[BB25:%.*]] ; CGSCC: bb25: -; CGSCC-NEXT: [[TRUETMP26]] = phi <2 x float> [ [[TRUETMP30:%.*]], [[BB28:%.*]] ], [ [[TRUETMP24]], [[BB23]] ] -; CGSCC-NEXT: [[TRUETMP27:%.*]] = icmp ult i32 undef, 8 -; CGSCC-NEXT: br i1 [[TRUETMP27]], label [[BB28]], label [[BB34]] +; CGSCC-NEXT: unreachable ; CGSCC: bb28: -; CGSCC-NEXT: [[TRUETMP29:%.*]] = insertelement <2 x float> [[TRUETMP26]], float undef, i32 0 -; CGSCC-NEXT: [[TRUETMP30]] = insertelement <2 x float> [[TRUETMP29]], float [[TRUETMP22]], i32 1 -; CGSCC-NEXT: br label [[BB25]] +; CGSCC-NEXT: unreachable ; CGSCC: bb34: -; CGSCC-NEXT: br label [[BB23]] +; CGSCC-NEXT: unreachable ; CGSCC: bb35: ; CGSCC-NEXT: unreachable ; diff --git a/llvm/test/Transforms/Attributor/value-simplify.ll b/llvm/test/Transforms/Attributor/value-simplify.ll index 4290397723892..31fc0746db2ce 100644 --- a/llvm/test/Transforms/Attributor/value-simplify.ll +++ b/llvm/test/Transforms/Attributor/value-simplify.ll @@ -858,7 +858,7 @@ define i1 @test_merge_with_undef_values_ptr(i1 %c) { ; CGSCC: Function Attrs: mustprogress nofree nosync nounwind willreturn memory(none) ; CGSCC-LABEL: define {{[^@]+}}@test_merge_with_undef_values_ptr ; CGSCC-SAME: (i1 [[C:%.*]]) #[[ATTR3]] { -; CGSCC-NEXT: [[R1:%.*]] = call noundef i1 @undef_then_null(i1 noundef [[C]]) #[[ATTR12]] +; CGSCC-NEXT: [[R1:%.*]] = call i1 @undef_then_null(i1 [[C]]) #[[ATTR12]] ; CGSCC-NEXT: ret i1 [[R1]] ; %r1 = call i1 @undef_then_null(i1 %c, ptr undef, ptr undef) @@ -867,8 +867,9 @@ define i1 @test_merge_with_undef_values_ptr(i1 %c) { define internal i1 @undef_then_null(i1 %c, ptr %i32Aptr, ptr %i32Bptr) { ; CGSCC: Function Attrs: mustprogress nofree nosync nounwind willreturn memory(none) ; CGSCC-LABEL: define {{[^@]+}}@undef_then_null -; CGSCC-SAME: (i1 noundef [[C:%.*]]) #[[ATTR3]] { -; CGSCC-NEXT: br i1 [[C]], label [[A:%.*]], label [[B:%.*]] +; CGSCC-SAME: (i1 [[C:%.*]]) #[[ATTR3]] { +; CGSCC-NEXT: [[OR:%.*]] = or i1 false, [[C]] +; CGSCC-NEXT: br i1 [[OR]], label [[A:%.*]], label [[B:%.*]] ; CGSCC: a: ; CGSCC-NEXT: ret i1 false ; CGSCC: b: @@ -894,7 +895,7 @@ define i1 @test_merge_with_undef_values(i1 %c) { ; CGSCC: Function Attrs: mustprogress nofree nosync nounwind willreturn memory(none) ; CGSCC-LABEL: define {{[^@]+}}@test_merge_with_undef_values ; CGSCC-SAME: (i1 [[C:%.*]]) #[[ATTR3]] { -; CGSCC-NEXT: [[R1:%.*]] = call noundef i1 @undef_then_1(i1 noundef [[C]]) #[[ATTR12]] +; CGSCC-NEXT: [[R1:%.*]] = call i1 @undef_then_1(i1 [[C]]) #[[ATTR12]] ; CGSCC-NEXT: ret i1 [[R1]] ; %r1 = call i1 @undef_then_1(i1 %c, i32 undef, i32 undef) @@ -904,8 +905,9 @@ define internal i1 @undef_then_1(i1 %c, i32 %i32A, i32 %i32B) { ; ; CGSCC: Function Attrs: mustprogress nofree nosync nounwind willreturn memory(none) ; CGSCC-LABEL: define {{[^@]+}}@undef_then_1 -; CGSCC-SAME: (i1 noundef [[C:%.*]]) #[[ATTR3]] { -; CGSCC-NEXT: br i1 [[C]], label [[A:%.*]], label [[B:%.*]] +; CGSCC-SAME: (i1 [[C:%.*]]) #[[ATTR3]] { +; CGSCC-NEXT: [[OR:%.*]] = or i1 false, [[C]] +; CGSCC-NEXT: br i1 [[OR]], label [[A:%.*]], label [[B:%.*]] ; CGSCC: a: ; CGSCC-NEXT: ret i1 false ; CGSCC: b: @@ -1389,6 +1391,11 @@ define internal void @not_called2() { ret void } define internal void @not_called3() { +; TUNIT: Function Attrs: mustprogress nofree norecurse nosync nounwind willreturn memory(none) +; TUNIT-LABEL: define {{[^@]+}}@not_called3 +; TUNIT-SAME: () #[[ATTR2]] { +; TUNIT-NEXT: ret void +; ; CGSCC: Function Attrs: mustprogress nofree norecurse nosync nounwind willreturn memory(none) ; CGSCC-LABEL: define {{[^@]+}}@not_called3 ; CGSCC-SAME: () #[[ATTR1]] { @@ -1410,7 +1417,7 @@ define i1 @user_of_not_called() { ; CHECK-LABEL: define {{[^@]+}}@user_of_not_called() { ; CHECK-NEXT: call void @useFnDecl(ptr addrspace(42) noundef nonnull addrspacecast (ptr @not_called1 to ptr addrspace(42))) ; CHECK-NEXT: call void @useFnDef(ptr addrspace(42) noundef nonnull addrspacecast (ptr @not_called2 to ptr addrspace(42))) -; CHECK-NEXT: ret i1 false +; CHECK-NEXT: ret i1 icmp eq (ptr addrspace(42) addrspacecast (ptr @not_called3 to ptr addrspace(42)), ptr addrspace(42) null) ; call void @useFnDecl(ptr addrspace(42) addrspacecast (ptr @not_called1 to ptr addrspace(42))) call void @useFnDef(ptr addrspace(42) addrspacecast (ptr @not_called2 to ptr addrspace(42))) diff --git a/llvm/test/Transforms/OpenMP/heap-to-shared-missing-declarations.ll b/llvm/test/Transforms/OpenMP/heap-to-shared-missing-declarations.ll index 154e549b19e9b..7a5bba75f6c48 100644 --- a/llvm/test/Transforms/OpenMP/heap-to-shared-missing-declarations.ll +++ b/llvm/test/Transforms/OpenMP/heap-to-shared-missing-declarations.ll @@ -37,16 +37,14 @@ define internal void @outlined1() { ; CHECK-LABEL: define {{[^@]+}}@outlined1 ; CHECK-SAME: () #[[ATTR1]] { ; CHECK-NEXT: bb: -; CHECK-NEXT: [[I:%.*]] = icmp sle i32 1, 0 -; CHECK-NEXT: br i1 [[I]], label [[BB1:%.*]], label [[BB2:%.*]] +; CHECK-NEXT: br label [[BB2:%.*]] ; CHECK: common.ret: ; CHECK-NEXT: ret void ; CHECK: bb1: -; CHECK-NEXT: call void @func() #[[ATTR1]] -; CHECK-NEXT: br label [[COMMON_RET:%.*]] +; CHECK-NEXT: unreachable ; CHECK: bb2: ; CHECK-NEXT: call void @__kmpc_free_shared(ptr null, i64 0) #[[ATTR0]] -; CHECK-NEXT: br label [[COMMON_RET]] +; CHECK-NEXT: br label [[COMMON_RET:%.*]] ; bb: %i = icmp sle i32 1, 0