Skip to content

[X86][SelectionDAG] Register type affect DAG ISel#179446

Open
woruyu wants to merge 1 commit intollvm:mainfrom
woruyu:fix/register-type-for-call
Open

[X86][SelectionDAG] Register type affect DAG ISel#179446
woruyu wants to merge 1 commit intollvm:mainfrom
woruyu:fix/register-type-for-call

Conversation

@woruyu
Copy link
Copy Markdown
Member

@woruyu woruyu commented Feb 3, 2026

Summary

This PR resolves #179100, the related PR: #164565

@llvmbot llvmbot added the llvm:SelectionDAG SelectionDAGISel as well label Feb 3, 2026
@llvmbot
Copy link
Copy Markdown
Member

llvmbot commented Feb 3, 2026

@llvm/pr-subscribers-llvm-selectiondag

Author: woruyu (woruyu)

Changes

Summary

This PR resolves #179100, the related PR: #164565


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

1 Files Affected:

  • (modified) llvm/lib/CodeGen/SelectionDAG/SelectionDAGBuilder.cpp (+1-6)
diff --git a/llvm/lib/CodeGen/SelectionDAG/SelectionDAGBuilder.cpp b/llvm/lib/CodeGen/SelectionDAG/SelectionDAGBuilder.cpp
index 63c9d193421ea..ea3192208a81e 100644
--- a/llvm/lib/CodeGen/SelectionDAG/SelectionDAGBuilder.cpp
+++ b/llvm/lib/CodeGen/SelectionDAG/SelectionDAGBuilder.cpp
@@ -2017,13 +2017,8 @@ SDValue SelectionDAGBuilder::getValueImpl(const Value *V) {
   if (const Instruction *Inst = dyn_cast<Instruction>(V)) {
     Register InReg = FuncInfo.InitializeRegForValue(Inst);
 
-    std::optional<CallingConv::ID> CallConv;
-    auto *CB = dyn_cast<CallBase>(Inst);
-    if (CB && !CB->isInlineAsm())
-      CallConv = CB->getCallingConv();
-
     RegsForValue RFV(*DAG.getContext(), TLI, DAG.getDataLayout(), InReg,
-                     Inst->getType(), CallConv);
+                     Inst->getType(), std::nullopt);
     SDValue Chain = DAG.getEntryNode();
     return RFV.getCopyFromRegs(DAG, FuncInfo, getCurSDLoc(), Chain, nullptr, V);
   }

Copy link
Copy Markdown
Contributor

@arsenm arsenm left a comment

Choose a reason for hiding this comment

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

Needs tests

@phoebewang
Copy link
Copy Markdown
Contributor

Then we will make problems like #134222 and #151692 again. Is there a way we can fix both?

@woruyu
Copy link
Copy Markdown
Member Author

woruyu commented Feb 3, 2026

// Old DAG
SelectionDAG has 25 nodes:
  t0: ch,glue = EntryToken
  t3: v4i1 = BUILD_VECTOR Constant:i1<0>, Constant:i1<0>, Constant:i1<0>, Constant:i1<0>
    t10: ch,glue = callseq_start t0, TargetConstant:i64<0>, TargetConstant:i64<0>
  t12: ch,glue = CopyToReg t10, Register:i64 $rdi, Constant:i64<0>
    t7: v4i32 = BUILD_VECTOR Constant:i32<0>, Constant:i32<0>, Constant:i32<0>, Constant:i32<0>
  t14: ch,glue = CopyToReg t12, Register:v4i32 $xmm0, t7, t12:1
      t5: v4i1,ch = CopyFromReg t0, Register:v4i1 %3
    t8: v4i32 = any_extend t5
  t16: ch,glue = CopyToReg t14, Register:v4i32 $xmm1, t8, t14:1
  t18: ch,glue = X86ISD::CALL t16, Constant:i64<0>, Register:i64 $rdi, Register:v4i32 $xmm0, Register:v4i32 $xmm1, RegisterMask:Untyped, t16:1
  t19: ch,glue = callseq_end t18, TargetConstant:i64<0>, TargetConstant:i64<0>, t18:1
  t21: i16,ch,glue = CopyFromReg t19, Register:i16 $ax, t19:1
    t23: ch = CopyToReg t0, Register:i16 %0, t21
  t24: ch = TokenFactor t23, t21:1

