Skip to content

Complex layout phase 2 - #159981

Draft
folkertdev wants to merge 31 commits into
rust-lang:mainfrom
folkertdev:complex-layout-phase-2
Draft

Complex layout phase 2#159981
folkertdev wants to merge 31 commits into
rust-lang:mainfrom
folkertdev:complex-layout-phase-2

Conversation

@folkertdev

Copy link
Copy Markdown
Contributor

tracking issue: #154023

Follow-up to #158885

@folkertdev folkertdev added the F-complex_numbers `#![feature(complex_numbers)]` label Jul 26, 2026
@rustbot rustbot added A-attributes Area: Attributes (`#[…]`, `#![…]`) A-run-make Area: port run-make Makefiles to rmake.rs A-test-infra-minicore Area: `minicore` test auxiliary and `//@ add-core-stubs` S-waiting-on-author Status: This is awaiting some action (such as code changes or more information) from the author. T-compiler Relevant to the compiler team, which will review and decide on the PR/issue. T-libs Relevant to the library team, which will review and decide on the PR/issue. labels Jul 26, 2026

@programmerjake programmerjake Jul 26, 2026

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

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

I think you'll also want tests for functions like safe fn complex_float_align2(_: c_float, value: Complex<c_float>) -> Complex<c_float>

also tests for properly handling complex arguments that could be split between registers and the stack (so the previous args take all but 1 fp or int reg), since different ABIs say to do different things (e.g. keep them together on the stack or split between registers and the stack)

View changes since the review

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've added a bunch more tests for that sort of scenario, and integrated my LLVM PRs (for mips, powerpc and sparc) so they now all match.

We should also run abi-cafe (and add complex support) to be fully sure, but for that we'd need to merge this first really.

@rust-log-analyzer

This comment has been minimized.

@folkertdev
folkertdev force-pushed the complex-layout-phase-2 branch from 3026f1f to 7fb70da Compare July 29, 2026 22:45
@rustbot rustbot added the A-LLVM Area: Code generation parts specific to LLVM. Both correctness bugs and optimization-related issues. label Jul 29, 2026
@rust-log-analyzer

This comment has been minimized.

// register alignment of 8 bytes.
//
// NOTE: clang uses a vector (e.g. <2 x f32>) here, but if we try that we run into
// ABI issues because vectors require the altivec target feature.

@programmerjake programmerjake Jul 29, 2026

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

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

idk how you're getting that, from my testing clang 22 passes complex f32 via an indirect pointer and doesn't use any vector types:
https://clang.godbolt.org/z/676ajoT6a

assuming clang is correct, we should try to generate the same LLVM IR function signature, since that makes cross-language LTO work much better.

View changes since the review

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.

assuming clang is correct

It is not.

Being compatible with the standard C compiler on the platform (that determines the ABI of libcalls etc) seems more important than LTO for _Complex. Anyhow, I'm trying to fix the discrepancy in that bottom PR.

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.

This matters e.g. for

// main.c
#include <stdio.h>
#include <complex.h>

int main(void) {
    volatile float re = -1.0f, im = 0.0f;
    _Complex float s = csqrtf(re + im * I);
    printf("%f + %fi\n", crealf(s), cimagf(s));
    return 0;
}

with

powerpc-linux-gnu-gcc -O2 main.c -o gcc.out -lm

# Use clang to compile, GCC as the linker.
clang --target=powerpc-linux-gnu -O2 -c main.c -o clang.o
powerpc-linux-gnu-gcc clang.o -o clang.out -lm

echo "gcc"
qemu-ppc -L /usr/powerpc-linux-gnu ./gcc.out
echo "clang"
qemu-ppc -L /usr/powerpc-linux-gnu ./clang.out

returns

gcc
0.000000 + 1.000000i
clang
4.186081 + 0.000000i

The clang result is nonsense.

@folkertdev
folkertdev force-pushed the complex-layout-phase-2 branch from 7fb70da to bc2336f Compare July 30, 2026 22:54
@rust-log-analyzer

