[RISCV][VLOPT] Add vector narrowing integer right shift instructions to isSupportedIn...
[llvm-project.git] / flang / test / Fir / struct-return-aarch64.fir
blob8b75c2cac7b6befe695ae477af50ba70e52aa09f
1 // Test AArch64 ABI rewrite of struct returned by value (BIND(C), VALUE derived types).
2 // RUN: fir-opt --target-rewrite="target=aarch64-unknown-linux-gnu" %s | FileCheck %s
4 !composite = !fir.type<t1{i:f32,j:i32,k:f32}>
5 // CHECK-LABEL: func.func private @test_composite() -> !fir.array<2xi64>
6 func.func private @test_composite() -> !composite
7 // CHECK-LABEL: func.func @test_call_composite(
8 // CHECK-SAME:    %[[ARG0:.*]]: !fir.ref<!fir.type<t1{i:f32,j:i32,k:f32}>>)
9 func.func @test_call_composite(%arg0 : !fir.ref<!composite>) {
10   // CHECK: %[[OUT:.*]] = fir.call @test_composite() : () -> !fir.array<2xi64>
11   // CHECK: %[[STACK:.*]] = llvm.intr.stacksave : !llvm.ptr
12   // CHECK: %[[ARR:.*]] = fir.alloca !fir.array<2xi64>
13   // CHECK: fir.store %[[OUT]] to %[[ARR]] : !fir.ref<!fir.array<2xi64>>
14   // CHECK: %[[CVT:.*]] = fir.convert %[[ARR]] : (!fir.ref<!fir.array<2xi64>>) -> !fir.ref<!fir.type<t1{i:f32,j:i32,k:f32}>>
15   // CHECK: %[[LD:.*]] = fir.load %[[CVT]] : !fir.ref<!fir.type<t1{i:f32,j:i32,k:f32}>>
16   // CHECK: llvm.intr.stackrestore %[[STACK]] : !llvm.ptr
17   %out = fir.call @test_composite() : () -> !composite
18   // CHECK: fir.store %[[LD]] to %[[ARG0]] : !fir.ref<!fir.type<t1{i:f32,j:i32,k:f32}>>
19   fir.store %out to %arg0 : !fir.ref<!composite>
20   // CHECK: return
21   return
24 !hfa_f16 = !fir.type<t2{x:f16, y:f16}>
25 // CHECK-LABEL: func.func private @test_hfa_f16() -> !fir.type<t2{x:f16,y:f16}>
26 func.func private @test_hfa_f16() -> !hfa_f16
27 // CHECK-LABEL: func.func @test_call_hfa_f16(
28 // CHECK-SAME:    %[[ARG0:.*]]: !fir.ref<!fir.type<t2{x:f16,y:f16}>>) {
29 func.func @test_call_hfa_f16(%arg0 : !fir.ref<!hfa_f16>) {
30   // CHECK: %[[OUT:.*]] = fir.call @test_hfa_f16() : () -> !fir.type<t2{x:f16,y:f16}>
31   // CHECK: %[[STACK:.*]] = llvm.intr.stacksave : !llvm.ptr
32   // CHECK: %[[ARR:.*]] = fir.alloca !fir.type<t2{x:f16,y:f16}>
33   // CHECK: fir.store %[[OUT]] to %[[ARR]] : !fir.ref<!fir.type<t2{x:f16,y:f16}>>
34   // CHECK: %[[CVT:.*]] = fir.convert %[[ARR]] : (!fir.ref<!fir.type<t2{x:f16,y:f16}>>) -> !fir.ref<!fir.type<t2{x:f16,y:f16}>>
35   // CHECK: %[[LD:.*]] = fir.load %[[CVT]] : !fir.ref<!fir.type<t2{x:f16,y:f16}>>
36   // CHECK: llvm.intr.stackrestore %[[STACK]] : !llvm.ptr
37   %out = fir.call @test_hfa_f16() : () -> !hfa_f16
38   // CHECK: fir.store %[[LD]] to %[[ARG0]] : !fir.ref<!fir.type<t2{x:f16,y:f16}>>
39   fir.store %out to %arg0 : !fir.ref<!hfa_f16>
40   return
43 !hfa_f32 = !fir.type<t3{w:f32, x:f32, y:f32, z:f32}>
44 // CHECK-LABEL: func.func private @test_hfa_f32() -> !fir.type<t3{w:f32,x:f32,y:f32,z:f32}>
45 func.func private @test_hfa_f32() -> !hfa_f32
46 // CHECK-LABEL: func.func @test_call_hfa_f32(
47 // CHECK-SAME:    %[[ARG0:.*]]: !fir.ref<!fir.type<t3{w:f32,x:f32,y:f32,z:f32}>>) {
48 func.func @test_call_hfa_f32(%arg0 : !fir.ref<!hfa_f32>) {
49   // CHECK: %[[OUT:.*]] = fir.call @test_hfa_f32() : () -> !fir.type<t3{w:f32,x:f32,y:f32,z:f32}>
50   // CHECK: %[[STACK:.*]] = llvm.intr.stacksave : !llvm.ptr
51   // CHECK: %[[ARR:.*]] = fir.alloca !fir.type<t3{w:f32,x:f32,y:f32,z:f32}>
52   // CHECK: fir.store %[[OUT]] to %[[ARR]] : !fir.ref<!fir.type<t3{w:f32,x:f32,y:f32,z:f32}>>
53   // CHECK: %[[CVT:.*]] = fir.convert %[[ARR]] : (!fir.ref<!fir.type<t3{w:f32,x:f32,y:f32,z:f32}>>) -> !fir.ref<!fir.type<t3{w:f32,x:f32,y:f32,z:f32}>>
54   // CHECK: %[[LD:.*]] = fir.load %[[CVT]] : !fir.ref<!fir.type<t3{w:f32,x:f32,y:f32,z:f32}>>
55   // CHECK: llvm.intr.stackrestore %[[STACK]] : !llvm.ptr
56   %out = fir.call @test_hfa_f32() : () -> !hfa_f32
57   // CHECK: fir.store %[[LD]] to %[[ARG0]] : !fir.ref<!fir.type<t3{w:f32,x:f32,y:f32,z:f32}>>
58   fir.store %out to %arg0 : !fir.ref<!hfa_f32>
59   return
62 !hfa_f64 = !fir.type<t4{x:f64, y:f64, z:f64}>
63 // CHECK-LABEL: func.func private @test_hfa_f64() -> !fir.type<t4{x:f64,y:f64,z:f64}>
64 func.func private @test_hfa_f64() -> !hfa_f64
65 // CHECK-LABEL: func.func @test_call_hfa_f64(
66 // CHECK-SAME:    %[[ARG0:.*]]: !fir.ref<!fir.type<t4{x:f64,y:f64,z:f64}>>)
67 func.func @test_call_hfa_f64(%arg0 : !fir.ref<!hfa_f64>) {
68   // CHECK: %[[OUT:.*]] = fir.call @test_hfa_f64() : () -> !fir.type<t4{x:f64,y:f64,z:f64}>
69   // CHECK: %[[STACK:.*]] = llvm.intr.stacksave : !llvm.ptr
70   // CHECK: %[[ARR:.*]] = fir.alloca !fir.type<t4{x:f64,y:f64,z:f64}>
71   // CHECK: fir.store %[[OUT]] to %[[ARR]] : !fir.ref<!fir.type<t4{x:f64,y:f64,z:f64}>>
72   // CHECK: %[[CVT:.*]] = fir.convert %[[ARR]] : (!fir.ref<!fir.type<t4{x:f64,y:f64,z:f64}>>) -> !fir.ref<!fir.type<t4{x:f64,y:f64,z:f64}>>
73   // CHECK: %[[LD:.*]] = fir.load %[[CVT]] : !fir.ref<!fir.type<t4{x:f64,y:f64,z:f64}>>
74   // CHECK: llvm.intr.stackrestore %[[STACK]] : !llvm.ptr
75   %out = fir.call @test_hfa_f64() : () -> !hfa_f64
76   // CHECK: fir.store %[[LD]] to %[[ARG0]] : !fir.ref<!fir.type<t4{x:f64,y:f64,z:f64}>>
77   fir.store %out to %arg0 : !fir.ref<!hfa_f64>
78   return
81 !hfa_f128 = !fir.type<t5{w:f128, x:f128, y:f128, z:f128}>
82 // CHECK-LABEL: func.func private @test_hfa_f128() -> !fir.type<t5{w:f128,x:f128,y:f128,z:f128}>
83 func.func private @test_hfa_f128() -> !hfa_f128
84 // CHECK-LABEL: func.func @test_call_hfa_f128(
85 // CHECK-SAME:    %[[ARG0:.*]]: !fir.ref<!fir.type<t5{w:f128,x:f128,y:f128,z:f128}>>) {
86 func.func @test_call_hfa_f128(%arg0 : !fir.ref<!hfa_f128>) {
87   // CHECK: %[[OUT:.*]] = fir.call @test_hfa_f128() : () -> !fir.type<t5{w:f128,x:f128,y:f128,z:f128}>
88   // CHECK: %[[STACK:.*]] = llvm.intr.stacksave : !llvm.ptr
89   // CHECK: %[[ARR:.*]] = fir.alloca !fir.type<t5{w:f128,x:f128,y:f128,z:f128}>
90   // CHECK: fir.store %[[OUT]] to %[[ARR]] : !fir.ref<!fir.type<t5{w:f128,x:f128,y:f128,z:f128}>>
91   // CHECK: %[[CVT:.*]] = fir.convert %[[ARR]] : (!fir.ref<!fir.type<t5{w:f128,x:f128,y:f128,z:f128}>>) -> !fir.ref<!fir.type<t5{w:f128,x:f128,y:f128,z:f128}>>
92   // CHECK: %[[LD:.*]] = fir.load %[[CVT]] : !fir.ref<!fir.type<t5{w:f128,x:f128,y:f128,z:f128}>>
93   // CHECK: llvm.intr.stackrestore %[[STACK]] : !llvm.ptr
94   %out = fir.call @test_hfa_f128() : () -> !hfa_f128
95   // CHECK: fir.store %[[LD]] to %[[ARG0]] : !fir.ref<!fir.type<t5{w:f128,x:f128,y:f128,z:f128}>>
96   fir.store %out to %arg0 : !fir.ref<!hfa_f128>
97   return
100 !hfa_bf16 = !fir.type<t6{w:bf16, x:bf16, y:bf16, z:bf16}>
101 // CHECK-LABEL: func.func private @test_hfa_bf16() -> !fir.type<t6{w:bf16,x:bf16,y:bf16,z:bf16}>
102 func.func private @test_hfa_bf16() -> !hfa_bf16
103 // CHECK-LABEL: func.func @test_call_hfa_bf16(
104 // CHECK-SAME:    %[[ARG0:.*]]: !fir.ref<!fir.type<t6{w:bf16,x:bf16,y:bf16,z:bf16}>>) {
105 func.func @test_call_hfa_bf16(%arg0 : !fir.ref<!hfa_bf16>) {
106   // CHECK: %[[OUT:.*]] = fir.call @test_hfa_bf16() : () -> !fir.type<t6{w:bf16,x:bf16,y:bf16,z:bf16}>
107   // CHECK: %[[STACK:.*]] = llvm.intr.stacksave : !llvm.ptr
108   // CHECK: %[[ARR:.*]] = fir.alloca !fir.type<t6{w:bf16,x:bf16,y:bf16,z:bf16}>
109   // CHECK: fir.store %[[OUT]] to %[[ARR]] : !fir.ref<!fir.type<t6{w:bf16,x:bf16,y:bf16,z:bf16}>>
110   // CHECK: %[[CVT:.*]] = fir.convert %[[ARR]] : (!fir.ref<!fir.type<t6{w:bf16,x:bf16,y:bf16,z:bf16}>>) -> !fir.ref<!fir.type<t6{w:bf16,x:bf16,y:bf16,z:bf16}>>
111   // CHECK: %[[LD:.*]] = fir.load %[[CVT]] : !fir.ref<!fir.type<t6{w:bf16,x:bf16,y:bf16,z:bf16}>>
112   // CHECK: llvm.intr.stackrestore %[[STACK]] : !llvm.ptr
113   %out = fir.call @test_hfa_bf16() : () -> !hfa_bf16
114   // CHECK: fir.store %[[LD]] to %[[ARG0]] : !fir.ref<!fir.type<t6{w:bf16,x:bf16,y:bf16,z:bf16}>>
115   fir.store %out to %arg0 : !fir.ref<!hfa_bf16>
116   return
119 !too_big = !fir.type<t7{x:i64, y:i64, z:i64}>
120 // CHECK-LABEL: func.func private @test_too_big(!fir.ref<!fir.type<t7{x:i64,y:i64,z:i64}>>
121 // CHECK-SAME:    {llvm.align = 8 : i32, llvm.sret = !fir.type<t7{x:i64,y:i64,z:i64}>})
122 func.func private @test_too_big() -> !too_big
123 // CHECK-LABEL: func.func @test_call_too_big(
124 // CHECK-SAME:    %[[ARG0:.*]]: !fir.ref<!fir.type<t7{x:i64,y:i64,z:i64}>>) {
125 func.func @test_call_too_big(%arg0 : !fir.ref<!too_big>) {
126   // CHECK: %[[STACK:.*]] = llvm.intr.stacksave : !llvm.ptr
127   // CHECK: %[[ARG:.*]] = fir.alloca !fir.type<t7{x:i64,y:i64,z:i64}>
128   // CHECK: fir.call @test_too_big(%[[ARG]]) : (!fir.ref<!fir.type<t7{x:i64,y:i64,z:i64}>>) -> ()
129   // CHECK: %[[CVT:.*]] = fir.convert %[[ARG]] : (!fir.ref<!fir.type<t7{x:i64,y:i64,z:i64}>>) -> !fir.ref<!fir.type<t7{x:i64,y:i64,z:i64}>>
130   // CHECK: %[[LD:.*]] = fir.load %[[CVT]] : !fir.ref<!fir.type<t7{x:i64,y:i64,z:i64}>>
131   // CHECK: llvm.intr.stackrestore %[[STACK]] : !llvm.ptr
132   %out = fir.call @test_too_big() : () -> !too_big
133   // CHECK: fir.store %[[LD]] to %[[ARG0]] : !fir.ref<!fir.type<t7{x:i64,y:i64,z:i64}>>
134   fir.store %out to %arg0 : !fir.ref<!too_big>
135   return
139 !too_big_hfa = !fir.type<t8{i:!fir.array<5xf32>}>
140 // CHECK-LABEL: func.func private @test_too_big_hfa(!fir.ref<!fir.type<t8{i:!fir.array<5xf32>}>>
141 // CHECK-SAME:    {llvm.align = 8 : i32, llvm.sret = !fir.type<t8{i:!fir.array<5xf32>}>})
142 func.func private @test_too_big_hfa() -> !too_big_hfa
143 // CHECK-LABEL: func.func @test_call_too_big_hfa(
144 // CHECK-SAME:    %[[ARG0:.*]]: !fir.ref<!fir.type<t8{i:!fir.array<5xf32>}>>) {
145 func.func @test_call_too_big_hfa(%arg0 : !fir.ref<!too_big_hfa>) {
146   // CHECK: %[[STACK:.*]] = llvm.intr.stacksave : !llvm.ptr
147   // CHECK: %[[ARG:.*]] = fir.alloca !fir.type<t8{i:!fir.array<5xf32>}>
148   // CHECK: fir.call @test_too_big_hfa(%[[ARG]]) : (!fir.ref<!fir.type<t8{i:!fir.array<5xf32>}>>) -> ()
149   // CHECK: %[[CVT:.*]] = fir.convert %[[ARG]] : (!fir.ref<!fir.type<t8{i:!fir.array<5xf32>}>>) -> !fir.ref<!fir.type<t8{i:!fir.array<5xf32>}>>
150   // CHECK: %[[LD:.*]] = fir.load %[[CVT]] : !fir.ref<!fir.type<t8{i:!fir.array<5xf32>}>>
151   // CHECK: llvm.intr.stackrestore %[[STACK]] : !llvm.ptr
152   %out = fir.call @test_too_big_hfa() : () -> !too_big_hfa
153   // CHECK: fir.store %[[LD]] to %[[ARG0]] : !fir.ref<!fir.type<t8{i:!fir.array<5xf32>}>>
154   fir.store %out to %arg0 : !fir.ref<!too_big_hfa>
155   return
158 !nested_hfa_first = !fir.type<t9{s:!hfa_f16,c:f16}>
159 // CHECK-LABEL: func.func private @test_nested_hfa_first() -> !fir.type<t9{s:!fir.type<t2{x:f16,y:f16}>,c:f16}>
160 func.func private @test_nested_hfa_first() -> !nested_hfa_first
161 // CHECK-LABEL: func.func @test_call_nested_hfa_first(%arg0: !fir.ref<!fir.type<t9{s:!fir.type<t2{x:f16,y:f16}>,c:f16}>>) {
162 func.func @test_call_nested_hfa_first(%arg0 : !fir.ref<!nested_hfa_first>) {
163   %out = fir.call @test_nested_hfa_first() : () -> !nested_hfa_first
164   // CHECK: %[[OUT:.*]] = fir.call @test_nested_hfa_first() : () -> !fir.type<t9{s:!fir.type<t2{x:f16,y:f16}>,c:f16}>
165   // CHECK: %[[STACK:.*]] = llvm.intr.stacksave : !llvm.ptr
166   // CHECK: %[[ARR:.*]] = fir.alloca !fir.type<t9{s:!fir.type<t2{x:f16,y:f16}>,c:f16}>
167   // CHECK: fir.store %[[OUT]] to %[[ARR]] : !fir.ref<!fir.type<t9{s:!fir.type<t2{x:f16,y:f16}>,c:f16}>>
168   // CHECK: %[[CVT:.*]] = fir.convert %[[ARR]] : (!fir.ref<!fir.type<t9{s:!fir.type<t2{x:f16,y:f16}>,c:f16}>>
169   // CHECK: %[[LD:.*]] = fir.load %[[CVT]] : !fir.ref<!fir.type<t9{s:!fir.type<t2{x:f16,y:f16}>,c:f16}>>
170   // CHECK: llvm.intr.stackrestore %[[STACK]] : !llvm.ptr
171   fir.store %out to %arg0 : !fir.ref<!nested_hfa_first>
172   // CHECK fir.store %[[LD]] to %[[ARG0]] : !fir.ref<!fir.type<t9{s:!fir.type<t2{x:f16,y:f16}>,c:f16}>>
173   return
177 !nested_hfa_middle = !fir.type<t10{a:f16,s:!hfa_f16,c:f16}>
178 // CHECK-LABEL: func.func private @test_nested_hfa_middle() -> !fir.type<t10{a:f16,s:!fir.type<t2{x:f16,y:f16}>,c:f16}>
179 func.func private @test_nested_hfa_middle() -> !nested_hfa_middle
180 // CHECK-LABEL: func.func @test_call_nested_hfa_middle(%arg0: !fir.ref<!fir.type<t10{a:f16,s:!fir.type<t2{x:f16,y:f16}>,c:f16}>>) {
181 func.func @test_call_nested_hfa_middle(%arg0 : !fir.ref<!nested_hfa_middle>) {
182   %out = fir.call @test_nested_hfa_middle() : () -> !nested_hfa_middle
183   // CHECK: %[[OUT:.*]] = fir.call @test_nested_hfa_middle() : () -> !fir.type<t10{a:f16,s:!fir.type<t2{x:f16,y:f16}>,c:f16}>
184   // CHECK: %[[STACK:.*]] = llvm.intr.stacksave : !llvm.ptr
185   // CHECK: %[[ARR:.*]] = fir.alloca !fir.type<t10{a:f16,s:!fir.type<t2{x:f16,y:f16}>,c:f16}>
186   // CHECK: fir.store %[[OUT]] to %[[ARR]] : !fir.ref<!fir.type<t10{a:f16,s:!fir.type<t2{x:f16,y:f16}>,c:f16}>>
187   // CHECK: %[[CVT:.*]] = fir.convert %[[ARR]] : (!fir.ref<!fir.type<t10{a:f16,s:!fir.type<t2{x:f16,y:f16}>,c:f16}>>
188   // CHECK: %[[LD:.*]] = fir.load %[[CVT]] : !fir.ref<!fir.type<t10{a:f16,s:!fir.type<t2{x:f16,y:f16}>,c:f16}>>
189   // CHECK: llvm.intr.stackrestore %[[STACK]] : !llvm.ptr
190   fir.store %out to %arg0 : !fir.ref<!nested_hfa_middle>
191   // CHECK fir.store %[[LD]] to %[[ARG0]] : !fir.ref<!fir.type<t10{a:f16,s:!fir.type<t2{x:f16,y:f16}>,c:f16}>>
192   return
195 !nested_hfa_end = !fir.type<t11{a:f16,s:!hfa_f16}>
196 // CHECK-LABEL: func.func private @test_nested_hfa_end() -> !fir.type<t11{a:f16,s:!fir.type<t2{x:f16,y:f16}>}>
197 func.func private @test_nested_hfa_end() -> !nested_hfa_end
198 // CHECK-LABEL: func.func @test_call_nested_hfa_end(%arg0: !fir.ref<!fir.type<t11{a:f16,s:!fir.type<t2{x:f16,y:f16}>}>>) {
199 func.func @test_call_nested_hfa_end(%arg0 : !fir.ref<!nested_hfa_end>) {
200   %out = fir.call @test_nested_hfa_end() : () -> !nested_hfa_end
201   // CHECK: %[[OUT:.*]] = fir.call @test_nested_hfa_end() : () -> !fir.type<t11{a:f16,s:!fir.type<t2{x:f16,y:f16}>}>
202   // CHECK: %[[STACK:.*]] = llvm.intr.stacksave : !llvm.ptr
203   // CHECK: %[[ARR:.*]] = fir.alloca !fir.type<t11{a:f16,s:!fir.type<t2{x:f16,y:f16}>}>
204   // CHECK: fir.store %[[OUT]] to %[[ARR]] : !fir.ref<!fir.type<t11{a:f16,s:!fir.type<t2{x:f16,y:f16}>}>>
205   // CHECK: %[[CVT:.*]] = fir.convert %[[ARR]] : (!fir.ref<!fir.type<t11{a:f16,s:!fir.type<t2{x:f16,y:f16}>}>>
206   // CHECK: %[[LD:.*]] = fir.load %[[CVT]] : !fir.ref<!fir.type<t11{a:f16,s:!fir.type<t2{x:f16,y:f16}>}>>
207   // CHECK: llvm.intr.stackrestore %[[STACK]] : !llvm.ptr
208   fir.store %out to %arg0 : !fir.ref<!nested_hfa_end>
209   // CHECK fir.store %[[LD]] to %[[ARG0]] : !fir.ref<!fir.type<t11{a:f16,s:!fir.type<t2{x:f16,y:f16}>}>>
210   return
213 !nested_hfa_array = !fir.type<t12{a:!fir.array<2xf32>,b:f32}>
214 // CHECK-LABEL: func.func private @test_nested_hfa_array() -> !fir.type<t12{a:!fir.array<2xf32>,b:f32}>
215 func.func private @test_nested_hfa_array() -> !nested_hfa_array
216 // CHECK-LABEL: func.func @test_call_nested_hfa_array(%arg0: !fir.ref<!fir.type<t12{a:!fir.array<2xf32>,b:f32}>
217 func.func @test_call_nested_hfa_array(%arg0 : !fir.ref<!nested_hfa_array>) {
218   %out = fir.call @test_nested_hfa_array() : () -> !nested_hfa_array
219   // CHECK: %[[OUT:.*]] = fir.call @test_nested_hfa_array() : () -> !fir.type<t12{a:!fir.array<2xf32>,b:f32}>
220   // CHECK: %[[STACK:.*]] = llvm.intr.stacksave : !llvm.ptr
221   // CHECK: %[[ARR:.*]] = fir.alloca !fir.type<t12{a:!fir.array<2xf32>,b:f32}>
222   // CHECK: fir.store %[[OUT]] to %[[ARR]] : !fir.ref<!fir.type<t12{a:!fir.array<2xf32>,b:f32}>
223   // CHECK: %[[CVT:.*]] = fir.convert %[[ARR]] : (!fir.ref<!fir.type<t12{a:!fir.array<2xf32>,b:f32}>
224   // CHECK: %[[LD:.*]] = fir.load %[[CVT]] : !fir.ref<!fir.type<t12{a:!fir.array<2xf32>,b:f32}>
225   // CHECK: llvm.intr.stackrestore %[[STACK]] : !llvm.ptr
226   fir.store %out to %arg0 : !fir.ref<!nested_hfa_array>
227   // CHECK fir.store %[[LD]] to %[[ARG0]] : !fir.ref<!fir.type<t12{a:!fir.array<2xf32>,b:f32}>
228   return