Skip to content

[FastISel] Lower call instruction with illegal type returned#180322

Merged
LuoYuanke merged 4 commits intollvm:mainfrom
LuoYuanke:fastISel-v4i1
Mar 10, 2026
Merged

[FastISel] Lower call instruction with illegal type returned#180322
LuoYuanke merged 4 commits intollvm:mainfrom
LuoYuanke:fastISel-v4i1

Conversation

@LuoYuanke
Copy link
Copy Markdown
Contributor

@LuoYuanke LuoYuanke commented Feb 7, 2026

Fix issue #179100
When lowering the call instruction with illegal type returned, we should
bail out and transfer the lowering to DAG. Otherwise the return value is
not promoted to proper type, but DAG would assume it has been promoted.

@llvmbot llvmbot added backend:X86 llvm:SelectionDAG SelectionDAGISel as well labels Feb 7, 2026
@llvmbot
Copy link
Copy Markdown
Member

llvmbot commented Feb 7, 2026

@llvm/pr-subscribers-llvm-selectiondag

@llvm/pr-subscribers-backend-x86

Author: Luo Yuanke (LuoYuanke)

Changes

Full diff: https://github.com/llvm/llvm-project/pull/180322.diff

2 Files Affected:

  • (modified) llvm/lib/CodeGen/SelectionDAG/SelectionDAGBuilder.cpp (+8-2)
  • (added) llvm/test/CodeGen/X86/fast-isel-v4i1.ll (+27)
diff --git a/llvm/lib/CodeGen/SelectionDAG/SelectionDAGBuilder.cpp b/llvm/lib/CodeGen/SelectionDAG/SelectionDAGBuilder.cpp
index 27131e14141cc..3010c4e6430f2 100644
--- a/llvm/lib/CodeGen/SelectionDAG/SelectionDAGBuilder.cpp
+++ b/llvm/lib/CodeGen/SelectionDAG/SelectionDAGBuilder.cpp
@@ -2019,8 +2019,14 @@ SDValue SelectionDAGBuilder::getValueImpl(const Value *V) {
 
     std::optional<CallingConv::ID> CallConv;
     auto *CB = dyn_cast<CallBase>(Inst);
-    if (CB && !CB->isInlineAsm())
-      CallConv = CB->getCallingConv();
+
+    if (CB && !CB->isInlineAsm()) {
+      if (Inst->getType()->isFirstClassType()) {
+        EVT VT = TLI.getValueType(DAG.getDataLayout(), Inst->getType());
+        if (!TLI.isTypeLegal(VT))
+          CallConv = CB->getCallingConv();
+      }
+    }
 
     RegsForValue RFV(*DAG.getContext(), TLI, DAG.getDataLayout(), InReg,
                      Inst->getType(), CallConv);
diff --git a/llvm/test/CodeGen/X86/fast-isel-v4i1.ll b/llvm/test/CodeGen/X86/fast-isel-v4i1.ll
new file mode 100644
index 0000000000000..2e9a26a93d507
--- /dev/null
+++ b/llvm/test/CodeGen/X86/fast-isel-v4i1.ll
@@ -0,0 +1,27 @@
+; NOTE: Assertions have been autogenerated by utils/update_llc_test_checks.py UTC_ARGS: --version 6
+; RUN: llc --fast-isel < %s -mtriple=x86_64-unknown-unknown | FileCheck %s
+
+define fastcc i16 @test() #0 nounwind {
+; CHECK-LABEL: test:
+; CHECK:       # %bb.0: # %entry
+; CHECK-NEXT:    pushq %rax
+; CHECK-NEXT:    xorl %eax, %eax
+; CHECK-NEXT:    vpxor %xmm0, %xmm0, %xmm0
+; CHECK-NEXT:    xorl %edi, %edi
+; CHECK-NEXT:    callq *%rax
+; CHECK-NEXT:    vpslld $31, %xmm0, %xmm0
+; CHECK-NEXT:    xorl %eax, %eax
+; CHECK-NEXT:    xorl %edi, %edi
+; CHECK-NEXT:    vpmovd2m %xmm0, %k0
+; CHECK-NEXT:    vpxor %xmm0, %xmm0, %xmm0
+; CHECK-NEXT:    vpmovm2d %k0, %xmm1
+; CHECK-NEXT:    callq *%rax
+; CHECK-NEXT:    popq %rcx
+; CHECK-NEXT:    retq
+entry:
+  %0 = call fastcc <4 x i1> null(ptr null, <4 x i1> zeroinitializer)
+  %1 = call fastcc i16 null(ptr null, <4 x i1> zeroinitializer, <4 x i1> %0)
+  ret i16 %1
+}
+
+attributes #0 = { "target-cpu"="znver5" }

Comment on lines 22 to 23
Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Avoid UB in tests, and use named values

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Revised

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The type legality should not be a factor here

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Revised

@LuoYuanke LuoYuanke changed the title [FastISel] Get right type for value from fast isel [FastISel] Lower call instruction with illegal type returned Feb 8, 2026
@github-actions
Copy link
Copy Markdown

github-actions bot commented Feb 8, 2026

✅ With the latest revision this PR passed the undef deprecator.