Copy link
Copy Markdown
Collaborator

The job aarch64-gnu-llvm-21-1 failed! Check out the build log: (web) (plain enhanced) (plain)

Click to see the possible cause of the failure (guessed by this bot)

---- [codegen] tests/codegen-llvm/complex-abi.rs#POWERPC stdout ----
------FileCheck stdout------------------------------

------FileCheck stderr------------------------------
/checkout/tests/codegen-llvm/complex-abi.rs:160:14: error: POWERPC: expected string not found in input
 // POWERPC: define{{.*}} [2 x i32] @cplx_f32([2 x i32] {{.*}})
             ^
/checkout/obj/build/aarch64-unknown-linux-gnu/test/codegen-llvm/complex-abi.POWERPC/complex-abi.ll:1:1: note: scanning from here
; ModuleID = 'complex_abi.8dfb70534ff3b38e-cgu.0'
^
/checkout/obj/build/aarch64-unknown-linux-gnu/test/codegen-llvm/complex-abi.POWERPC/complex-abi.ll:67:1: note: possible intended match here
define [8 x i32] @cplx_f128([8 x i32] %0) unnamed_addr #0 {
^

Input file: /checkout/obj/build/aarch64-unknown-linux-gnu/test/codegen-llvm/complex-abi.POWERPC/complex-abi.ll
Check file: /checkout/tests/codegen-llvm/complex-abi.rs

-dump-input=help explains the following input dump.

Input was:
<<<<<<
             1: ; ModuleID = 'complex_abi.8dfb70534ff3b38e-cgu.0' 
check:160'0     X~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ error: no match found
             2: source_filename = "complex_abi.8dfb70534ff3b38e-cgu.0" 
check:160'0     ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
             3: target datalayout = "E-m:e-p:32:32-Fn32-i64:64-n32" 
check:160'0     ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
             4: target triple = "powerpc-unknown-linux-gnu" 
check:160'0     ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
             5:  
check:160'0     ~
             6: ; Function Attrs: nounwind uwtable 
check:160'0     ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
             7: define i32 @cplx_f16(i32 %0) unnamed_addr #0 { 
check:160'0     ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
             8: start: 
check:160'0     ~~~~~~~
             9:  %_0 = alloca [4 x i8], align 2 
check:160'0     ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
            10:  %1 = alloca [4 x i8], align 4 
check:160'0     ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
            11:  %x = alloca [4 x i8], align 2 
check:160'0     ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
            12:  call void @llvm.lifetime.start.p0(i64 4, ptr %1) 
check:160'0     ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
            13:  store i32 %0, ptr %1, align 4 
check:160'0     ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
            14:  call void @llvm.memcpy.p0.p0.i32(ptr align 2 %x, ptr align 4 %1, i32 4, i1 false) 
check:160'0     ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
            15:  call void @llvm.lifetime.end.p0(i64 4, ptr %1) 
check:160'0     ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
            16:  %2 = load half, ptr %x, align 2, !noundef !3 
check:160'0     ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
            17:  %3 = getelementptr inbounds i8, ptr %x, i32 2 
check:160'0     ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
            18:  %4 = load half, ptr %3, align 2, !noundef !3 
check:160'0     ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
            19:  store half %2, ptr %_0, align 2 
check:160'0     ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
            20:  %5 = getelementptr inbounds i8, ptr %_0, i32 2 
check:160'0     ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
            21:  store half %4, ptr %5, align 2 
check:160'0     ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
            22:  %6 = load i32, ptr %_0, align 2 
check:160'0     ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
            23:  ret i32 %6 
check:160'0     ~~~~~~~~~~~~
            24: } 
check:160'0     ~~
            25:  
check:160'0     ~
            26: ; Function Attrs: nounwind uwtable 
check:160'0     ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
            27: define i64 @cplx_f32(i64 %0) unnamed_addr #0 { 
check:160'0     ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
            28: start: 
