[llvm] [Attributor] Don't specialize an indirect call for a callee it cannot call (PR #217077)
via llvm-commits
llvm-commits at lists.llvm.org
Tue Aug 18 09:47:15 PDT 2026
llvmorg-github-actions[bot] wrote:
<!--LLVM PR SUMMARY COMMENT-->
@llvm/pr-subscribers-llvm-transforms
Author: Larry Meadows (lfmeadow)
<details>
<summary>Changes</summary>
`AAIndirectCallInfoCallSite::manifest()` replaces an indirect call with an if-cascade of direct calls, one arm per assumed callee. Where a callee cannot be promoted to, it asks `isLegalToPromote()`, is told no, and then builds the call anyway by another route:
```c++
NewCall = CallInst::Create(FunctionCallee(CSFT, NewCallee), CSArgs,
CB->getName(), ThenTI->getIterator());
```
a direct call naming the callee but carrying the call site's function type and operands.
Given a call site that passes one argument and two candidates, one taking one parameter and one taking two:
```llvm
define void @<!-- -->caller(i1 %c) {
%fp = select i1 %c, ptr @<!-- -->two_params, ptr @<!-- -->one_param
call void %fp(i32 1)
ret void
}
```
`opt -passes=attributor` produces an arm that calls a two-parameter function with one argument:
```llvm
4:
call void @<!-- -->two_params(i32 1)
```
`@<!-- -->two_params` reads a second parameter that nothing supplies. The signature at the call site is not the callee's, so this is not a call the indirect call could have performed — it is reachable through it only in ways that are undefined — and naming the callee directly hands the rest of the pipeline a call site to reason about as if the signature matched.
With this change the promotable candidate is still specialized and the other is left to the fallback, which the `!callees` metadata already names, so nothing is lost:
```llvm
2:
call void @<!-- -->one_param(i32 1)
br label %4
3:
call void %fp(i32 1), !callees !0
```
Since the arms that remain are promotable by construction, the fallback path in the loop and in the single-callee case both go away.
Two in-tree tests change, and both are this shape: in `nounwind.ll` the candidates return `i32` while the call site is `call void %fp()`, and `callgraph.ll` has several of the same. The punned direct calls are replaced by the indirect call surviving with its metadata.
`check-llvm` is clean: 46668 passed, 77 expectedly failed, no unexpected failures.
cc @<!-- -->jdoerfert
---
Patch is 34.91 KiB, truncated to 20.00 KiB below, full version: https://github.com/llvm/llvm-project/pull/217077.diff
4 Files Affected:
- (modified) llvm/lib/Transforms/IPO/AttributorAttributes.cpp (+16-26)
- (modified) llvm/test/Transforms/Attributor/callgraph.ll (+81-326)
- (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..484d163d3c01b 100644
--- a/llvm/lib/Transforms/IPO/AttributorAttributes.cpp
+++ b/llvm/lib/Transforms/IPO/AttributorAttributes.cpp
@@ -12524,8 +12524,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).
@@ -12537,19 +12535,10 @@ struct AAIndirectCallInfoCallSite : public AAIndirectCallInfo {
}
// 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())) {
+ promoteCall(*CB, AssumedCallees.front(), nullptr);
+ NumIndirectCallsPromoted++;
return ChangeStatus::CHANGED;
}
@@ -12566,7 +12555,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) ||
+ !A.shouldSpecializeCallSiteForCallee(*this, *CB, *NewCallee,
AssumedCallees.size())) {
SkippedAssumedCallees.push_back(NewCallee);
SpecializedForAllCallees = false;
@@ -12593,16 +12588,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});
}
diff --git a/llvm/test/Transforms/Attributor/callgraph.ll b/llvm/test/Transforms/Attributor/callgraph.ll
index 84e2c54bd832d..0dd6ac64158d6 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: 3:
-; OUNLM-NEXT: [[CALL2:%.*]] = call i32 [[FP]](i32 42)
-; OUNLM-NEXT: br label [[TMP4]]
-; OUNLM: 4:
-; OUNLM-NEXT: [[CALL_PHI:%.*]] = phi i32 [ [[CALL1]], [[TMP2]] ], [ [[CALL2]], [[TMP3]] ]
-; OUNLM-NEXT: ret i32 [[CALL_PHI]]
-;
-; LIMI2-LABEL: @non_matching_unknown(
-; LIMI2-NEXT: [[FP:%.*]] = select i1 [[C:%.*]], ptr @retI32, ptr [[FN:%.*]]
-; LIMI2-NEXT: [[TMP1:%.*]] = icmp eq ptr [[FP]], @retI32
-; LIMI2-NEXT: br i1 [[TMP1]], label [[TMP2:%.*]], label [[TMP3:%.*]]
-; LIMI2: 2:
-; LIMI2-NEXT: [[CALL1:%.*]] = call i32 @retI32(i32 42)
-; LIMI2-NEXT: br label [[TMP4:%.*]]
-; LIMI2: 3:
-; LIMI2-NEXT: [[CALL2:%.*]] = call i32 [[FP]](i32 42)
-; LIMI2-NEXT: br label [[TMP4]]
-; LIMI2: 4:
-; LIMI2-NEXT: [[CALL_PHI:%.*]] = phi i32 [ [[CALL1]], [[TMP2]] ], [ [[CALL2]], [[TMP3]] ]
-; LIMI2-NEXT: ret i32 [[CALL_PHI]]
-;
-; LIMI0-LABEL: @non_matching_unknown(
-; LIMI0-NEXT: [[FP:%.*]] = select i1 [[C:%.*]], ptr @retI32, ptr [[FN:%.*]]
-; LIMI0-NEXT: [[CALL:%.*]] = call i32 [[FP]](i32 42)
-; LIMI0-NEXT: ret i32 [[CALL]]
+; OWRDL-LABEL: @non_matching_unknown(
+; OWRDL-NEXT: [[FP:%.*]] = select i1 [[C:%.*]], ptr @retI32, ptr [[FN:%.*]]
+; OWRDL-NEXT: [[CALL:%.*]] = call i32 [[FP]](i32 42)
+; OWRDL-NEXT: ret i32 [[CALL]]
;
; CWRLD-LABEL: @non_matching_unknown(
; CWRLD-NEXT: [[FP:%.*]] = select i1 [[C:%.*]], ptr @retI32, ptr [[FN:%.*]]
-; CWRLD-NEXT: [[TMP1:%.*]] = icmp eq ptr [[FP]], @func3
-; CWRLD-NEXT: br i1 [[TMP1]], label [[TMP2:%.*]], label [[TMP3:%.*]]
-; CWRLD: 2:
-; CWRLD-NEXT: [[CALL1:%.*]] = call i32 @func3(i32 42)
-; CWRLD-NEXT: br label [[TMP24:%.*]]
-; CWRLD: 3:
-; CWRLD-NEXT: [[TMP4:%.*]] = icmp eq ptr [[FP]], @func4
-; CWRLD-NEXT: br i1 [[TMP4]], label [[TMP5:%.*]], label [[TMP6:%.*]]
-; CWRLD: 5:
-; CWRLD-NEXT: [[CALL2:%.*]] = call i32 @func4(i32 42)
-; CWRLD-NEXT: br label [[TMP24]]
-; CWRLD: 6:
-; CWRLD-NEXT: [[TMP7:%.*]] = icmp eq ptr [[FP]], @retI32
-; CWRLD-NEXT: br i1 [[TMP7]], label [[TMP8:%.*]], label [[TMP9:%.*]]
-; CWRLD: 8:
-; CWRLD-NEXT: [[CALL3:%.*]] = call i32 @retI32(i32 42)
-; CWRLD-NEXT: br label [[TMP24]]
-; CWRLD: 9:
-; CWRLD-NEXT: [[TMP10:%.*]] = icmp eq ptr [[FP]], @takeI32
-; CWRLD-NEXT: br i1 [[TMP10]], label [[TMP11:%.*]], label [[TMP12:%.*]]
-; CWRLD: 11:
-; CWRLD-NEXT: [[CALL4:%.*]] = call i32 @takeI32(i32 42)
-; CWRLD-NEXT: br label [[TMP24]]
-; CWRLD: 12:
; CWRLD-NEXT: [[TMP13:%.*]] = icmp eq ptr [[FP]], @retFloatTakeFloat
; CWRLD-NEXT: br i1 [[TMP13]], label [[TMP14:%.*]], label [[TMP18:%.*]]
-; CWRLD: 14:
+; CWRLD: 2:
; CWRLD-NEXT: [[TMP15:%.*]] = bitcast i32 42 to float
; CWRLD-NEXT: [[TMP16:%.*]] = call float @retFloatTakeFloat(float [[TMP15]])
; CWRLD-NEXT: [[TMP17:%.*]] = bitcast float [[TMP16]] to i32
+; CWRLD-NEXT: br label [[TMP24:%.*]]
+; CWRLD: 6:
+; CWRLD-NEXT: [[CALL1:%.*]] = call i32 [[FP]](i32 42), !callees [[META2:![0-9]+]]
; CWRLD-NEXT: br label [[TMP24]]
-; CWRLD: 18:
-; CWRLD-NEXT: [[TMP19:%.*]] = icmp eq ptr [[FP]], @retFloatTakeFloatFloatNoundef
-; CWRLD-NEXT: br i1 [[TMP19]], label [[TMP20:%.*]], label [[TMP21:%.*]]
-; CWRLD: 20:
-; CWRLD-NEXT: [[CALL5:%.*]] = call i32 @retFloatTakeFloatFloatNoundef(i32 42)
-; CWRLD-NEXT: br label [[TMP24]]
-; CWRLD: 21:
-; CWRLD-NEXT: br i1 true, label [[TMP22:%.*]], label [[TMP23:%....
[truncated]
``````````
</details>
https://github.com/llvm/llvm-project/pull/217077
More information about the llvm-commits
mailing list