// Cur DAG
SelectionDAG has 25 nodes:
  t0: ch,glue = EntryToken
  t3: v4i1 = BUILD_VECTOR Constant:i1<0>, Constant:i1<0>, Constant:i1<0>, Constant:i1<0>
  t5: v4i32,ch = CopyFromReg t0, Register:v4i32 %3
  t6: v4i1 = truncate t5
    t10: ch,glue = callseq_start t0, TargetConstant:i64<0>, TargetConstant:i64<0>
  t12: ch,glue = CopyToReg t10, Register:i64 $rdi, Constant:i64<0>
    t8: v4i32 = BUILD_VECTOR Constant:i32<0>, Constant:i32<0>, Constant:i32<0>, Constant:i32<0>
  t14: ch,glue = CopyToReg t12, Register:v4i32 $xmm0, t8, t12:1
  t16: ch,glue = CopyToReg t14, Register:v4i32 $xmm1, t5, t14:1
  t18: ch,glue = X86ISD::CALL t16, Constant:i64<0>, Register:i64 $rdi, Register:v4i32 $xmm0, Register:v4i32 $xmm1, RegisterMask:Untyped, t16:1
  t19: ch,glue = callseq_end t18, TargetConstant:i64<0>, TargetConstant:i64<0>, t18:1
  t21: i16,ch,glue = CopyFromReg t19, Register:i16 $ax, t19:1
    t23: ch = CopyToReg t0, Register:i16 %0, t21
  t24: ch = TokenFactor t23, t21:1

The difference comes from the virtual register type. In the old DAG, the value is carried as v4i1, which matches the source-level semantics. In the new DAG it is carried as v4i32. As a result, the new lowering no longer produces the explicit step:

t8: v4i32 = any_extend t5

However, that any_extend is not “free”: it still has to be legalized/selected later, typically into something like:

t25: v4i32 = VPMOVM2DZ128rk t5

I understand the overall pipeline, but I’m not sure what the best approach is to avoid or handle this missing any_extend step. Any suggestions?

@woruyu
Copy link
Copy Markdown
Member Author

woruyu commented Feb 3, 2026

Needs tests

understand, but I don't come up with a suitable method to fix both

@woruyu
Copy link
Copy Markdown
Member Author

woruyu commented Feb 3, 2026

Then we will make problems like #134222 and #151692 again. Is there a way we can fix both?

maybe I need spent some time to understand fast Isel parts.

@github-actions
Copy link
Copy Markdown

github-actions bot commented Feb 3, 2026

🐧 Linux x64 Test Results

  • 169116 tests passed
  • 3028 tests skipped
  • 1 test failed

Failed Tests

(click on a test name to see its output)

LLVM

LLVM.CodeGen/X86/bf16-fast-isel.ll
Exit Code: 1