check:160'0     ~~~~~~~
            29:  %_0 = alloca [8 x i8], align 4 
check:160'0     ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
            30:  %1 = alloca [8 x i8], align 8 
check:160'0     ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
            31:  %x = alloca [8 x i8], align 4 
check:160'0     ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
            32:  call void @llvm.lifetime.start.p0(i64 8, ptr %1) 
check:160'0     ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
            33:  store i64 %0, ptr %1, align 8 
check:160'0     ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
            34:  call void @llvm.memcpy.p0.p0.i32(ptr align 4 %x, ptr align 8 %1, i32 8, i1 false) 
check:160'0     ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
            35:  call void @llvm.lifetime.end.p0(i64 8, ptr %1) 
check:160'0     ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
            36:  %2 = load float, ptr %x, align 4, !noundef !3 
check:160'0     ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
            37:  %3 = getelementptr inbounds i8, ptr %x, i32 4 
check:160'0     ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
            38:  %4 = load float, ptr %3, align 4, !noundef !3 
check:160'0     ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
            39:  store float %2, ptr %_0, align 4 
check:160'0     ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
            40:  %5 = getelementptr inbounds i8, ptr %_0, i32 4 
check:160'0     ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
            41:  store float %4, ptr %5, align 4 
check:160'0     ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
            42:  %6 = load i64, ptr %_0, align 4 
check:160'0     ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
            43:  ret i64 %6 
check:160'0     ~~~~~~~~~~~~
            44: } 
check:160'0     ~~
            45:  
check:160'0     ~
            46: ; Function Attrs: nounwind uwtable 
check:160'0     ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
            47: define [4 x i32] @cplx_f64([4 x i32] %0) unnamed_addr #0 { 
check:160'0     ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
            48: start: 
check:160'0     ~~~~~~~
            49:  %_0 = alloca [16 x i8], align 8 
check:160'0     ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
            50:  %1 = alloca [16 x i8], align 4 
check:160'0     ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
            51:  %x = alloca [16 x i8], align 8 
check:160'0     ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
            52:  call void @llvm.lifetime.start.p0(i64 16, ptr %1) 
check:160'0     ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
            53:  store [4 x i32] %0, ptr %1, align 4 
check:160'0     ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
            54:  call void @llvm.memcpy.p0.p0.i32(ptr align 8 %x, ptr align 4 %1, i32 16, i1 false) 
check:160'0     ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
            55:  call void @llvm.lifetime.end.p0(i64 16, ptr %1) 
check:160'0     ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
            56:  %2 = load double, ptr %x, align 8, !noundef !3 
check:160'0     ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
            57:  %3 = getelementptr inbounds i8, ptr %x, i32 8 
check:160'0     ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
            58:  %4 = load double, ptr %3, align 8, !noundef !3 
check:160'0     ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
            59:  store double %2, ptr %_0, align 8 
check:160'0     ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
            60:  %5 = getelementptr inbounds i8, ptr %_0, i32 8 
check:160'0     ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
            61:  store double %4, ptr %5, align 8 
check:160'0     ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
            62:  %6 = load [4 x i32], ptr %_0, align 8 
check:160'0     ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
            63:  ret [4 x i32] %6 
check:160'0     ~~~~~~~~~~~~~~~~~~
            64: } 
check:160'0     ~~
            65:  
check:160'0     ~
            66: ; Function Attrs: nounwind uwtable 
check:160'0     ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
            67: define [8 x i32] @cplx_f128([8 x i32] %0) unnamed_addr #0 { 
check:160'0     ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
check:160'1     ?                                                            possible intended match
            68: start: 
check:160'0     ~~~~~~~
            69:  %_0 = alloca [32 x i8], align 16 
check:160'0     ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
            70:  %1 = alloca [32 x i8], align 4 
check:160'0     ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
            71:  %x = alloca [32 x i8], align 16 
check:160'0     ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
            72:  call void @llvm.lifetime.start.p0(i64 32, ptr %1) 
check:160'0     ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
            73:  store [8 x i32] %0, ptr %1, align 4 
