[RISCV][VLOPT] Add vector narrowing integer right shift instructions to isSupportedIn...
[llvm-project.git] / flang / test / Fir / struct-return-x86-64.fir
blobf4c2add69ff7e9015b9b00256dee4034aefeae34
1 // Test X86-64 ABI rewrite of struct returned by value (BIND(C), VALUE derived types).
2 // REQUIRES: x86-registered-target
3 // RUN: fir-opt --target-rewrite %s | FileCheck %s
5 !fits_in_reg = !fir.type<t1{i:f32,j:i32,k:f32}>
6 !too_big = !fir.type<t2{i:!fir.array<5xf32>}>
8 module attributes {fir.defaultkind = "a1c4d8i4l4r4", fir.kindmap = "", llvm.data_layout = "e-m:e-p270:32:32-p271:32:32-p272:64:64-i64:64-i128:128-f80:128-n8:16:32:64-S128", llvm.target_triple = "x86_64-unknown-linux-gnu"} {
10   func.func private @test_inreg() -> !fits_in_reg
11   func.func @test_call_inreg(%arg0: !fir.ref<!fits_in_reg>) {
12     %0 = fir.call @test_inreg() : () -> !fits_in_reg
13     fir.store %0 to %arg0 : !fir.ref<!fits_in_reg>
14     return
15   }
16   func.func @test_addr_of_inreg() -> (() -> ()) {
17     %0 = fir.address_of(@test_inreg) : () -> !fits_in_reg
18     %1 = fir.convert %0 : (() -> !fits_in_reg) -> (() -> ())
19     return %1 : () -> ()
20   }
21   func.func @test_dispatch_inreg(%arg0: !fir.ref<!fits_in_reg>, %arg1: !fir.class<!fir.type<somet>>) {
22     %0 = fir.dispatch "bar"(%arg1 : !fir.class<!fir.type<somet>>) (%arg1 : !fir.class<!fir.type<somet>>) -> !fits_in_reg {pass_arg_pos = 0 : i32}
23     fir.store %0 to %arg0 : !fir.ref<!fits_in_reg>
24     return
25   }
27   func.func private @test_sret() -> !too_big
28   func.func @test_call_sret(%arg0: !fir.ref<!too_big>) {
29     %0 = fir.call @test_sret() : () -> !too_big
30     fir.store %0 to %arg0 : !fir.ref<!too_big>
31     return
32   }
33   func.func @test_addr_of_sret() -> (() -> ()) {
34     %0 = fir.address_of(@test_sret) : () -> !too_big
35     %1 = fir.convert %0 : (() -> !too_big) -> (() -> ())
36     return %1 : () -> ()
37   }
38   func.func @test_dispatch_sret(%arg0: !fir.ref<!too_big>, %arg1: !fir.class<!fir.type<somet>>) {
39     %0 = fir.dispatch "bar"(%arg1 : !fir.class<!fir.type<somet>>) (%arg1 : !fir.class<!fir.type<somet>>) -> !too_big {pass_arg_pos = 0 : i32}
40     fir.store %0 to %arg0 : !fir.ref<!too_big>
41     return
42   }
43   func.func private @test_fp_80() -> !fir.type<t3{i:f80}>
44   func.func private @test_complex_80() -> !fir.type<t4{i:complex<f80>}>
45   func.func private @test_two_fp_80() -> !fir.type<t5{i:f80,j:f80}>
46   func.func private @test_fp128() -> !fir.type<t6{i:f128}>
49 // CHECK-LABEL:   func.func private @test_inreg() -> tuple<i64, f32>
51 // CHECK-LABEL:   func.func @test_call_inreg(
52 // CHECK-SAME:                               %[[VAL_0:.*]]: !fir.ref<!fir.type<t1{i:f32,j:i32,k:f32}>>) {
53 // CHECK:           %[[VAL_1:.*]] = fir.call @test_inreg() : () -> tuple<i64, f32>
54 // CHECK:           %[[VAL_2:.*]] = llvm.intr.stacksave : !llvm.ptr
55 // CHECK:           %[[VAL_3:.*]] = fir.alloca tuple<i64, f32>
56 // CHECK:           fir.store %[[VAL_1]] to %[[VAL_3]] : !fir.ref<tuple<i64, f32>>
57 // CHECK:           %[[VAL_4:.*]] = fir.convert %[[VAL_3]] : (!fir.ref<tuple<i64, f32>>) -> !fir.ref<!fir.type<t1{i:f32,j:i32,k:f32}>>
58 // CHECK:           %[[VAL_5:.*]] = fir.load %[[VAL_4]] : !fir.ref<!fir.type<t1{i:f32,j:i32,k:f32}>>
59 // CHECK:           llvm.intr.stackrestore %[[VAL_2]] : !llvm.ptr
60 // CHECK:           fir.store %[[VAL_5]] to %[[VAL_0]] : !fir.ref<!fir.type<t1{i:f32,j:i32,k:f32}>>
61 // CHECK:           return
62 // CHECK:         }
64 // CHECK-LABEL:   func.func @test_addr_of_inreg() -> (() -> ()) {
65 // CHECK:           %[[VAL_0:.*]] = fir.address_of(@test_inreg) : () -> tuple<i64, f32>
66 // CHECK:           %[[VAL_1:.*]] = fir.convert %[[VAL_0]] : (() -> tuple<i64, f32>) -> (() -> ())
67 // CHECK:           return %[[VAL_1]] : () -> ()
68 // CHECK:         }
70 // CHECK-LABEL:   func.func @test_dispatch_inreg(
71 // CHECK-SAME:                                   %[[VAL_0:.*]]: !fir.ref<!fir.type<t1{i:f32,j:i32,k:f32}>>,
72 // CHECK-SAME:                                   %[[VAL_1:.*]]: !fir.class<!fir.type<somet>>) {
73 // CHECK:           %[[VAL_2:.*]] = fir.dispatch "bar"(%[[VAL_1]] : !fir.class<!fir.type<somet>>) (%[[VAL_1]] : !fir.class<!fir.type<somet>>) -> tuple<i64, f32> {pass_arg_pos = 0 : i32}
74 // CHECK:           %[[VAL_3:.*]] = llvm.intr.stacksave : !llvm.ptr
75 // CHECK:           %[[VAL_4:.*]] = fir.alloca tuple<i64, f32>
76 // CHECK:           fir.store %[[VAL_2]] to %[[VAL_4]] : !fir.ref<tuple<i64, f32>>
77 // CHECK:           %[[VAL_5:.*]] = fir.convert %[[VAL_4]] : (!fir.ref<tuple<i64, f32>>) -> !fir.ref<!fir.type<t1{i:f32,j:i32,k:f32}>>
78 // CHECK:           %[[VAL_6:.*]] = fir.load %[[VAL_5]] : !fir.ref<!fir.type<t1{i:f32,j:i32,k:f32}>>
79 // CHECK:           llvm.intr.stackrestore %[[VAL_3]] : !llvm.ptr
80 // CHECK:           fir.store %[[VAL_6]] to %[[VAL_0]] : !fir.ref<!fir.type<t1{i:f32,j:i32,k:f32}>>
81 // CHECK:           return
82 // CHECK:         }
83 // CHECK:         func.func private @test_sret(!fir.ref<!fir.type<t2{i:!fir.array<5xf32>}>> {llvm.align = 8 : i32, llvm.sret = !fir.type<t2{i:!fir.array<5xf32>}>})
85 // CHECK-LABEL:   func.func @test_call_sret(
86 // CHECK-SAME:                              %[[VAL_0:.*]]: !fir.ref<!fir.type<t2{i:!fir.array<5xf32>}>>) {
87 // CHECK:           %[[VAL_1:.*]] = llvm.intr.stacksave : !llvm.ptr
88 // CHECK:           %[[VAL_2:.*]] = fir.alloca !fir.type<t2{i:!fir.array<5xf32>}>
89 // CHECK:           fir.call @test_sret(%[[VAL_2]]) : (!fir.ref<!fir.type<t2{i:!fir.array<5xf32>}>>) -> ()
90 // CHECK:           %[[VAL_3:.*]] = fir.convert %[[VAL_2]] : (!fir.ref<!fir.type<t2{i:!fir.array<5xf32>}>>) -> !fir.ref<!fir.type<t2{i:!fir.array<5xf32>}>>
91 // CHECK:           %[[VAL_4:.*]] = fir.load %[[VAL_3]] : !fir.ref<!fir.type<t2{i:!fir.array<5xf32>}>>
92 // CHECK:           llvm.intr.stackrestore %[[VAL_1]] : !llvm.ptr
93 // CHECK:           fir.store %[[VAL_4]] to %[[VAL_0]] : !fir.ref<!fir.type<t2{i:!fir.array<5xf32>}>>
94 // CHECK:           return
95 // CHECK:         }
97 // CHECK-LABEL:   func.func @test_addr_of_sret() -> (() -> ()) {
98 // CHECK:           %[[VAL_0:.*]] = fir.address_of(@test_sret) : (!fir.ref<!fir.type<t2{i:!fir.array<5xf32>}>>) -> ()
99 // CHECK:           %[[VAL_1:.*]] = fir.convert %[[VAL_0]] : ((!fir.ref<!fir.type<t2{i:!fir.array<5xf32>}>>) -> ()) -> (() -> ())
100 // CHECK:           return %[[VAL_1]] : () -> ()
101 // CHECK:         }
103 // CHECK-LABEL:   func.func @test_dispatch_sret(
104 // CHECK-SAME:                                  %[[VAL_0:.*]]: !fir.ref<!fir.type<t2{i:!fir.array<5xf32>}>>,
105 // CHECK-SAME:                                  %[[VAL_1:.*]]: !fir.class<!fir.type<somet>>) {
106 // CHECK:           %[[VAL_2:.*]] = llvm.intr.stacksave : !llvm.ptr
107 // CHECK:           %[[VAL_3:.*]] = fir.alloca !fir.type<t2{i:!fir.array<5xf32>}>
108 // CHECK:           fir.dispatch "bar"(%[[VAL_1]] : !fir.class<!fir.type<somet>>) (%[[VAL_3]], %[[VAL_1]] : !fir.ref<!fir.type<t2{i:!fir.array<5xf32>}>>, !fir.class<!fir.type<somet>>) {pass_arg_pos = 1 : i32}
109 // CHECK:           %[[VAL_4:.*]] = fir.convert %[[VAL_3]] : (!fir.ref<!fir.type<t2{i:!fir.array<5xf32>}>>) -> !fir.ref<!fir.type<t2{i:!fir.array<5xf32>}>>
110 // CHECK:           %[[VAL_5:.*]] = fir.load %[[VAL_4]] : !fir.ref<!fir.type<t2{i:!fir.array<5xf32>}>>
111 // CHECK:           llvm.intr.stackrestore %[[VAL_2]] : !llvm.ptr
112 // CHECK:           fir.store %[[VAL_5]] to %[[VAL_0]] : !fir.ref<!fir.type<t2{i:!fir.array<5xf32>}>>
113 // CHECK:           return
114 // CHECK:         }
117 // CHECK: func.func private @test_fp_80() -> f80
118 // CHECK: func.func private @test_complex_80(!fir.ref<!fir.type<t4{i:complex<f80>}>> {llvm.align = 16 : i32, llvm.sret = !fir.type<t4{i:complex<f80>}>})
119 // CHECK: func.func private @test_two_fp_80(!fir.ref<!fir.type<t5{i:f80,j:f80}>> {llvm.align = 16 : i32, llvm.sret = !fir.type<t5{i:f80,j:f80}>})
120 // CHECK: func.func private @test_fp128() -> f128