Break circular dependency between FIR dialect and utilities
[llvm-project.git] / flang / test / Fir / box.fir
blob1a9c9e049681426481001919e9f7455ae07d9746
1 // RUN: tco -o - %s | FileCheck %s
3 // Global box initialization (test must come first because llvm globals are emitted first).
4 // CHECK-LABEL: @globalx = internal global { ptr, i64, i32, i8, i8, i8, i8 } { ptr null, i64 ptrtoint (ptr getelementptr (i32, ptr null, i32 1) to i64), i32 20180515, i8 0, i8 9, i8 2, i8 0 }
5 fir.global internal @globalx : !fir.box<!fir.heap<i32>> {
6   %c0 = arith.constant 0 : index
7   %0 = fir.convert %c0 : (index) -> !fir.heap<i32>
8   %1 = fir.embox %0 : (!fir.heap<i32>) -> !fir.box<!fir.heap<i32>>
9   fir.has_value %1 : !fir.box<!fir.heap<i32>>
12 // CHECK-LABEL: @globaly = internal global { ptr, i64, i32, i8, i8, i8, i8, [1 x [3 x i64]] } { ptr null, i64 ptrtoint (ptr getelementptr (float, ptr null, i32 1) to i64), i32 20180515, i8 1, i8 27, i8 2, i8 0,{{.*}}[3 x i64] [i64 1, i64 0, i64 ptrtoint (ptr getelementptr (float, ptr null, i32 1) to i64)]
13 fir.global internal @globaly : !fir.box<!fir.heap<!fir.array<?xf32>>> {
14   %c0 = arith.constant 0 : index
15   %0 = fir.convert %c0 : (index) -> !fir.heap<!fir.array<?xf32>>
16   %1 = fir.shape %c0 : (index) -> !fir.shape<1>
17   %2 = fir.embox %0(%1) : (!fir.heap<!fir.array<?xf32>>, !fir.shape<1>) -> !fir.box<!fir.heap<!fir.array<?xf32>>>
18   fir.has_value %2 : !fir.box<!fir.heap<!fir.array<?xf32>>>
21 // CHECK-LABEL: declare void @g(ptr)
22 func.func private @g(%b : !fir.box<f32>)
23 // CHECK-LABEL: declare void @ga(ptr)
24 func.func private @ga(%b : !fir.box<!fir.array<?xf32>>)
26 // CHECK-LABEL: define void @f
27 // CHECK: (ptr %[[ARG:.*]])
28 func.func @f(%a : !fir.ref<f32>) {
29   // CHECK: %[[DESC:.*]] = alloca { ptr, i64, i32, i8, i8, i8, i8 }
30   // CHECK: %[[INS0:.*]] = insertvalue {{.*}} { ptr undef, i64 ptrtoint (ptr getelementptr (float, ptr null, i32 1) to i64), i32 20180515, i8 0, i8 27, i8 0, i8 0 }, ptr %[[ARG]], 0
31   // CHECK: store {{.*}} %[[INS0]], {{.*}} %[[DESC]]
32   %b = fir.embox %a : (!fir.ref<f32>) -> !fir.box<f32>
34   // CHECK: call void @g({{.*}} %[[DESC]])
35   fir.call @g(%b) : (!fir.box<f32>) -> ()
36   // CHECK: ret void
37   return
40 // CHECK-LABEL: define void @fa
41 // CHECK: (ptr %[[ARG:.*]])
42 func.func @fa(%a : !fir.ref<!fir.array<100xf32>>) {
43   %c = fir.convert %a : (!fir.ref<!fir.array<100xf32>>) -> !fir.ref<!fir.array<?xf32>>
44   %c1 = arith.constant 1 : index
45   %c100 = arith.constant 100 : index
46   %d = fir.shape %c100 : (index) -> !fir.shape<1>
47   // CHECK: %[[INS70:.*]] = insertvalue {{.*}} { ptr undef, i64 ptrtoint (ptr getelementptr (float, ptr null, i32 1) to i64), i32 20180515, i8 1, i8 27, i8 0, i8 0, {{.*}} }, ptr %{{.*}}, 0
48   %b = fir.embox %c(%d) : (!fir.ref<!fir.array<?xf32>>, !fir.shape<1>) -> !fir.box<!fir.array<?xf32>>
49   // CHECK: call void @ga(
50   fir.call @ga(%b) : (!fir.box<!fir.array<?xf32>>) -> ()
51   // CHECK: ret void
52   return
55 // Boxing of a scalar character of dynamic length
56 // CHECK-LABEL: define void @b1(
57 // CHECK-SAME: ptr %[[res:.*]], ptr %[[arg0:.*]], i64 %[[arg1:.*]])
58 func.func @b1(%arg0 : !fir.ref<!fir.char<1,?>>, %arg1 : index) -> !fir.box<!fir.char<1,?>> {
59   // CHECK: %[[size:.*]] = mul i64 ptrtoint (ptr getelementptr (i8, ptr null, i32 1) to i64), %[[arg1]]
60   // CHECK: insertvalue {{.*}} undef, i64 %[[size]], 1
61   // CHECK: insertvalue {{.*}} i32 20180515, 2
62   // CHECK: insertvalue {{.*}} ptr %[[arg0]], 0
63   %x = fir.embox %arg0 typeparams %arg1 : (!fir.ref<!fir.char<1,?>>, index) -> !fir.box<!fir.char<1,?>>
64   // CHECK: store {{.*}}, ptr %[[res]]
65   return %x : !fir.box<!fir.char<1,?>>
68 // Boxing of a dynamic array of character with static length (5)
69 // CHECK-LABEL: define void @b2(
70 // CHECK-SAME: ptr %[[res]],
71 // CHECK-SAME: ptr %[[arg0:.*]], i64 %[[arg1:.*]])
72 func.func @b2(%arg0 : !fir.ref<!fir.array<?x!fir.char<1,5>>>, %arg1 : index) -> !fir.box<!fir.array<?x!fir.char<1,5>>> {
73   %1 = fir.shape %arg1 : (index) -> !fir.shape<1>
74   // CHECK: insertvalue {{.*}} { ptr undef, i64 ptrtoint (ptr getelementptr ([5 x i8], ptr null, i32 1) to i64), i32 20180515, i8 1, i8 40, i8 0, i8 0, {{.*}} }, i64 %[[arg1]], 7, 0, 1
75   // CHECK: insertvalue {{.*}} %{{.*}}, i64 ptrtoint (ptr getelementptr ([5 x i8], ptr null, i32 1) to i64), 7, 0, 2
76   // CHECK: insertvalue {{.*}} ptr %[[arg0]], 0
77   %2 = fir.embox %arg0(%1) : (!fir.ref<!fir.array<?x!fir.char<1,5>>>, !fir.shape<1>) -> !fir.box<!fir.array<?x!fir.char<1,5>>>
78   // CHECK: store {{.*}}, ptr %[[res]]
79   return %2 : !fir.box<!fir.array<?x!fir.char<1,5>>>
82 // Boxing of a dynamic array of character of dynamic length
83 // CHECK-LABEL: define void @b3(
84 // CHECK-SAME: ptr %[[res:.*]], ptr %[[arg0:.*]], i64 %[[arg1:.*]], i64 %[[arg2:.*]])
85 func.func @b3(%arg0 : !fir.ref<!fir.array<?x!fir.char<1,?>>>, %arg1 : index, %arg2 : index) -> !fir.box<!fir.array<?x!fir.char<1,?>>> {
86   %1 = fir.shape %arg2 : (index) -> !fir.shape<1>
87   // CHECK: %[[size:.*]] = mul i64 ptrtoint (ptr getelementptr (i8, ptr null, i32 1) to i64), %[[arg1]]
88   // CHECK: insertvalue {{.*}} i64 %[[size]], 1
89   // CHECK: insertvalue {{.*}} i32 20180515, 2
90   // CHECK: insertvalue {{.*}} i64 %[[arg2]], 7, 0, 1
91   // CHECK: insertvalue {{.*}} i64 %[[size]], 7, 0, 2
92   // CHECK: insertvalue {{.*}} ptr %[[arg0]], 0
93   %2 = fir.embox %arg0(%1) typeparams %arg1 : (!fir.ref<!fir.array<?x!fir.char<1,?>>>, !fir.shape<1>, index) -> !fir.box<!fir.array<?x!fir.char<1,?>>>
94   // CHECK: store {{.*}}, ptr %[[res]]
95   return %2 : !fir.box<!fir.array<?x!fir.char<1,?>>>
98 // Boxing of a static array of character of dynamic length
99 // CHECK-LABEL: define void @b4(
100 // CHECK-SAME: ptr %[[res:.*]], ptr %[[arg0:.*]], i64 %[[arg1:.*]])
101 func.func @b4(%arg0 : !fir.ref<!fir.array<7x!fir.char<1,?>>>, %arg1 : index) -> !fir.box<!fir.array<7x!fir.char<1,?>>> {
102   %c_7 = arith.constant 7 : index
103   %1 = fir.shape %c_7 : (index) -> !fir.shape<1>
104   // CHECK:   %[[size:.*]] = mul i64 ptrtoint (ptr getelementptr (i8, ptr null, i32 1) to i64), %[[arg1]]
105   // CHECK: insertvalue {{.*}} i64 %[[size]], 1
106   // CHECK: insertvalue {{.*}} i32 20180515, 2
107   // CHECK: insertvalue {{.*}} i64 7, 7, 0, 1
108   // CHECK: insertvalue {{.*}} i64 %[[size]], 7, 0, 2
109   // CHECK: insertvalue {{.*}} ptr %[[arg0]], 0
110   %x = fir.embox %arg0(%1) typeparams %arg1 : (!fir.ref<!fir.array<7x!fir.char<1,?>>>, !fir.shape<1>, index) -> !fir.box<!fir.array<7x!fir.char<1,?>>>
111   // CHECK: store {{.*}}, ptr %[[res]]
112   return %x : !fir.box<!fir.array<7x!fir.char<1,?>>>
115 // Storing a fir.box into a fir.ref<fir.box> (modifying descriptors).
116 // CHECK-LABEL: define void @b5(
117 // CHECK-SAME: ptr %[[arg0:.*]], ptr %[[arg1:.*]])
118 func.func @b5(%arg0 : !fir.ref<!fir.box<!fir.heap<!fir.array<?x?xf32>>>>, %arg1 : !fir.box<!fir.heap<!fir.array<?x?xf32>>>) {
119   fir.store %arg1 to %arg0 : !fir.ref<!fir.box<!fir.heap<!fir.array<?x?xf32>>>>
120   // CHECK: %[[boxLoad:.*]] = load { ptr, i64, i32, i8, i8, i8, i8, [2 x [3 x i64]] }, ptr %[[arg1]]
121   // CHECK: store { ptr, i64, i32, i8, i8, i8, i8, [2 x [3 x i64]] } %[[boxLoad]], ptr %[[arg0]]
122   return
125 func.func private @callee6(!fir.box<none>) -> i32
127 // CHECK-LABEL: define i32 @box6(
128 // CHECK-SAME: ptr %[[ARG0:.*]], i64 %[[ARG1:.*]], i64 %[[ARG2:.*]])
129 func.func @box6(%0 : !fir.ref<!fir.array<?x?x?x?xf32>>, %1 : index, %2 : index) -> i32 {
130   %c100 = arith.constant 100 : index
131   %c50 = arith.constant 50 : index
132   %c30 = arith.constant 30 : index
133   %c6 = arith.constant 6 : index
134   %shape = fir.shape %c100, %c50, %c30, %c6 : (index, index, index, index) -> !fir.shape<4>
135   %3 = fir.undefined index
136   %c41 = arith.constant 41 : index
137   %c2 = arith.constant 2 : index
138   %c24 = arith.constant 24 : index
139   %c1 = arith.constant 1 : index
140   %c3 = arith.constant 3 : index
142   // CHECK: %[[i:.*]] = sub i64 %[[ARG1]], 1
143   // CHECK: %[[i100:.*]] = mul i64 %[[i]], 100
144   // CHECK: %[[i100p40:.*]] = add i64 %[[i100]], 40
145   // CHECK: %[[diff:.*]] = sub i64 %[[ARG2]], %[[ARG1]]
146   // CHECK: %[[dp2:.*]] = add i64 %[[diff]], 2
147   // CHECK: %[[sdp2:.*]] = sdiv i64 %[[dp2]], 2
148   // CHECK: %[[cmp:.*]] = icmp sgt i64 %[[sdp2]], 0
149   // CHECK: %[[extent:.*]] = select i1 %[[cmp]], i64 %[[sdp2]], i64 0
150   // CHECK: insertvalue { ptr, i64, i32, i8, i8, i8, i8, [2 x [3 x i64]] } { ptr undef, i64 ptrtoint (ptr getelementptr (float, ptr null, i32 1) to i64), i32 20180515, i8 2, i8 27, i8 0, i8 0, [2 x [3 x i64]] [{{\[}}3 x i64] [i64 1, i64 undef, i64 undef], [3 x i64] undef] }, i64 %[[extent]], 7, 0, 1
151   // CHECK: insertvalue { ptr, i64, i32, i8, i8, i8, i8, [2 x [3 x i64]] } %{{.*}}, i64 mul (i64 ptrtoint (ptr getelementptr (float, ptr null, i32 1) to i64), i64 200), 7, 0, 2
152   // CHECK: %[[op25:.*]] = add i64 25000, %[[i100p40]]
153   // CHECK: insertvalue { ptr, i64, i32, i8, i8, i8, i8, [2 x [3 x i64]] } %{{.*}}, i64 1, 7, 1, 0
154   // CHECK: insertvalue { ptr, i64, i32, i8, i8, i8, i8, [2 x [3 x i64]] } %{{.*}}, i64 4, 7, 1, 1
155   // CHECK: insertvalue { ptr, i64, i32, i8, i8, i8, i8, [2 x [3 x i64]] } %{{.*}}, i64 mul (i64 ptrtoint (ptr getelementptr (float, ptr null, i32 1) to i64), i64 30000), 7, 1, 2
156   // CHECK: %[[op300:.*]] = add i64 300000, %[[op25]]
157   // CHECK: %[[ptr:.*]] = getelementptr float, ptr %[[ARG0]], i64 %[[op300]]
158   // CHECK: insertvalue { ptr, i64, i32, i8, i8, i8, i8, [2 x [3 x i64]] } %{{.*}}, ptr %[[ptr]], 0
159   // CHECK: store { ptr, i64, i32, i8, i8, i8, i8, [2 x [3 x i64]] } %{{.*}}, ptr %[[mem:[0-9]+]]
162   %slice = fir.slice %c41, %3, %3, %1, %2, %c2, %c6, %c24, %c6, %c3, %3, %3 : (index, index, index, index, index, index, index, index, index, index, index, index) -> !fir.slice<4>
163   %box = fir.embox %0(%shape)[%slice] : (!fir.ref<!fir.array<?x?x?x?xf32>>, !fir.shape<4>, !fir.slice<4>) -> !fir.box<!fir.array<?x?x?x?xf32>>
164   %nonebox = fir.convert %box : (!fir.box<!fir.array<?x?x?x?xf32>>) -> !fir.box<none>
165   // CHECK: %[[call:.*]] = call i32 @callee6(ptr %[[mem]])
166   %rv = fir.call @callee6(%nonebox) : (!fir.box<none>) -> i32
167   // CHECK: ret i32 %[[call]]
168   return %rv : i32