check:160'0     ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
            74:  call void @llvm.memcpy.p0.p0.i32(ptr align 16 %x, ptr align 4 %1, i32 32, i1 false) 
check:160'0     ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
            75:  call void @llvm.lifetime.end.p0(i64 32, ptr %1) 
check:160'0     ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
            76:  %2 = load fp128, ptr %x, align 16, !noundef !3 
check:160'0     ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
            77:  %3 = getelementptr inbounds i8, ptr %x, i32 16 
check:160'0     ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
            78:  %4 = load fp128, ptr %3, align 16, !noundef !3 
check:160'0     ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
            79:  store fp128 %2, ptr %_0, align 16 
check:160'0     ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
            80:  %5 = getelementptr inbounds i8, ptr %_0, i32 16 
check:160'0     ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
            81:  store fp128 %4, ptr %5, align 16 
check:160'0     ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
            82:  %6 = load [8 x i32], ptr %_0, align 16 
check:160'0     ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
            83:  ret [8 x i32] %6 
check:160'0     ~~~~~~~~~~~~~~~~~~
            84: } 
check:160'0     ~~
            85:  
check:160'0     ~
            86: ; Function Attrs: nounwind uwtable 
check:160'0     ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
            87: define i16 @cplx_i8(i16 %0) unnamed_addr #0 { 
check:160'0     ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
            88: start: 
check:160'0     ~~~~~~~
            89:  %_0 = alloca [2 x i8], align 1 
check:160'0     ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
            90:  %1 = alloca [2 x i8], align 2 
check:160'0     ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
            91:  %x = alloca [2 x i8], align 1 
check:160'0     ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
            92:  call void @llvm.lifetime.start.p0(i64 2, ptr %1) 
check:160'0     ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
            93:  store i16 %0, ptr %1, align 2 
check:160'0     ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
            94:  call void @llvm.memcpy.p0.p0.i32(ptr align 1 %x, ptr align 2 %1, i32 2, i1 false) 
check:160'0     ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
            95:  call void @llvm.lifetime.end.p0(i64 2, ptr %1) 
check:160'0     ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
            96:  %2 = load i8, ptr %x, align 1, !noundef !3 
check:160'0     ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
            97:  %3 = getelementptr inbounds i8, ptr %x, i32 1 
check:160'0     ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
            98:  %4 = load i8, ptr %3, align 1, !noundef !3 
check:160'0     ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
            99:  store i8 %2, ptr %_0, align 1 
check:160'0     ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
           100:  %5 = getelementptr inbounds i8, ptr %_0, i32 1 
check:160'0     ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
           101:  store i8 %4, ptr %5, align 1 
check:160'0     ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
           102:  %6 = load i16, ptr %_0, align 1 
check:160'0     ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
           103:  ret i16 %6 
check:160'0     ~~~~~~~~~~~~
           104: } 
check:160'0     ~~
           105:  
check:160'0     ~
           106: ; Function Attrs: nounwind uwtable 
check:160'0     ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
           107: define i32 @cplx_i16(i32 %0) unnamed_addr #0 { 
check:160'0     ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
           108: start: 
check:160'0     ~~~~~~~
           109:  %_0 = alloca [4 x i8], align 2 
check:160'0     ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
           110:  %1 = alloca [4 x i8], align 4 
check:160'0     ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
           111:  %x = alloca [4 x i8], align 2 
check:160'0     ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
           112:  call void @llvm.lifetime.start.p0(i64 4, ptr %1) 
check:160'0     ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
           113:  store i32 %0, ptr %1, align 4 
check:160'0     ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
           114:  call void @llvm.memcpy.p0.p0.i32(ptr align 2 %x, ptr align 4 %1, i32 4, i1 false) 
check:160'0     ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
           115:  call void @llvm.lifetime.end.p0(i64 4, ptr %1) 
check:160'0     ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
           116:  %2 = load i16, ptr %x, align 2, !noundef !3 
check:160'0     ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
           117:  %3 = getelementptr inbounds i8, ptr %x, i32 2 
