<table border="1" cellspacing="0" cellpadding="8">
<tr>
<th>Issue</th>
<td>
<a href=https://github.com/llvm/llvm-project/issues/106319>106319</a>
</td>
</tr>
<tr>
<th>Summary</th>
<td>
llc sometimes emits non-working calling sequence on x86_64-windows-gnu
</td>
</tr>
<tr>
<th>Labels</th>
<td>
new issue
</td>
</tr>
<tr>
<th>Assignees</th>
<td>
</td>
</tr>
<tr>
<th>Reporter</th>
<td>
minoki
</td>
</tr>
</table>
<pre>
When compiling the following IR for `x86_64-w64-window-gnu`, llc emits invalid code depending on the options.
```
; ModuleID = 'hello.c'
; source_filename = "hello.c"
target datalayout = "e-m:w-p270:32:32-p271:32:32-p272:64:64-i64:64-i128:128-f80:128-n8:16:32:64-S128"
target triple = "x86_64-w64-windows-gnu"
@.str = private unnamed_addr constant [13 x i8] c"Hello world!\00", align 1
define i32 @main() {
call void @puts(ptr noundef nonnull @.str)
ret i32 0
}
; declare void @puts(ptr noundef)
@puts = external global [0 x i8], align 1
```
When compiling with `-O2 -code-model=small -relocation-model=static`, LLVM emits bogus code (which crashes when run). Note that calling instruction is not rip-relative:
```
$ build/bin/llc --print-after-isel -O2 -code-model=small -relocation-model=static hello.ll 2>&1 | grep puts
CALL64m $noreg, 1, $noreg, target-flags(x86-coffstub) @puts, $noreg, <regmask $bh $bl $bp $bph $bpl $bx $di $dih $dil $ebp $ebx $edi $esi $hbp $hbx $hdi $hsi $rbp $rbx $rdi $rsi $si $sih $sil $r12 $r13 $r14 $r15 $xmm6 $xmm7 $xmm8 $xmm9 $xmm10 and 25 more...>, implicit $rsp, implicit $ssp, implicit $rcx, implicit-def $rsp, implicit-def $ssp :: (load (s64) from got)
$ grep -n puts hello.s
27: callq *.refptr.puts
38: .section .rdata$.refptr.puts,"dr",discard,.refptr.puts
40: .globl .refptr.puts
41:.refptr.puts:
42: .quad puts
```
When optimization is disabled, LLVM emits a working assembly code:
```
$ build/bin/llc --print-after-isel -O0 -code-model=small -relocation-model=static hello.ll 2>&1 | grep puts
CALL64m $rip, 1, $noreg, target-flags(x86-coffstub) @puts, $noreg, <regmask $bh $bl $bp $bph $bpl $bx $di $dih $dil $ebp $ebx $edi $esi $hbp $hbx $hdi $hsi $rbp $rbx $rdi $rsi $si $sih $sil $r12 $r13 $r14 $r15 $xmm6 $xmm7 $xmm8 $xmm9 $xmm10 and 25 more...>, implicit $rsp, implicit $ssp, implicit $rcx
$ grep -n puts hello.s
27: callq *.refptr.puts(%rip)
38: .section .rdata$.refptr.puts,"dr",discard,.refptr.puts
40: .globl .refptr.puts
41:.refptr.puts:
42: .quad puts
```
When `-code-model=large` is set, LLVM emits a working assembly code:
```
$ build/bin/llc --print-after-isel -O2 -code-model=large -relocation-model=static hello.ll 2>&1 | grep puts
%2:gr64 = MOV64ri @puts
$ grep -n puts hello.s
28: movabsq $puts, %rax
```
When `-relocation-model=pic` is set, LLVM emits a working assembly code:
```
t$ build/bin/llc --print-after-isel -O2 -code-model=small -relocation-model=pic hello.ll 2>&1 | grep puts
CALL64m $rip, 1, $noreg, target-flags(x86-coffstub) @puts, $noreg, <regmask $bh $bl $bp $bph $bpl $bx $di $dih $dil $ebp $ebx $edi $esi $hbp $hbx $hdi $hsi $rbp $rbx $rdi $rsi $si $sih $sil $r12 $r13 $r14 $r15 $xmm6 $xmm7 $xmm8 $xmm9 $xmm10 and 25 more...>, implicit $rsp, implicit $ssp, implicit $rcx, implicit-def $rsp, implicit-def $ssp :: (load (s64) from got)
$ grep -n puts hello.s
27: callq *.refptr.puts(%rip)
38: .section .rdata$.refptr.puts,"dr",discard,.refptr.puts
40: .globl .refptr.puts
41:.refptr.puts:
42: .quad puts
```
When `declare` is used instead of `external global`, LLVM emits a working assembly code:
```
$ build/bin/llc --print-after-isel -O2 -code-model=small -relocation-model=static hello.ll 2>&1 | grep puts
CALL64pcrel32 @puts, <regmask $bh $bl $bp $bph $bpl $bx $di $dih $dil $ebp $ebx $edi $esi $hbp $hbx $hdi $hsi $rbp $rbx $rdi $rsi $si $sih $sil $r12 $r13 $r14 $r15 $xmm6 $xmm7 $xmm8 $xmm9 $xmm10 and 25 more...>, implicit $rsp, implicit $ssp, implicit $rcx, implicit-def $rsp, implicit-def $ssp
$ grep -n puts hello.s
27: callq puts
```
When `x86_64-*-windows-msvc` triple is used, LLVM emits a working assembly code:
```
$ build/bin/llc --print-after-isel -O2 -code-model=small -relocation-model=static hello.ll 2>&1 | grep puts
CALL64pcrel32 @puts, <regmask $bh $bl $bp $bph $bpl $bx $di $dih $dil $ebp $ebx $edi $esi $hbp $hbx $hdi $hsi $rbp $rbx $rdi $rsi $si $sih $sil $r12 $r13 $r14 $r15 $xmm6 $xmm7 $xmm8 $xmm9 $xmm10 and 25 more...>, implicit $rsp, implicit $ssp, implicit $rcx, implicit-def $rsp, implicit-def $ssp
$ grep -n puts hello.s
22: callq puts
```
I noticed the first argument to CALL64m was `$noreg` when the bogus code was emitted, but could not track the problem further because my knowledge on LLVM was limited.
As a note, I encountered this issue while trying to use `x86_64-*-windows-gnu` triple in GHC: https://gitlab.haskell.org/ghc/ghc/-/issues/22487 Suggestions are welcome as to what GHC should do.
</pre>
<img width="1px" height="1px" alt="" src="http://email.email.llvm.org/o/eJzsWV9v4zYS_zT0y0CGRMmy_eAHx7lcF9i9Aleg97igxLHEC0VqSSpO7tMfhpSdf22xLdLFYpEgmZHI4b_h7zekJsJ71RnEHVtdsdX1Qkyht243KGNv1aKx8mH3nx4NtHYYlVamg9AjHK3W9kRvH_4NR-uA1fn9pv5cV9mJ_pSR9pR1ZmJ1zvgBtG4BBxU8KHMntJLQWokgcUQjqRtrYr92DMoav2T5Ncv3s6zz-Te9llfwycpJ44drYOU1ML7uUWu7bBlfP9p4O7kWPx-VRiMGnE35xZQn0yBchwGkCEKLBzuFsyFmAyv3p2zk65yV-5JHQa_F81d6qqsoMnV5KPiGlfuCb7LjJp-fTCyqz83rKvuFzF5MJTg16st8X3nVR7ee28yyypc-uNhmdOpOBITJ0LLlZyGlg9YaH4QJwFZXRQn3oDZsdQ3khp_IIXCyTkvGC7Y65Dn1zg8gtOoMFE8HknhUBkGVHFiVD0IZRgvYAltfJQuAVmgNd1ZJMhmn4BnfjMGBsZOReARjjZm0hnnSjG_PLR2G2PV5p9fXzxZZXoHEVguHf9D9pbuLZ8gmegbvAzojNHTaNkKTL_KzK16v9wXqonzBhJMKPSE_-5lDRoDOBitRs_LaD-SEzKG2rSBIP9YEEVQ70-Ljx18_zbxobDf5xArGN6detT20TvgePZxoWDcZxrdL-JcNCKEXITqapqGMD25qaRhQHowN4NRIg4ug7pCV-z-iE6-gmRRt_k1D23lDXM2y0SkTMnEM6DLlUcOfXyQkrmkNnJX_YLwugK0P0DkcIW5c2vbD_uPHuhqA8cpYhx05piDxtCBxIztq0dGG32_qrLXHow9TE-F3hsLzVqw8OOwG4W-puOmj1FGOSaaiMZXdk5QqyT6pWIPJHJMFJhP0UfWprk91farrU51LdS7VuVTnUt1Z9knFcVzBkyqTqpJakbofhnrW61lvZr2ddZGDMBL4CgbrcLlcRrcfQA2jVq0KafTxZZF_XeTa-6dFGfH2deNzsfcjEMrKPWFXWyFJ-7qirTk6O0BnwyMxeZUwkJkIgxkmMxz4mrqhH4L3FwBgfL90eByDWz6iptyczZYeE_SXjoI449Uza35gnEuXQppUvhVOMn543WOVX3qk-KDhN0wo8j8rPlOr4pfGXyYhAZ4A_PcjCZ12g_qfODNXKi8ajfJFaBAUnW-J6cJ7HBr9EOPEm_E6_3t4_ZTYTo3vtP4-aP0mHKRDfxU3dfsD8ZGO8mdM0ARPVudETo_hG_Py5XkbZ_MGvGR8Re7pXF3Fe9Gnn3-tK6cubPsahFy2e7B3ovFfCF2PVF05cf81zv6NpYzxcvSGDg9_yw1n_CvXm_co-N1Ewe_1cvPDBtb5y23m9uRRxu8WFBLskQxefJ29_kL61uH2ba9BY-tQp8_mC5nfCfyNCPzXuPmVyJ4zNIzvLxmawd_FU2xO5cyAf8fzO56_IZ75n8TzBzA2qBZlyvAq5wMI100DmgDBXi4yJ-EhRuf5KlLnKUFFrZ5ksciMgB4S8JspQGsnLWN-KjjR3sYWo7ONxgGOkws9OmiwFZNHGB7g1tiTRtkhWJOIQ31qNaiA8lmKeE9sMjYgjfQB0LR2MgFdXIvyoLyfEE690gjBPcQstiVO_g5_U-L6Ql8D__zpQN7sQxjjWchvGL_pVNCiWfbC36LWS-s6Kuzbi8wYv4lDe8ZvOK82a_hl6jr0MckNwiGcULd2QBCeZnTqRaCxwPfRVdLOy1zIXSm35VYscFesebXJ62JbLvpdU2Mhqm3V1nktRdvUYrPBti7qojmu6zxfqB3PeZVv-CbPq-2qXG6KUsh13jblUR5L0bAqx0EovdT6bqBFLOKUd0Vel8V2oUWD2sf_DnBu8JR8SbeM1fXC7ahR1kydZ1WulQ_-sZuggsYdhSdvBwxqQD9HPmNNdo595ySmxy8Tmjbu9Tnn_bgbi8np3Svv91OzbO0Qg-DdWWWjs__FNjz1_byWux3_fwAAAP__Gldj3g">