When lowering the call instruction with illegal type returned, we should
bail out and transfer the lowering to DAG. Otherwise the return value is
not promoted to proper type, but DAG would assume it has been promoted.
Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This logic kind of makes sense, but this is too narrow, and I would expect would already logically happen. Why wouldn't the same apply for the input arguments? I thought fast isel already gave up on illegally typed operations, so why does this need a new special case?

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I wouldn't use mips as a reference on how to do anything

@nikic
Copy link
Copy Markdown
Contributor

nikic commented Feb 8, 2026

Is this fixing #179100? If so, please reference it in the PR description.

@LuoYuanke
Copy link
Copy Markdown
Contributor Author

Is this fixing #179100? If so, please reference it in the PR description.

Done

@LuoYuanke LuoYuanke requested a review from arsenm February 10, 2026 03:48
Co-authored-by: Craig Topper <craig.topper@sifive.com>
@github-actions
Copy link
Copy Markdown

github-actions bot commented Feb 10, 2026

✅ With the latest revision this PR passed the C/C++ code formatter.

@LuoYuanke LuoYuanke requested a review from topperc February 10, 2026 07:19
Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I'd prefer this test file was called pr179100.ll for better reference

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Revised.

@RKSimon RKSimon self-requested a review February 18, 2026 09:38
Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Probably should be processing the processed return type, instead of this. AArch64 example:

if (!isTypeLegal(Val->getType(), VT) &&

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I think CLI.OutVals is not the returned values. X86 has code to check it at https://github.com/llvm/llvm-project/blob/main/llvm/lib/Target/X86/X86FastISel.cpp#L3306

@alexrp
Copy link
Copy Markdown
Member

alexrp commented Mar 9, 2026

Friendly ping on reviews since the bug this is fixing will be a problem for Zig's LLVM 22 upgrade.

@LuoYuanke LuoYuanke requested a review from arsenm March 9, 2026 01:09
@LuoYuanke
Copy link
Copy Markdown
Contributor Author

ping

Copy link
Copy Markdown
Contributor

@phoebewang phoebewang left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

LGTM.

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

These are redundant but functional correct. I think it's not a big problem for fast isel.

@LuoYuanke
Copy link
Copy Markdown
Contributor Author

I think the required change from @arsenm has been addressed. I'll land the patch if there is no objection.

@LuoYuanke LuoYuanke merged commit 41ef3d0 into llvm:main Mar 10, 2026
10 checks passed
@LuoYuanke LuoYuanke deleted the fastISel-v4i1 branch March 10, 2026 03:56
@alexrp alexrp added this to the LLVM 22.x Release milestone Mar 10, 2026
@github-project-automation github-project-automation bot moved this to Needs Triage in LLVM Release Status Mar 10, 2026
@github-project-automation github-project-automation bot moved this from Needs Triage to Done in LLVM Release Status Mar 10, 2026
@nikic
Copy link
Copy Markdown
Contributor

nikic commented Mar 10, 2026

For the record, this causes an -O0 compile-time regression for tramp3d-v4: https://llvm-compile-time-tracker.com/compare.php?from=351d900e6c96ee51cbb40c933969b5ebd15a4122&to=41ef3d083a0925cb9c184057f76a0d42ad5680ab&stat=instructions:u I assume it often uses some illegal type for returns, but I haven't checked what it is. My guess would be i1.

@LuoYuanke
Copy link
Copy Markdown
Contributor Author

For the record, this causes an -O0 compile-time regression for tramp3d-v4: https://llvm-compile-time-tracker.com/compare.php?from=351d900e6c96ee51cbb40c933969b5ebd15a4122&to=41ef3d083a0925cb9c184057f76a0d42ad5680ab&stat=instructions:u I assume it often uses some illegal type for returns, but I haven't checked what it is. My guess would be i1.

Switching from fast ISel to DAG ISel would spent more compile-time on ISel. The i1 return type is promoted to i8 which is the same in ISel promotion. The bf16 return type is bf16, while it is promoted to f32 in ISel. Maybe we can check if the promoted type is the same to abi return type before switching form fast ISel to DAG ISel.

dyung pushed a commit to llvmbot/llvm-project that referenced this pull request Mar 12, 2026
…0322)

Fix issue llvm#179100
When lowering the call instruction with illegal type returned, we should
bail out and transfer the lowering to DAG. Otherwise the return value is
not promoted to proper type, but DAG would assume it has been promoted.

---------

Co-authored-by: Yuanke Luo <ykluo@birentech.com>
(cherry picked from commit 41ef3d0)
@LuoYuanke
Copy link
Copy Markdown
Contributor Author

LuoYuanke commented Mar 16, 2026

I create a PR (#186723) to improve the compile-time.

nikic added a commit to rust-lang/llvm-project that referenced this pull request Mar 28, 2026
nikic added a commit to rust-lang/llvm-project that referenced this pull request Mar 28, 2026
…lvm#180322)"

This reverts commit 4dfb4b6.

This causes a large compile-time regression for debug builds.
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

backend:X86 llvm:SelectionDAG SelectionDAGISel as well

Projects

Development

Successfully merging this pull request may close these issues.

8 participants