check:160'0     ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
           118:  %4 = load i16, ptr %3, align 2, !noundef !3 
check:160'0     ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
           119:  store i16 %2, ptr %_0, align 2 
check:160'0     ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
           120:  %5 = getelementptr inbounds i8, ptr %_0, i32 2 
check:160'0     ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
           121:  store i16 %4, ptr %5, align 2 
check:160'0     ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
           122:  %6 = load i32, ptr %_0, align 2 
check:160'0     ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
           123:  ret i32 %6 
check:160'0     ~~~~~~~~~~~~
           124: } 
check:160'0     ~~
           125:  
check:160'0     ~
           126: ; Function Attrs: nounwind uwtable 
check:160'0     ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
           127: define i64 @cplx_i32(i64 %0) unnamed_addr #0 { 
check:160'0     ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
           128: start: 
check:160'0     ~~~~~~~
           129:  %_0 = alloca [8 x i8], align 4 
check:160'0     ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
           130:  %1 = alloca [8 x i8], align 8 
check:160'0     ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
           131:  %x = alloca [8 x i8], align 4 
check:160'0     ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
           132:  call void @llvm.lifetime.start.p0(i64 8, ptr %1) 
check:160'0     ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
           133:  store i64 %0, ptr %1, align 8 
check:160'0     ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
           134:  call void @llvm.memcpy.p0.p0.i32(ptr align 4 %x, ptr align 8 %1, i32 8, i1 false) 
check:160'0     ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
           135:  call void @llvm.lifetime.end.p0(i64 8, ptr %1) 
check:160'0     ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
           136:  %2 = load i32, ptr %x, align 4, !noundef !3 
check:160'0     ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
           137:  %3 = getelementptr inbounds i8, ptr %x, i32 4 
check:160'0     ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
           138:  %4 = load i32, ptr %3, align 4, !noundef !3 
check:160'0     ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
           139:  store i32 %2, ptr %_0, align 4 
check:160'0     ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
           140:  %5 = getelementptr inbounds i8, ptr %_0, i32 4 
check:160'0     ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
           141:  store i32 %4, ptr %5, align 4 
check:160'0     ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
           142:  %6 = load i64, ptr %_0, align 4 
check:160'0     ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
           143:  ret i64 %6 
check:160'0     ~~~~~~~~~~~~
           144: } 
check:160'0     ~~
           145:  
check:160'0     ~
           146: ; Function Attrs: nounwind uwtable 
check:160'0     ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
           147: define [4 x i32] @cplx_i64([4 x i32] %0) unnamed_addr #0 { 
check:160'0     ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
           148: start: 
check:160'0     ~~~~~~~
           149:  %_0 = alloca [16 x i8], align 8 
check:160'0     ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
           150:  %1 = alloca [16 x i8], align 4 
check:160'0     ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
           151:  %x = alloca [16 x i8], align 8 
check:160'0     ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
           152:  call void @llvm.lifetime.start.p0(i64 16, ptr %1) 
check:160'0     ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
           153:  store [4 x i32] %0, ptr %1, align 4 
check:160'0     ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
           154:  call void @llvm.memcpy.p0.p0.i32(ptr align 8 %x, ptr align 4 %1, i32 16, i1 false) 
check:160'0     ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
           155:  call void @llvm.lifetime.end.p0(i64 16, ptr %1) 
check:160'0     ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
           156:  %2 = load i64, ptr %x, align 8, !noundef !3 
check:160'0     ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
           157:  %3 = getelementptr inbounds i8, ptr %x, i32 8 
check:160'0     ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
           158:  %4 = load i64, ptr %3, align 8, !noundef !3 
check:160'0     ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
           159:  store i64 %2, ptr %_0, align 8 
check:160'0     ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
           160:  %5 = getelementptr inbounds i8, ptr %_0, i32 8 
check:160'0     ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
           161:  store i64 %4, ptr %5, align 8 
check:160'0     ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
           162:  %6 = load [4 x i32], ptr %_0, align 8 