Command Output (stdout):
--
# RUN: at line 2
/home/gha/actions-runner/_work/llvm-project/llvm-project/build/bin/llc --fast-isel < /home/gha/actions-runner/_work/llvm-project/llvm-project/llvm/test/CodeGen/X86/bf16-fast-isel.ll -mtriple=x86_64-unknown-unknown | /home/gha/actions-runner/_work/llvm-project/llvm-project/build/bin/FileCheck /home/gha/actions-runner/_work/llvm-project/llvm-project/llvm/test/CodeGen/X86/bf16-fast-isel.ll
# executed command: /home/gha/actions-runner/_work/llvm-project/llvm-project/build/bin/llc --fast-isel -mtriple=x86_64-unknown-unknown
# note: command had no output on stdout or stderr
# executed command: /home/gha/actions-runner/_work/llvm-project/llvm-project/build/bin/FileCheck /home/gha/actions-runner/_work/llvm-project/llvm-project/llvm/test/CodeGen/X86/bf16-fast-isel.ll
# .---command stderr------------
# | /home/gha/actions-runner/_work/llvm-project/llvm-project/llvm/test/CodeGen/X86/bf16-fast-isel.ll:9:15: error: CHECK-NEXT: is not on the line after the previous match
# | ; CHECK-NEXT: callq bar@PLT
# |               ^
# | <stdin>:12:2: note: 'next' match was here
# |  callq bar@PLT
# |  ^
# | <stdin>:10:15: note: previous match ended here
# |  callq foo@PLT
# |               ^
# | <stdin>:11:1: note: non-matching line after previous match is here
# |  callq __truncsfbf2@PLT
# | ^
# | /home/gha/actions-runner/_work/llvm-project/llvm-project/llvm/test/CodeGen/X86/bf16-fast-isel.ll:23:15: error: CHECK-NEXT: is not on the line after the previous match
# | ; CHECK-NEXT: callq bar@PLT
# |               ^
# | <stdin>:26:2: note: 'next' match was here
# |  callq bar@PLT
# |  ^
# | <stdin>:24:20: note: previous match ended here
# |  callq foo_fast@PLT
# |                    ^
# | <stdin>:25:1: note: non-matching line after previous match is here
# |  callq __truncsfbf2@PLT
# | ^
# | /home/gha/actions-runner/_work/llvm-project/llvm-project/llvm/test/CodeGen/X86/bf16-fast-isel.ll:39:15: error: CHECK-NEXT: is not on the line after the previous match
# | ; CHECK-NEXT: callq *%rbx
# |               ^
# | <stdin>:42:2: note: 'next' match was here
# |  callq *%rbx
# |  ^
# | <stdin>:40:15: note: previous match ended here
# |  callq foo@PLT
# |               ^
# | <stdin>:41:1: note: non-matching line after previous match is here
# |  callq __truncsfbf2@PLT
# | ^
# | /home/gha/actions-runner/_work/llvm-project/llvm-project/llvm/test/CodeGen/X86/bf16-fast-isel.ll:55:15: error: CHECK-NEXT: is not on the line after the previous match
# | ; CHECK-NEXT: callq *%rbx
# |               ^
# | <stdin>:58:2: note: 'next' match was here
# |  callq *%rbx
# |  ^
# | <stdin>:56:15: note: previous match ended here
# |  callq foo@PLT
# |               ^
# | <stdin>:57:1: note: non-matching line after previous match is here
# |  callq __truncsfbf2@PLT
# | ^
# | 
# | Input file: <stdin>
# | Check file: /home/gha/actions-runner/_work/llvm-project/llvm-project/llvm/test/CodeGen/X86/bf16-fast-isel.ll
# | 
# | -dump-input=help explains the following input dump.
# | 
# | Input was:
# | <<<<<<
# |          .
# |          .
# |          .
# |          7: test_direct_call: # @test_direct_call 
# |          8: # %bb.0: # %entry 
# |          9:  pushq %rax 
# |         10:  callq foo@PLT 
# |         11:  callq __truncsfbf2@PLT 
# |         12:  callq bar@PLT 
# | next:9       !~~~~~~~~~~~~  error: match on wrong line
# |         13:  popq %rcx 
# |         14:  retq 
# |         15: .Lfunc_end0: 
# |         16:  .size test_direct_call, .Lfunc_end0-test_direct_call 
# |         17:  # -- End function 
# |         18:  .globl test_fast_direct_call # -- Begin function test_fast_direct_call 
# |         19:  .p2align 4 
# |         20:  .type test_fast_direct_call,@function 
# |         21: test_fast_direct_call: # @test_fast_direct_call 
# |         22: # %bb.0: # %entry 
# |         23:  pushq %rax 
# |         24:  callq foo_fast@PLT 
# |         25:  callq __truncsfbf2@PLT 
# |         26:  callq bar@PLT 
# | next:23      !~~~~~~~~~~~~  error: match on wrong line
# |         27:  popq %rcx 
# |         28:  retq 
# |         29: .Lfunc_end1: 
# |         30:  .size test_fast_direct_call, .Lfunc_end1-test_fast_direct_call 
# |         31:  # -- End function 
# |          .
# |          .
# |          .
# |         37:  pushq %rbx 
# |         38:  movq %rdi, %rbx 
# |         39:  movq %rsi, %rdi 
# |         40:  callq foo@PLT 
# |         41:  callq __truncsfbf2@PLT 
# |         42:  callq *%rbx 
# | next:39      !~~~~~~~~~~  error: match on wrong line
# |         43:  popq %rbx 
# |         44:  retq 
# |         45: .Lfunc_end2: 
# |         46:  .size test_indirect_all, .Lfunc_end2-test_indirect_all 
# |         47:  # -- End function 
# |          .
# |          .
# |          .
# |         53:  pushq %rbx 
# |         54:  movq %rdi, %rbx 
# |         55:  movq %rsi, %rdi 
# |         56:  callq foo@PLT 
# |         57:  callq __truncsfbf2@PLT 
# |         58:  callq *%rbx 
# | next:55      !~~~~~~~~~~  error: match on wrong line
# |         59:  popq %rbx 
# |         60:  retq 
# |         61: .Lfunc_end3: 
# |         62:  .size test_fast_indirect_all, .Lfunc_end3-test_fast_indirect_all 
# |         63:  # -- End function 
# |         64:  .section ".note.GNU-stack","",@progbits 
# | >>>>>>
# `-----------------------------
# error: command failed with exit status: 1

