[llvm] [Attributor][NFC] Use poison for the placeholder callee in callgraph.ll (PR #217082)
via llvm-commits
llvm-commits at lists.llvm.org
Tue Aug 18 10:01:54 PDT 2026
llvmorg-github-actions[bot] wrote:
<!--LLVM PR SUMMARY COMMENT-->
@llvm/pr-subscribers-llvm-transforms
Author: Larry Meadows (lfmeadow)
<details>
<summary>Changes</summary>
Stacked on #<!-- -->217077 and #<!-- -->217079, which regenerate this file; only the last commit belongs to this PR.
`@<!-- -->undef_in_callees` checks that a `!callees` list naming something that is not a function does not crash the pass. The callee, its arguments and the entry in the metadata are all placeholders standing for "not a function", which `poison` says as well as `undef` does.
`PoisonValue` is a `UndefValue`, so the pass cannot tell the difference: regenerating after the swap gives a file identical token for token, which is also why this is worth doing — it moves a test off `undef` at no cost.
```llvm
- call void undef(ptr undef, i32 undef, ptr undef), !callees !3
+ call void poison(ptr poison, i32 poison, ptr poison), !callees !3
-!3 = distinct !{ptr undef, ptr null}
+!3 = distinct !{ptr poison, ptr null}
```
cc @<!-- -->jdoerfert @<!-- -->nikic
Made with [Cursor](https://cursor.com)
---
Patch is 43.49 KiB, truncated to 20.00 KiB below, full version: https://github.com/llvm/llvm-project/pull/217082.diff
5 Files Affected:
- (modified) llvm/lib/Transforms/IPO/AttributorAttributes.cpp (+70-27)
- (modified) llvm/test/Transforms/Attributor/callgraph.ll (+85-330)
- (added) llvm/test/Transforms/Attributor/indirect_call_cycle.ll (+134)
- (added) llvm/test/Transforms/Attributor/indirect_call_signature_mismatch.ll (+57)
- (modified) llvm/test/Transforms/Attributor/nounwind.ll (+49-48)
``````````diff
diff --git a/llvm/lib/Transforms/IPO/AttributorAttributes.cpp b/llvm/lib/Transforms/IPO/AttributorAttributes.cpp
index 050bc32355253..1d43a479599a1 100644
--- a/llvm/lib/Transforms/IPO/AttributorAttributes.cpp
+++ b/llvm/lib/Transforms/IPO/AttributorAttributes.cpp
@@ -12495,11 +12495,51 @@ struct AAIndirectCallInfoCallSite : public AAIndirectCallInfo {
AllCalleesKnownNow = false;
}
+ // A direct call to a callee that can reach the function holding this call
+ // site closes a call graph cycle that previously existed only through the
+ // function pointer, and nothing downstream undoes that: an alwaysinline
+ // dispatcher stops being inlinable once it is in a cycle, and on a target
+ // without a dynamically sized stack the recursion it leaves behind has no
+ // statically known stack size. Record which callees those are so manifest()
+ // can leave them to the indirect call. The question has to be asked here,
+ // because the solver no longer answers once manifestation starts.
+ //
+ // Only edges the call graph agrees are direct can close such a cycle, so
+ // walk the solver's known edges rather than asking AAInterFnReachability,
+ // which conservatively reaches everything downstream of an unknown callee
+ // and would suppress far more than this.
+ SmallPtrSet<Function *, 4> CalleesReachingCallerNow;
+ if (Function *Caller = CB->getFunction()) {
+ auto KnownEdgesReach = [&](Function *From) {
+ SmallPtrSet<Function *, 16> Visited;
+ SmallVector<Function *, 16> Worklist = {From};
+ while (!Worklist.empty()) {
+ Function *Fn = Worklist.pop_back_val();
+ if (Fn == Caller)
+ return true;
+ if (!Visited.insert(Fn).second)
+ continue;
+ const auto *EdgesAA = A.getAAFor<AACallEdges>(
+ *this, IRPosition::function(*Fn), DepClassTy::REQUIRED);
+ if (!EdgesAA)
+ continue;
+ for (Function *Next : EdgesAA->getOptimisticEdges())
+ Worklist.push_back(Next);
+ }
+ return false;
+ };
+ for (Function *Callee : AssumedCalleesNow)
+ if (Callee == Caller || KnownEdgesReach(Callee))
+ CalleesReachingCallerNow.insert(Callee);
+ }
+
if (AssumedCalleesNow == AssumedCallees &&
- AllCalleesKnown == AllCalleesKnownNow)
+ AllCalleesKnown == AllCalleesKnownNow &&
+ CalleesReachingCallerNow == CalleesReachingCaller)
return ChangeStatus::UNCHANGED;
std::swap(AssumedCallees, AssumedCalleesNow);
+ std::swap(CalleesReachingCaller, CalleesReachingCallerNow);
AllCalleesKnown = AllCalleesKnownNow;
return ChangeStatus::CHANGED;
}
@@ -12524,8 +12564,6 @@ struct AAIndirectCallInfoCallSite : public AAIndirectCallInfo {
bool CBIsVoid = CB->getType()->isVoidTy();
BasicBlock::iterator IP = CB->getIterator();
- FunctionType *CSFT = CB->getFunctionType();
- SmallVector<Value *> CSArgs(CB->args());
// If we know all callees and there are none, the call site is (effectively)
// dead (or UB).
@@ -12536,20 +12574,18 @@ struct AAIndirectCallInfoCallSite : public AAIndirectCallInfo {
return ChangeStatus::CHANGED;
}
+ // Callees that can reach the function holding this call site were recorded
+ // during the update; see there for why they are left to the indirect call.
+ auto ReachesCaller = [&](Function *Callee) {
+ return CalleesReachingCaller.contains(Callee);
+ };
+
// Special handling for the single callee case.
- if (AllCalleesKnown && AssumedCallees.size() == 1) {
- auto *NewCallee = AssumedCallees.front();
- if (isLegalToPromote(*CB, NewCallee)) {
- promoteCall(*CB, NewCallee, nullptr);
- NumIndirectCallsPromoted++;
- return ChangeStatus::CHANGED;
- }
- Instruction *NewCall =
- CallInst::Create(FunctionCallee(CSFT, NewCallee), CSArgs,
- CB->getName(), CB->getIterator());
- if (!CBIsVoid)
- A.changeAfterManifest(IRPosition::callsite_returned(*CB), *NewCall);
- A.deleteAfterManifest(*CB);
+ if (AllCalleesKnown && AssumedCallees.size() == 1 &&
+ isLegalToPromote(*CB, AssumedCallees.front()) &&
+ !ReachesCaller(AssumedCallees.front())) {
+ promoteCall(*CB, AssumedCallees.front(), nullptr);
+ NumIndirectCallsPromoted++;
return ChangeStatus::CHANGED;
}
@@ -12566,7 +12602,13 @@ struct AAIndirectCallInfoCallSite : public AAIndirectCallInfo {
SmallVector<Function *, 8> SkippedAssumedCallees;
SmallVector<std::pair<CallInst *, Instruction *>> NewCalls;
for (Function *NewCallee : AssumedCallees) {
- if (!A.shouldSpecializeCallSiteForCallee(*this, *CB, *NewCallee,
+ // A callee the call site cannot be promoted to is one it can only reach
+ // in ways that are undefined, so a direct call built from the call site's
+ // own operands would not be the call the indirect call performs. Leave it
+ // to the indirect fallback, which the !callees metadata below still
+ // names.
+ if (!isLegalToPromote(*CB, NewCallee) || ReachesCaller(NewCallee) ||
+ !A.shouldSpecializeCallSiteForCallee(*this, *CB, *NewCallee,
AssumedCallees.size())) {
SkippedAssumedCallees.push_back(NewCallee);
SpecializedForAllCallees = false;
@@ -12593,16 +12635,11 @@ struct AAIndirectCallInfoCallSite : public AAIndirectCallInfo {
ThenTI->replaceUsesOfWith(ElseBB, CBBB);
}
CastInst *RetBC = nullptr;
- CallInst *NewCall = nullptr;
- if (isLegalToPromote(*CB, NewCallee)) {
- auto *CBClone = cast<CallBase>(CB->clone());
- CBClone->insertBefore(ThenTI->getIterator());
- NewCall = &cast<CallInst>(promoteCall(*CBClone, NewCallee, &RetBC));
- NumIndirectCallsPromoted++;
- } else {
- NewCall = CallInst::Create(FunctionCallee(CSFT, NewCallee), CSArgs,
- CB->getName(), ThenTI->getIterator());
- }
+ auto *CBClone = cast<CallBase>(CB->clone());
+ CBClone->insertBefore(ThenTI->getIterator());
+ CallInst *NewCall =
+ &cast<CallInst>(promoteCall(*CBClone, NewCallee, &RetBC));
+ NumIndirectCallsPromoted++;
NewCalls.push_back({NewCall, RetBC});
}
@@ -12691,6 +12728,12 @@ struct AAIndirectCallInfoCallSite : public AAIndirectCallInfo {
/// time.
SmallSetVector<Function *, 4> AssumedCallees;
+ /// The subset of the assumed callees that can reach the function holding this
+ /// call site, so that specializing for them would make a call graph cycle
+ /// explicit. Determined during the update, where reachability can still be
+ /// queried, and only read when manifesting.
+ SmallPtrSet<Function *, 4> CalleesReachingCaller;
+
/// Flag to indicate if all possible callees are in the AssumedCallees set or
/// if there could be others.
bool AllCalleesKnown = true;
diff --git a/llvm/test/Transforms/Attributor/callgraph.ll b/llvm/test/Transforms/Attributor/callgraph.ll
index 84e2c54bd832d..ace71ed23e7d8 100644
--- a/llvm/test/Transforms/Attributor/callgraph.ll
+++ b/llvm/test/Transforms/Attributor/callgraph.ll
@@ -128,61 +128,23 @@ declare float @retFloatTakeFloatFloatNoundef(float, float noundef)
declare void @void()
define i32 @non_matching_fp1(i1 %c1, i1 %c2, i1 %c) {
-; UNLIM-LABEL: @non_matching_fp1(
-; UNLIM-NEXT: [[FP1:%.*]] = select i1 [[C1:%.*]], ptr @retI32, ptr @takeI32
-; UNLIM-NEXT: [[FP2:%.*]] = select i1 [[C2:%.*]], ptr @retFloatTakeFloat, ptr @void
-; UNLIM-NEXT: [[FP:%.*]] = select i1 [[C:%.*]], ptr [[FP1]], ptr [[FP2]]
-; UNLIM-NEXT: [[TMP1:%.*]] = icmp eq ptr [[FP]], @takeI32
-; UNLIM-NEXT: br i1 [[TMP1]], label [[TMP2:%.*]], label [[TMP3:%.*]]
-; UNLIM: 2:
-; UNLIM-NEXT: [[CALL1:%.*]] = call i32 @takeI32(i32 42)
-; UNLIM-NEXT: br label [[TMP15:%.*]]
-; UNLIM: 3:
-; UNLIM-NEXT: [[TMP4:%.*]] = icmp eq ptr [[FP]], @retI32
-; UNLIM-NEXT: br i1 [[TMP4]], label [[TMP5:%.*]], label [[TMP6:%.*]]
-; UNLIM: 5:
-; UNLIM-NEXT: [[CALL2:%.*]] = call i32 @retI32(i32 42)
-; UNLIM-NEXT: br label [[TMP15]]
-; UNLIM: 6:
-; UNLIM-NEXT: [[TMP7:%.*]] = icmp eq ptr [[FP]], @void
-; UNLIM-NEXT: br i1 [[TMP7]], label [[TMP8:%.*]], label [[TMP9:%.*]]
-; UNLIM: 8:
-; UNLIM-NEXT: [[CALL3:%.*]] = call i32 @void(i32 42)
-; UNLIM-NEXT: br label [[TMP15]]
-; UNLIM: 9:
-; UNLIM-NEXT: br i1 true, label [[TMP10:%.*]], label [[TMP14:%.*]]
-; UNLIM: 10:
-; UNLIM-NEXT: [[TMP11:%.*]] = bitcast i32 42 to float
-; UNLIM-NEXT: [[TMP12:%.*]] = call float @retFloatTakeFloat(float [[TMP11]])
-; UNLIM-NEXT: [[TMP13:%.*]] = bitcast float [[TMP12]] to i32
-; UNLIM-NEXT: br label [[TMP15]]
-; UNLIM: 14:
-; UNLIM-NEXT: unreachable
-; UNLIM: 15:
-; UNLIM-NEXT: [[CALL_PHI:%.*]] = phi i32 [ [[CALL1]], [[TMP2]] ], [ [[CALL2]], [[TMP5]] ], [ [[CALL3]], [[TMP8]] ], [ [[TMP13]], [[TMP10]] ]
-; UNLIM-NEXT: ret i32 [[CALL_PHI]]
-;
-; LIMI2-LABEL: @non_matching_fp1(
-; LIMI2-NEXT: [[FP1:%.*]] = select i1 [[C1:%.*]], ptr @retI32, ptr @takeI32
-; LIMI2-NEXT: [[FP2:%.*]] = select i1 [[C2:%.*]], ptr @retFloatTakeFloat, ptr @void
-; LIMI2-NEXT: [[FP:%.*]] = select i1 [[C:%.*]], ptr [[FP1]], ptr [[FP2]]
-; LIMI2-NEXT: [[TMP1:%.*]] = icmp eq ptr [[FP]], @takeI32
-; LIMI2-NEXT: br i1 [[TMP1]], label [[TMP2:%.*]], label [[TMP3:%.*]]
-; LIMI2: 2:
-; LIMI2-NEXT: [[CALL1:%.*]] = call i32 @takeI32(i32 42)
-; LIMI2-NEXT: br label [[TMP7:%.*]]
-; LIMI2: 3:
-; LIMI2-NEXT: [[TMP4:%.*]] = icmp eq ptr [[FP]], @retI32
-; LIMI2-NEXT: br i1 [[TMP4]], label [[TMP5:%.*]], label [[TMP6:%.*]]
-; LIMI2: 5:
-; LIMI2-NEXT: [[CALL2:%.*]] = call i32 @retI32(i32 42)
-; LIMI2-NEXT: br label [[TMP7]]
-; LIMI2: 6:
-; LIMI2-NEXT: [[CALL3:%.*]] = call i32 [[FP]](i32 42), !callees [[META0:![0-9]+]]
-; LIMI2-NEXT: br label [[TMP7]]
-; LIMI2: 7:
-; LIMI2-NEXT: [[CALL_PHI:%.*]] = phi i32 [ [[CALL1]], [[TMP2]] ], [ [[CALL2]], [[TMP5]] ], [ [[CALL3]], [[TMP6]] ]
-; LIMI2-NEXT: ret i32 [[CALL_PHI]]
+; UPTO2-LABEL: @non_matching_fp1(
+; UPTO2-NEXT: [[FP1:%.*]] = select i1 [[C1:%.*]], ptr @retI32, ptr @takeI32
+; UPTO2-NEXT: [[FP2:%.*]] = select i1 [[C2:%.*]], ptr @retFloatTakeFloat, ptr @void
+; UPTO2-NEXT: [[FP:%.*]] = select i1 [[C:%.*]], ptr [[FP1]], ptr [[FP2]]
+; UPTO2-NEXT: [[TMP1:%.*]] = icmp eq ptr [[FP]], @retFloatTakeFloat
+; UPTO2-NEXT: br i1 [[TMP1]], label [[TMP2:%.*]], label [[TMP6:%.*]]
+; UPTO2: 2:
+; UPTO2-NEXT: [[TMP3:%.*]] = bitcast i32 42 to float
+; UPTO2-NEXT: [[TMP4:%.*]] = call float @retFloatTakeFloat(float [[TMP3]])
+; UPTO2-NEXT: [[TMP5:%.*]] = bitcast float [[TMP4]] to i32
+; UPTO2-NEXT: br label [[TMP7:%.*]]
+; UPTO2: 6:
+; UPTO2-NEXT: [[CALL1:%.*]] = call i32 [[FP]](i32 42), !callees [[META0:![0-9]+]]
+; UPTO2-NEXT: br label [[TMP7]]
+; UPTO2: 7:
+; UPTO2-NEXT: [[CALL_PHI:%.*]] = phi i32 [ [[TMP5]], [[TMP2]] ], [ [[CALL1]], [[TMP6]] ]
+; UPTO2-NEXT: ret i32 [[CALL_PHI]]
;
; LIMI0-LABEL: @non_matching_fp1(
; LIMI0-NEXT: [[FP1:%.*]] = select i1 [[C1:%.*]], ptr @retI32, ptr @takeI32
@@ -199,53 +161,12 @@ define i32 @non_matching_fp1(i1 %c1, i1 %c2, i1 %c) {
}
define i32 @non_matching_fp1_noundef(i1 %c1, i1 %c2, i1 %c) {
-; UNLIM-LABEL: @non_matching_fp1_noundef(
-; UNLIM-NEXT: [[FP1:%.*]] = select i1 [[C1:%.*]], ptr @retI32, ptr @takeI32
-; UNLIM-NEXT: [[FP2:%.*]] = select i1 [[C2:%.*]], ptr @retFloatTakeFloatFloatNoundef, ptr @void
-; UNLIM-NEXT: [[FP:%.*]] = select i1 [[C:%.*]], ptr [[FP1]], ptr [[FP2]]
-; UNLIM-NEXT: [[TMP1:%.*]] = icmp eq ptr [[FP]], @takeI32
-; UNLIM-NEXT: br i1 [[TMP1]], label [[TMP2:%.*]], label [[TMP3:%.*]]
-; UNLIM: 2:
-; UNLIM-NEXT: [[CALL1:%.*]] = call i32 @takeI32(i32 42)
-; UNLIM-NEXT: br label [[TMP9:%.*]]
-; UNLIM: 3:
-; UNLIM-NEXT: [[TMP4:%.*]] = icmp eq ptr [[FP]], @retI32
-; UNLIM-NEXT: br i1 [[TMP4]], label [[TMP5:%.*]], label [[TMP6:%.*]]
-; UNLIM: 5:
-; UNLIM-NEXT: [[CALL2:%.*]] = call i32 @retI32(i32 42)
-; UNLIM-NEXT: br label [[TMP9]]
-; UNLIM: 6:
-; UNLIM-NEXT: br i1 true, label [[TMP7:%.*]], label [[TMP8:%.*]]
-; UNLIM: 7:
-; UNLIM-NEXT: [[CALL3:%.*]] = call i32 @void(i32 42)
-; UNLIM-NEXT: br label [[TMP9]]
-; UNLIM: 8:
-; UNLIM-NEXT: unreachable
-; UNLIM: 9:
-; UNLIM-NEXT: [[CALL_PHI:%.*]] = phi i32 [ [[CALL1]], [[TMP2]] ], [ [[CALL2]], [[TMP5]] ], [ [[CALL3]], [[TMP7]] ]
-; UNLIM-NEXT: ret i32 [[CALL_PHI]]
-;
-; LIMI2-LABEL: @non_matching_fp1_noundef(
-; LIMI2-NEXT: [[FP1:%.*]] = select i1 [[C1:%.*]], ptr @retI32, ptr @takeI32
-; LIMI2-NEXT: [[FP2:%.*]] = select i1 [[C2:%.*]], ptr @retFloatTakeFloatFloatNoundef, ptr @void
-; LIMI2-NEXT: [[FP:%.*]] = select i1 [[C:%.*]], ptr [[FP1]], ptr [[FP2]]
-; LIMI2-NEXT: [[TMP1:%.*]] = icmp eq ptr [[FP]], @takeI32
-; LIMI2-NEXT: br i1 [[TMP1]], label [[TMP2:%.*]], label [[TMP3:%.*]]
-; LIMI2: 2:
-; LIMI2-NEXT: [[CALL1:%.*]] = call i32 @takeI32(i32 42)
-; LIMI2-NEXT: br label [[TMP7:%.*]]
-; LIMI2: 3:
-; LIMI2-NEXT: [[TMP4:%.*]] = icmp eq ptr [[FP]], @retI32
-; LIMI2-NEXT: br i1 [[TMP4]], label [[TMP5:%.*]], label [[TMP6:%.*]]
-; LIMI2: 5:
-; LIMI2-NEXT: [[CALL2:%.*]] = call i32 @retI32(i32 42)
-; LIMI2-NEXT: br label [[TMP7]]
-; LIMI2: 6:
-; LIMI2-NEXT: [[CALL3:%.*]] = call i32 [[FP]](i32 42), !callees [[META1:![0-9]+]]
-; LIMI2-NEXT: br label [[TMP7]]
-; LIMI2: 7:
-; LIMI2-NEXT: [[CALL_PHI:%.*]] = phi i32 [ [[CALL1]], [[TMP2]] ], [ [[CALL2]], [[TMP5]] ], [ [[CALL3]], [[TMP6]] ]
-; LIMI2-NEXT: ret i32 [[CALL_PHI]]
+; UPTO2-LABEL: @non_matching_fp1_noundef(
+; UPTO2-NEXT: [[FP1:%.*]] = select i1 [[C1:%.*]], ptr @retI32, ptr @takeI32
+; UPTO2-NEXT: [[FP2:%.*]] = select i1 [[C2:%.*]], ptr @retFloatTakeFloatFloatNoundef, ptr @void
+; UPTO2-NEXT: [[FP:%.*]] = select i1 [[C:%.*]], ptr [[FP1]], ptr [[FP2]]
+; UPTO2-NEXT: [[CALL:%.*]] = call i32 [[FP]](i32 42), !callees [[META0]]
+; UPTO2-NEXT: ret i32 [[CALL]]
;
; LIMI0-LABEL: @non_matching_fp1_noundef(
; LIMI0-NEXT: [[FP1:%.*]] = select i1 [[C1:%.*]], ptr @retI32, ptr @takeI32
@@ -262,108 +183,38 @@ define i32 @non_matching_fp1_noundef(i1 %c1, i1 %c2, i1 %c) {
}
define void @non_matching_fp2(i1 %c1, i1 %c2, i1 %c, ptr %unknown) {
-; OUNLM-LABEL: @non_matching_fp2(
-; OUNLM-NEXT: [[FP1:%.*]] = select i1 [[C1:%.*]], ptr @retI32, ptr @takeI32
-; OUNLM-NEXT: [[FP2:%.*]] = select i1 [[C2:%.*]], ptr @retFloatTakeFloat, ptr [[UNKNOWN:%.*]]
-; OUNLM-NEXT: [[FP:%.*]] = select i1 [[C:%.*]], ptr [[FP1]], ptr [[FP2]]
-; OUNLM-NEXT: [[TMP1:%.*]] = icmp eq ptr [[FP]], @takeI32
-; OUNLM-NEXT: br i1 [[TMP1]], label [[TMP2:%.*]], label [[TMP3:%.*]]
-; OUNLM: 2:
-; OUNLM-NEXT: call void @takeI32()
-; OUNLM-NEXT: br label [[TMP10:%.*]]
-; OUNLM: 3:
-; OUNLM-NEXT: [[TMP4:%.*]] = icmp eq ptr [[FP]], @retI32
-; OUNLM-NEXT: br i1 [[TMP4]], label [[TMP5:%.*]], label [[TMP6:%.*]]
-; OUNLM: 5:
-; OUNLM-NEXT: call void @retI32()
-; OUNLM-NEXT: br label [[TMP10]]
-; OUNLM: 6:
-; OUNLM-NEXT: [[TMP7:%.*]] = icmp eq ptr [[FP]], @retFloatTakeFloat
-; OUNLM-NEXT: br i1 [[TMP7]], label [[TMP8:%.*]], label [[TMP9:%.*]]
-; OUNLM: 8:
-; OUNLM-NEXT: call void @retFloatTakeFloat()
-; OUNLM-NEXT: br label [[TMP10]]
-; OUNLM: 9:
-; OUNLM-NEXT: call void [[FP]]()
-; OUNLM-NEXT: br label [[TMP10]]
-; OUNLM: 10:
-; OUNLM-NEXT: ret void
-;
-; LIMI2-LABEL: @non_matching_fp2(
-; LIMI2-NEXT: [[FP1:%.*]] = select i1 [[C1:%.*]], ptr @retI32, ptr @takeI32
-; LIMI2-NEXT: [[FP2:%.*]] = select i1 [[C2:%.*]], ptr @retFloatTakeFloat, ptr [[UNKNOWN:%.*]]
-; LIMI2-NEXT: [[FP:%.*]] = select i1 [[C:%.*]], ptr [[FP1]], ptr [[FP2]]
-; LIMI2-NEXT: [[TMP1:%.*]] = icmp eq ptr [[FP]], @takeI32
-; LIMI2-NEXT: br i1 [[TMP1]], label [[TMP2:%.*]], label [[TMP3:%.*]]
-; LIMI2: 2:
-; LIMI2-NEXT: call void @takeI32()
-; LIMI2-NEXT: br label [[TMP7:%.*]]
-; LIMI2: 3:
-; LIMI2-NEXT: [[TMP4:%.*]] = icmp eq ptr [[FP]], @retI32
-; LIMI2-NEXT: br i1 [[TMP4]], label [[TMP5:%.*]], label [[TMP6:%.*]]
-; LIMI2: 5:
-; LIMI2-NEXT: call void @retI32()
-; LIMI2-NEXT: br label [[TMP7]]
-; LIMI2: 6:
-; LIMI2-NEXT: call void [[FP]]()
-; LIMI2-NEXT: br label [[TMP7]]
-; LIMI2: 7:
-; LIMI2-NEXT: ret void
-;
-; LIMI0-LABEL: @non_matching_fp2(
-; LIMI0-NEXT: [[FP1:%.*]] = select i1 [[C1:%.*]], ptr @retI32, ptr @takeI32
-; LIMI0-NEXT: [[FP2:%.*]] = select i1 [[C2:%.*]], ptr @retFloatTakeFloat, ptr [[UNKNOWN:%.*]]
-; LIMI0-NEXT: [[FP:%.*]] = select i1 [[C:%.*]], ptr [[FP1]], ptr [[FP2]]
-; LIMI0-NEXT: call void [[FP]]()
-; LIMI0-NEXT: ret void
+; OWRDL-LABEL: @non_matching_fp2(
+; OWRDL-NEXT: [[FP1:%.*]] = select i1 [[C1:%.*]], ptr @retI32, ptr @takeI32
+; OWRDL-NEXT: [[FP2:%.*]] = select i1 [[C2:%.*]], ptr @retFloatTakeFloat, ptr [[UNKNOWN:%.*]]
+; OWRDL-NEXT: [[FP:%.*]] = select i1 [[C:%.*]], ptr [[FP1]], ptr [[FP2]]
+; OWRDL-NEXT: call void [[FP]]()
+; OWRDL-NEXT: ret void
;
; CWRLD-LABEL: @non_matching_fp2(
; CWRLD-NEXT: [[FP1:%.*]] = select i1 [[C1:%.*]], ptr @retI32, ptr @takeI32
; CWRLD-NEXT: [[FP2:%.*]] = select i1 [[C2:%.*]], ptr @retFloatTakeFloat, ptr [[UNKNOWN:%.*]]
; CWRLD-NEXT: [[FP:%.*]] = select i1 [[C:%.*]], ptr [[FP1]], ptr [[FP2]]
-; CWRLD-NEXT: [[TMP1:%.*]] = icmp eq ptr [[FP]], @takeI32
+; CWRLD-NEXT: [[TMP1:%.*]] = icmp eq ptr [[FP]], @func3
; CWRLD-NEXT: br i1 [[TMP1]], label [[TMP2:%.*]], label [[TMP3:%.*]]
; CWRLD: 2:
-; CWRLD-NEXT: call void @takeI32()
+; CWRLD-NEXT: call void @func3()
; CWRLD-NEXT: br label [[TMP21:%.*]]
; CWRLD: 3:
-; CWRLD-NEXT: [[TMP4:%.*]] = icmp eq ptr [[FP]], @retI32
+; CWRLD-NEXT: [[TMP4:%.*]] = icmp eq ptr [[FP]], @func4
; CWRLD-NEXT: br i1 [[TMP4]], label [[TMP5:%.*]], label [[TMP6:%.*]]
; CWRLD: 5:
-; CWRLD-NEXT: call void @retI32()
+; CWRLD-NEXT: call void @func4()
; CWRLD-NEXT: br label [[TMP21]]
; CWRLD: 6:
-; CWRLD-NEXT: [[TMP7:%.*]] = icmp eq ptr [[FP]], @func3
+; CWRLD-NEXT: [[TMP7:%.*]] = icmp eq ptr [[FP]], @void
; CWRLD-NEXT: br i1 [[TMP7]], label [[TMP8:%.*]], label [[TMP9:%.*]]
; CWRLD: 8:
-; CWRLD-NEXT: call void @func3()
+; CWRLD-NEXT: call void @void()
; CWRLD-NEXT: br label [[TMP21]]
; CWRLD: 9:
-; CWRLD-NEXT: [[TMP10:%.*]] = icmp eq ptr [[FP]], @func4
-; CWRLD-NEXT: br i1 [[TMP10]], label [[TMP11:%.*]], label [[TMP12:%.*]]
-; CWRLD: 11:
-; CWRLD-NEXT: call void @func4()
+; CWRLD-NEXT: call void [[FP]](), !callees [[META1:![0-9]+]]
; CWRLD-NEXT: br label [[TMP21]]
-; CWRLD: 12:
-; CWRLD-NEXT: [[TMP13:%.*]] = icmp eq ptr [[FP]], @retFloatTakeFloat
-; CWRLD-NEXT: br i1 [[TMP13]], label [[TMP14:%.*]], label [[TMP15:%.*]]
-; CWRLD: 14:
-; CWRLD-NEXT: call void @retFloatTakeFloat()
-; CWRLD-NEXT: br label [[TMP21]]
-; CWRLD: 15:
-; CWRLD-NEXT: [[TMP16:%.*]] = icmp eq ptr [[FP]], @retFloatTakeFloatFloatNoundef
-; CWRLD-NEXT: br i1 [[TMP16]], label [[TMP17:%.*]], label [[TMP18:%.*]]
-; CWRLD: 17:
-; CWRLD-NEXT: call void @retFloatTakeFloatFloatNoundef()
-; CWRLD-NEXT: br label [[TMP21]]
-; CWRLD: 18:
-; CWRLD-NEXT: br i1 true, label [[TMP19:%.*]], label [[TMP20:%.*]]
-; CWRLD: 19:
-; CWRLD-NEXT: call void @void()
-; CWRLD-NEXT: br label [[TMP21]]
-; CWRLD: 20:
-; CWRLD-NEXT: unreachable
-; CWRLD: 21:
+; CWRLD: 10:
; CWRLD-NEXT: ret void
;
%fp1 = select i1 %c1, ptr @retI32, ptr @takeI32
@@ -374,87 +225,25 @@ define void @non_matching_fp2(i1 %c1, i1 %c2, i1 %c, ptr %unknown) {
}
define i32 @non_matching_unknown(i1 %c, ptr %fn) {
-; OUNLM-LABEL: @non_matching_unknown(
-; OUNLM-NEXT: [[FP:%.*]] = select i1 [[C:%.*]], ptr @retI32, ptr [[FN:%.*]]
-; OUNLM-NEXT: [[TMP1:%.*]] = icmp eq ptr [[FP]], @retI32
-; OUNLM-NEXT: br i1 [[TMP1]], label [[TMP2:%.*]], label [[TMP3:%.*]]
-; OUNLM: 2:
-; OUNLM-NEXT: [[CALL1:%.*]] = call i32 @retI32(i32 42)
-; OUNLM-NEXT: br label [[TMP4:%.*]]
-; OUNLM: ...
[truncated]
``````````
</details>
https://github.com/llvm/llvm-project/pull/217082
More information about the llvm-commits
mailing list