check:160'0     ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
           163:  ret [4 x i32] %6 
check:160'0     ~~~~~~~~~~~~~~~~~~
           164: } 
check:160'0     ~~
           165:  
check:160'0     ~
           166: ; Function Attrs: nocallback nofree nosync nounwind willreturn memory(argmem: readwrite) 
check:160'0     ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
           167: declare void @llvm.lifetime.start.p0(i64 immarg, ptr captures(none)) #1 
check:160'0     ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
             .
             .
             .
>>>>>>

------------------------------------------

error in revision `POWERPC`: verification with 'FileCheck' failed
status: exit status: 1
command: "/usr/lib/llvm-21/bin/FileCheck" "--input-file" "/checkout/obj/build/aarch64-unknown-linux-gnu/test/codegen-llvm/complex-abi.POWERPC/complex-abi.ll" "/checkout/tests/codegen-llvm/complex-abi.rs" "--check-prefix=CHECK" "--check-prefix" "POWERPC" "--allow-unused-prefixes" "--dump-input-context" "100"
stdout: none
--- stderr -------------------------------
/checkout/tests/codegen-llvm/complex-abi.rs:160:14: error: POWERPC: expected string not found in input
 // POWERPC: define{{.*}} [2 x i32] @cplx_f32([2 x i32] {{.*}})
             ^
/checkout/obj/build/aarch64-unknown-linux-gnu/test/codegen-llvm/complex-abi.POWERPC/complex-abi.ll:1:1: note: scanning from here
; ModuleID = 'complex_abi.8dfb70534ff3b38e-cgu.0'
^
/checkout/obj/build/aarch64-unknown-linux-gnu/test/codegen-llvm/complex-abi.POWERPC/complex-abi.ll:67:1: note: possible intended match here
define [8 x i32] @cplx_f128([8 x i32] %0) unnamed_addr #0 {
^

Input file: /checkout/obj/build/aarch64-unknown-linux-gnu/test/codegen-llvm/complex-abi.POWERPC/complex-abi.ll
Check file: /checkout/tests/codegen-llvm/complex-abi.rs

-dump-input=help explains the following input dump.

Input was:
<<<<<<
             1: ; ModuleID = 'complex_abi.8dfb70534ff3b38e-cgu.0' 
check:160'0     X~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ error: no match found
             2: source_filename = "complex_abi.8dfb70534ff3b38e-cgu.0" 
check:160'0     ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
             3: target datalayout = "E-m:e-p:32:32-Fn32-i64:64-n32" 
check:160'0     ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
             4: target triple = "powerpc-unknown-linux-gnu" 
check:160'0     ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
             5:  
check:160'0     ~
             6: ; Function Attrs: nounwind uwtable 
check:160'0     ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
             7: define i32 @cplx_f16(i32 %0) unnamed_addr #0 { 
check:160'0     ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
             8: start: 
check:160'0     ~~~~~~~
             9:  %_0 = alloca [4 x i8], align 2 
check:160'0     ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
            10:  %1 = alloca [4 x i8], align 4 
check:160'0     ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
            11:  %x = alloca [4 x i8], align 2 
check:160'0     ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
            12:  call void @llvm.lifetime.start.p0(i64 4, ptr %1) 
check:160'0     ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
            13:  store i32 %0, ptr %1, align 4 
check:160'0     ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
            14:  call void @llvm.memcpy.p0.p0.i32(ptr align 2 %x, ptr align 4 %1, i32 4, i1 false) 
check:160'0     ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
            15:  call void @llvm.lifetime.end.p0(i64 4, ptr %1) 
check:160'0     ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
            16:  %2 = load half, ptr %x, align 2, !noundef !3 
check:160'0     ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
            17:  %3 = getelementptr inbounds i8, ptr %x, i32 2 
check:160'0     ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
            18:  %4 = load half, ptr %3, align 2, !noundef !3 
check:160'0     ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
            19:  store half %2, ptr %_0, align 2 
check:160'0     ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
            20:  %5 = getelementptr inbounds i8, ptr %_0, i32 2 