--

If these failures are unrelated to your changes (for example tests are broken or flaky at HEAD), please open an issue at https://github.com/llvm/llvm-project/issues and add the infrastructure label.

@github-actions
Copy link
Copy Markdown

github-actions bot commented Feb 3, 2026

🪟 Windows x64 Test Results

  • 130401 tests passed
  • 2904 tests skipped
  • 1 test failed

Failed Tests

(click on a test name to see its output)

LLVM

LLVM.CodeGen/X86/bf16-fast-isel.ll
Exit Code: 1

Command Output (stdout):
--
# RUN: at line 2
c:\_work\llvm-project\llvm-project\build\bin\llc.exe --fast-isel < C:\_work\llvm-project\llvm-project\llvm\test\CodeGen\X86\bf16-fast-isel.ll -mtriple=x86_64-unknown-unknown | c:\_work\llvm-project\llvm-project\build\bin\filecheck.exe C:\_work\llvm-project\llvm-project\llvm\test\CodeGen\X86\bf16-fast-isel.ll
# executed command: 'c:\_work\llvm-project\llvm-project\build\bin\llc.exe' --fast-isel -mtriple=x86_64-unknown-unknown
# note: command had no output on stdout or stderr
# executed command: 'c:\_work\llvm-project\llvm-project\build\bin\filecheck.exe' 'C:\_work\llvm-project\llvm-project\llvm\test\CodeGen\X86\bf16-fast-isel.ll'
# .---command stderr------------
# | C:\_work\llvm-project\llvm-project\llvm\test\CodeGen\X86\bf16-fast-isel.ll:9:15: error: CHECK-NEXT: is not on the line after the previous match
# | ; CHECK-NEXT: callq bar@PLT
# |               ^
# | <stdin>:12:2: note: 'next' match was here
# |  callq bar@PLT
# |  ^
# | <stdin>:10:15: note: previous match ended here
# |  callq foo@PLT
# |               ^
# | <stdin>:11:1: note: non-matching line after previous match is here
# |  callq __truncsfbf2@PLT
# | ^
# | C:\_work\llvm-project\llvm-project\llvm\test\CodeGen\X86\bf16-fast-isel.ll:23:15: error: CHECK-NEXT: is not on the line after the previous match
# | ; CHECK-NEXT: callq bar@PLT
# |               ^
# | <stdin>:26:2: note: 'next' match was here
# |  callq bar@PLT
# |  ^
# | <stdin>:24:20: note: previous match ended here
# |  callq foo_fast@PLT
# |                    ^
# | <stdin>:25:1: note: non-matching line after previous match is here
# |  callq __truncsfbf2@PLT
# | ^
# | C:\_work\llvm-project\llvm-project\llvm\test\CodeGen\X86\bf16-fast-isel.ll:39:15: error: CHECK-NEXT: is not on the line after the previous match
# | ; CHECK-NEXT: callq *%rbx
# |               ^
# | <stdin>:42:2: note: 'next' match was here
# |  callq *%rbx
# |  ^
# | <stdin>:40:15: note: previous match ended here
# |  callq foo@PLT
# |               ^
# | <stdin>:41:1: note: non-matching line after previous match is here
# |  callq __truncsfbf2@PLT
# | ^
# | C:\_work\llvm-project\llvm-project\llvm\test\CodeGen\X86\bf16-fast-isel.ll:55:15: error: CHECK-NEXT: is not on the line after the previous match
# | ; CHECK-NEXT: callq *%rbx
# |               ^
# | <stdin>:58:2: note: 'next' match was here
# |  callq *%rbx
# |  ^
# | <stdin>:56:15: note: previous match ended here
# |  callq foo@PLT
# |               ^
# | <stdin>:57:1: note: non-matching line after previous match is here
# |  callq __truncsfbf2@PLT
# | ^
# | 
# | Input file: <stdin>
# | Check file: C:\_work\llvm-project\llvm-project\llvm\test\CodeGen\X86\bf16-fast-isel.ll
# | 
# | -dump-input=help explains the following input dump.
# | 
# | Input was:
# | <<<<<<
# |          .
# |          .
# |          .
# |          7: test_direct_call: # @test_direct_call 
# |          8: # %bb.0: # %entry 
# |          9:  pushq %rax 
# |         10:  callq foo@PLT 
# |         11:  callq __truncsfbf2@PLT 
# |         12:  callq bar@PLT 
# | next:9       !~~~~~~~~~~~~  error: match on wrong line
# |         13:  popq %rcx 
# |         14:  retq 
# |         15: .Lfunc_end0: 
# |         16:  .size test_direct_call, .Lfunc_end0-test_direct_call 
# |         17:  # -- End function 
# |         18:  .globl test_fast_direct_call # -- Begin function test_fast_direct_call 
# |         19:  .p2align 4 
# |         20:  .type test_fast_direct_call,@function 
# |         21: test_fast_direct_call: # @test_fast_direct_call 
# |         22: # %bb.0: # %entry 
# |         23:  pushq %rax 
# |         24:  callq foo_fast@PLT 
# |         25:  callq __truncsfbf2@PLT 
# |         26:  callq bar@PLT 
# | next:23      !~~~~~~~~~~~~  error: match on wrong line
# |         27:  popq %rcx 
# |         28:  retq 
# |         29: .Lfunc_end1: 
# |         30:  .size test_fast_direct_call, .Lfunc_end1-test_fast_direct_call 
# |         31:  # -- End function 
# |          .
# |          .
# |          .
# |         37:  pushq %rbx 
# |         38:  movq %rdi, %rbx 
# |         39:  movq %rsi, %rdi 
# |         40:  callq foo@PLT 
# |         41:  callq __truncsfbf2@PLT 
# |         42:  callq *%rbx 
# | next:39      !~~~~~~~~~~  error: match on wrong line
# |         43:  popq %rbx 
# |         44:  retq 
# |         45: .Lfunc_end2: 
# |         46:  .size test_indirect_all, .Lfunc_end2-test_indirect_all 
# |         47:  # -- End function 
# |          .
# |          .
# |          .
# |         53:  pushq %rbx 
# |         54:  movq %rdi, %rbx 
# |         55:  movq %rsi, %rdi 
# |         56:  callq foo@PLT 
# |         57:  callq __truncsfbf2@PLT 
# |         58:  callq *%rbx 
# | next:55      !~~~~~~~~~~  error: match on wrong line
# |         59:  popq %rbx 
# |         60:  retq 
# |         61: .Lfunc_end3: 
# |         62:  .size test_fast_indirect_all, .Lfunc_end3-test_fast_indirect_all 
# |         63:  # -- End function 
# |         64:  .section ".note.GNU-stack","",@progbits 
# | >>>>>>
# `-----------------------------
# error: command failed with exit status: 1

