[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