check:160'0     ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
            21:  store half %4, ptr %5, align 2 
check:160'0     ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
            22:  %6 = load i32, ptr %_0, align 2 
check:160'0     ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
            23:  ret i32 %6 
check:160'0     ~~~~~~~~~~~~
            24: } 
check:160'0     ~~
            25:  
check:160'0     ~
            26: ; Function Attrs: nounwind uwtable 
check:160'0     ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
            27: define i64 @cplx_f32(i64 %0) unnamed_addr #0 { 
check:160'0     ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
            28: start: 
check:160'0     ~~~~~~~
            29:  %_0 = alloca [8 x i8], align 4 
check:160'0     ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
            30:  %1 = alloca [8 x i8], align 8 
check:160'0     ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
            31:  %x = alloca [8 x i8], align 4 
check:160'0     ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
            32:  call void @llvm.lifetime.start.p0(i64 8, ptr %1) 
check:160'0     ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
            33:  store i64 %0, ptr %1, align 8 
check:160'0     ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
            34:  call void @llvm.memcpy.p0.p0.i32(ptr align 4 %x, ptr align 8 %1, i32 8, i1 false) 
check:160'0     ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
            35:  call void @llvm.lifetime.end.p0(i64 8, ptr %1) 
check:160'0     ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
            36:  %2 = load float, ptr %x, align 4, !noundef !3 
check:160'0     ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
            37:  %3 = getelementptr inbounds i8, ptr %x, i32 4 
check:160'0     ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
            38:  %4 = load float, ptr %3, align 4, !noundef !3 
check:160'0     ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
            39:  store float %2, ptr %_0, align 4 
check:160'0     ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
            40:  %5 = getelementptr inbounds i8, ptr %_0, i32 4 
check:160'0     ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
            41:  store float %4, ptr %5, align 4 
check:160'0     ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
            42:  %6 = load i64, ptr %_0, align 4 
check:160'0     ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
            43:  ret i64 %6 
check:160'0     ~~~~~~~~~~~~
            44: } 
check:160'0     ~~
            45:  
check:160'0     ~
            46: ; Function Attrs: nounwind uwtable 
check:160'0     ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
            47: define [4 x i32] @cplx_f64([4 x i32] %0) unnamed_addr #0 { 
check:160'0     ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
            48: start: 
check:160'0     ~~~~~~~
            49:  %_0 = alloca [16 x i8], align 8 
check:160'0     ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
            50:  %1 = alloca [16 x i8], align 4 
check:160'0     ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
            51:  %x = alloca [16 x i8], align 8 
check:160'0     ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
            52:  call void @llvm.lifetime.start.p0(i64 16, ptr %1) 
check:160'0     ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
            53:  store [4 x i32] %0, ptr %1, align 4 
check:160'0     ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
            54:  call void @llvm.memcpy.p0.p0.i32(ptr align 8 %x, ptr align 4 %1, i32 16, i1 false) 
check:160'0     ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
            55:  call void @llvm.lifetime.end.p0(i64 16, ptr %1) 
check:160'0     ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
            56:  %2 = load double, ptr %x, align 8, !noundef !3 
check:160'0     ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
            57:  %3 = getelementptr inbounds i8, ptr %x, i32 8 
check:160'0     ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~

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

Labels

A-attributes Area: Attributes (`#[…]`, `#![…]`) A-LLVM Area: Code generation parts specific to LLVM. Both correctness bugs and optimization-related issues. A-run-make Area: port run-make Makefiles to rmake.rs A-test-infra-minicore Area: `minicore` test auxiliary and `//@ add-core-stubs` F-complex_numbers `#![feature(complex_numbers)]` S-waiting-on-author Status: This is awaiting some action (such as code changes or more information) from the author. T-compiler Relevant to the compiler team, which will review and decide on the PR/issue. T-libs Relevant to the library team, which will review and decide on the PR/issue.

Projects

None yet

Development

Successfully merging this pull request may close these issues.

4 participants