--

If these failures are unrelated to your changes (for example tests are broken or flaky at HEAD), please open an issue at https://github.com/llvm/llvm-project/issues and add the infrastructure label.

@phoebewang
Copy link
Copy Markdown
Contributor

Then we will make problems like #134222 and #151692 again. Is there a way we can fix both?

maybe I need spent some time to understand fast Isel parts.

That would be great. I'd say #134222 is more important, because bfloat is a legal ABI type that used by front end, while <4 x i1> is not.

@alexrp
Copy link
Copy Markdown
Member

alexrp commented Feb 5, 2026

Then we will make problems like #134222 and #151692 again. Is there a way we can fix both?

maybe I need spent some time to understand fast Isel parts.

That would be great. I'd say #134222 is more important, because bfloat is a legal ABI type that used by front end, while <4 x i1> is not.

I'm not too worried about this situation -- I'm sure #179100 will be resolved one way or another in time for the 21.1.0 tag -- but just as a point of order, I think it's worth noting that per the developer policy, it is actually the responsibility of a committer to resolve any regressions caused by a commit - ideally with a follow-up fix, but failing that, a revert. Barring exceptional circumstances (probably requiring an RFC), we can't get into a situation where we justify breaking existing valid code to fix some other code; that approach will quickly break down in a project the scale of LLVM.

@LuoYuanke
Copy link
Copy Markdown
Contributor

I got a rough patch #180322 to fix this issue. I need more time to know the fastISel behavior.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

llvm:SelectionDAG SelectionDAGISel as well

Projects

None yet

Development

Successfully merging this pull request may close these issues.

[X86] LLVM ERROR: Cannot emit physreg copy instruction

6 participants