xref: /llvm-project/mlir/test/Target/LLVMIR/Import/constant.ll (revision 9dd0eb9c9c207e7ea17912616c5cea58aa5c514d)
1; RUN: mlir-translate -import-llvm -split-input-file %s | FileCheck %s
2
3; CHECK-LABEL: @int_constants
4define void @int_constants(i16 %arg0, i32 %arg1, i1 %arg2) {
5  ; CHECK:  %[[C0:.+]] = llvm.mlir.constant(42 : i16) : i16
6  ; CHECK:  %[[C1:.+]] = llvm.mlir.constant(7 : i32) : i32
7  ; CHECK:  %[[C2:.+]] = llvm.mlir.constant(true) : i1
8
9  ; CHECK:  llvm.add %[[C0]], %{{.*}} : i16
10  %1 = add i16 42, %arg0
11  ; CHECK:  llvm.add %[[C1]], %{{.*}} : i32
12  %2 = add i32 7, %arg1
13  ; CHECK:  llvm.or %[[C2]], %{{.*}} : i1
14  %3 = or i1 1, %arg2
15  ret void
16}
17
18; // -----
19
20; CHECK-LABEL: @float_constants
21define void @float_constants(half %arg0, bfloat %arg1, fp128 %arg2, x86_fp80 %arg3) {
22  ; CHECK:  %[[C0:.+]] = llvm.mlir.constant(1.000000e+00 : f16) : f16
23  ; CHECK:  %[[C1:.+]] = llvm.mlir.constant(1.000000e+00 : bf16) : bf16
24  ; CHECK:  %[[C2:.+]] = llvm.mlir.constant(0.000000e+00 : f128) : f128
25  ; CHECK:  %[[C3:.+]] = llvm.mlir.constant(7.000000e+00 : f80) : f80
26
27  ; CHECK:  llvm.fadd %[[C0]], %{{.*}} : f16
28  %1 = fadd half 1.0, %arg0
29  ; CHECK:  llvm.fadd %[[C1]], %{{.*}} : bf16
30  %2 = fadd bfloat 1.0, %arg1
31  ; CHECK:  llvm.fadd %[[C2]], %{{.*}} : f128
32  %3 = fadd fp128 0xL00000000000000000000000000000000, %arg2
33  ; CHECK:  llvm.fadd %[[C3]], %{{.*}} : f80
34  %4 = fadd x86_fp80 0xK4001E000000000000000, %arg3
35  ret void
36}
37
38; // -----
39
40; CHECK-LABEL: @undef_constant
41define void @undef_constant(i32 %arg0) {
42  ; CHECK:  %[[UNDEF:.+]] = llvm.mlir.undef : i32
43  ; CHECK:  llvm.add %[[UNDEF]], %{{.*}} : i32
44  %1 = add i32 undef, %arg0
45  ret void
46}
47
48; // -----
49
50; CHECK-LABEL: @poison_constant
51define void @poison_constant(double %arg0) {
52  ; CHECK:  %[[POISON:.+]] = llvm.mlir.poison : f64
53  ; CHECK:  llvm.fadd %[[POISON]], %{{.*}} : f64
54  %1 = fadd double poison, %arg0
55  ret void
56}
57
58; // -----
59
60; CHECK-LABEL: @null_constant
61define ptr @null_constant() {
62  ; CHECK:  %[[NULL:[0-9]+]] = llvm.mlir.zero : !llvm.ptr
63  ; CHECK:  llvm.return %[[NULL]] : !llvm.ptr
64  ret ptr null
65}
66
67; // -----
68
69@global = external global i32, align 8
70
71; CHECK-LABEL: @gep_const_expr
72define ptr @gep_const_expr() {
73  ; CHECK-DAG:  %[[ADDR:[0-9]+]] = llvm.mlir.addressof @global : !llvm.ptr
74  ; CHECK-DAG:  %[[IDX:[0-9]+]] = llvm.mlir.constant(2 : i32) : i32
75  ; CHECK-DAG:  %[[GEP:[0-9]+]] = llvm.getelementptr %[[ADDR]][%[[IDX]]] : (!llvm.ptr, i32) -> !llvm.ptr
76  ; CHECK-DAG:  llvm.return %[[GEP]] : !llvm.ptr
77  ret ptr getelementptr (i32, ptr @global, i32 2)
78}
79
80; // -----
81
82@global = external global i32, align 8
83
84; CHECK-LABEL: @const_expr_with_duplicate
85define i64 @const_expr_with_duplicate() {
86  ; CHECK-DAG:  %[[ADDR:[0-9]+]] = llvm.mlir.addressof @global : !llvm.ptr
87  ; CHECK-DAG:  %[[IDX:[0-9]+]] = llvm.mlir.constant(7 : i32) : i32
88  ; CHECK-DAG:  %[[GEP:[0-9]+]] = llvm.getelementptr %[[ADDR]][%[[IDX]]] : (!llvm.ptr, i32) -> !llvm.ptr
89  ; CHECK-DAG:  %[[DUP:[0-9]+]] = llvm.ptrtoint %[[GEP]] : !llvm.ptr to i64
90
91  ; Verify the duplicate sub expression is converted only once.
92  ; CHECK-DAG:  %[[SUM:[0-9]+]] = llvm.add %[[DUP]], %[[DUP]] : i64
93  ; CHECK-DAG:  llvm.return %[[SUM]] : i64
94  ret i64 add (i64 ptrtoint (ptr getelementptr (i32, ptr @global, i32 7) to i64),
95               i64 ptrtoint (ptr getelementptr (i32, ptr @global, i32 7) to i64))
96}
97
98; // -----
99
100@global = external global i32, align 8
101
102; CHECK-LABEL: @const_expr_with_aggregate()
103define i64 @const_expr_with_aggregate() {
104  ; Compute the vector elements.
105  ; CHECK-DAG:  %[[VAL1:[0-9]+]] = llvm.mlir.constant(33 : i64) : i64
106  ; CHECK-DAG:  %[[ADDR:[0-9]+]] = llvm.mlir.addressof @global : !llvm.ptr
107  ; CHECK-DAG:  %[[IDX1:[0-9]+]] = llvm.mlir.constant(7 : i32) : i32
108  ; CHECK-DAG:  %[[GEP1:[0-9]+]] = llvm.getelementptr %[[ADDR]][%[[IDX1]]] : (!llvm.ptr, i32) -> !llvm.ptr
109  ; CHECK-DAG:  %[[VAL2:[0-9]+]] = llvm.ptrtoint %[[GEP1]] : !llvm.ptr to i64
110
111  ; Fill the vector.
112  ; CHECK-DAG:  %[[VEC1:[0-9]+]] = llvm.mlir.undef : vector<2xi64>
113  ; CHECK-DAG:  %[[IDX2:[0-9]+]] = llvm.mlir.constant(0 : i32) : i32
114  ; CHECK-DAG:  %[[VEC2:[0-9]+]] = llvm.insertelement %[[VAL1]], %[[VEC1]][%[[IDX2]] : i32] : vector<2xi64>
115  ; CHECK-DAG:  %[[IDX3:[0-9]+]] = llvm.mlir.constant(1 : i32) : i32
116  ; CHECK-DAG:  %[[VEC3:[0-9]+]] = llvm.insertelement %[[VAL2]], %[[VEC2]][%[[IDX3]] : i32] : vector<2xi64>
117  ; CHECK-DAG:  %[[IDX4:[0-9]+]] = llvm.mlir.constant(42 : i32) : i32
118
119  ; Compute the extract index.
120  ; CHECK-DAG:  %[[GEP2:[0-9]+]] = llvm.getelementptr %[[ADDR]][%[[IDX4]]] : (!llvm.ptr, i32) -> !llvm.ptr
121  ; CHECK-DAG:  %[[IDX5:[0-9]+]] = llvm.ptrtoint %[[GEP2]] : !llvm.ptr to i64
122
123  ; Extract the vector element.
124  ; CHECK-DAG:  %[[ELEM:[0-9]+]] = llvm.extractelement %[[VEC3]][%[[IDX5]] : i64] : vector<2xi64>
125  ; CHECK-DAG:  llvm.return %[[ELEM]] : i64
126  ret i64 extractelement (
127    <2 x i64> <i64 33, i64 ptrtoint (ptr getelementptr (i32, ptr @global, i32 7) to i64)>,
128    i64 ptrtoint (ptr getelementptr (i32, ptr @global, i32 42) to i64))
129}
130
131; // -----
132
133; Verify the function constant import.
134
135; Calling a function that has not been defined yet.
136; CHECK-LABEL: @function_address_before_def
137define i32 @function_address_before_def() {
138  %1 = alloca ptr
139  ; CHECK:  %[[FUN:.*]] = llvm.mlir.addressof @callee : !llvm.ptr
140  ; CHECK:  llvm.store %[[FUN]], %[[PTR:.*]] : !llvm.ptr, !llvm.ptr
141  store ptr @callee, ptr %1
142  ; CHECK:  %[[INDIR:.*]] = llvm.load %[[PTR]] : !llvm.ptr -> !llvm.ptr
143  %2 = load ptr, ptr %1
144  ; CHECK:  llvm.call %[[INDIR]]() : !llvm.ptr, () -> i32
145  %3 = call i32 %2()
146  ret i32 %3
147}
148
149define i32 @callee() {
150  ret i32 42
151}
152
153; Calling a function that has been defined.
154; CHECK-LABEL: @function_address_after_def
155define i32 @function_address_after_def() {
156  %1 = alloca ptr
157  ; CHECK:  %[[FUN:.*]] = llvm.mlir.addressof @callee : !llvm.ptr
158  ; CHECK:  llvm.store %[[FUN]], %[[PTR:.*]] : !llvm.ptr, !llvm.ptr
159  store ptr @callee, ptr %1
160  ; CHECK:  %[[INDIR:.*]] = llvm.load %[[PTR]] : !llvm.ptr -> !llvm.ptr
161  %2 = load ptr, ptr %1
162  ; CHECK:  llvm.call %[[INDIR]]() : !llvm.ptr, () -> i32
163  %3 = call i32 %2()
164  ret i32 %3
165}
166
167; // -----
168
169; Verify the aggregate constant import.
170
171; CHECK-DAG:  %[[C0:.+]] = llvm.mlir.constant(9 : i32) : i32
172; CHECK-DAG:  %[[C1:.+]] = llvm.mlir.constant(4 : i8) : i8
173; CHECK-DAG:  %[[C2:.+]] = llvm.mlir.constant(8 : i16) : i16
174; CHECK-DAG:  %[[C3:.+]] = llvm.mlir.constant(7 : i32) : i32
175; CHECK-DAG:  %[[ROOT:.+]] = llvm.mlir.undef : !llvm.struct<"simple_agg_type", (i32, i8, i16, i32)>
176; CHECK-DAG:  %[[CHAIN0:.+]] = llvm.insertvalue %[[C0]], %[[ROOT]][0]
177; CHECK-DAG:  %[[CHAIN1:.+]] = llvm.insertvalue %[[C1]], %[[CHAIN0]][1]
178; CHECK-DAG:  %[[CHAIN2:.+]] = llvm.insertvalue %[[C2]], %[[CHAIN1]][2]
179; CHECK-DAG:  %[[CHAIN3:.+]] = llvm.insertvalue %[[C3]], %[[CHAIN2]][3]
180; CHECK-DAG:  llvm.return %[[CHAIN3]]
181%simple_agg_type = type {i32, i8, i16, i32}
182@simple_agg = global %simple_agg_type {i32 9, i8 4, i16 8, i32 7}
183
184; CHECK-DAG:  %[[C1:.+]] = llvm.mlir.constant(1 : i32) : i32
185; CHECK-DAG:  %[[C2:.+]] = llvm.mlir.constant(2 : i8) : i8
186; CHECK-DAG:  %[[C3:.+]] = llvm.mlir.constant(3 : i16) : i16
187; CHECK-DAG:  %[[C4:.+]] = llvm.mlir.constant(4 : i32) : i32
188; CHECK-DAG:  %[[NESTED:.+]] = llvm.mlir.undef : !llvm.struct<"simple_agg_type", (i32, i8, i16, i32)>
189; CHECK-DAG:  %[[CHAIN0:.+]] = llvm.insertvalue %[[C1]], %[[NESTED]][0]
190; CHECK-DAG:  %[[CHAIN1:.+]] = llvm.insertvalue %[[C2]], %[[CHAIN0]][1]
191; CHECK-DAG:  %[[CHAIN2:.+]] = llvm.insertvalue %[[C3]], %[[CHAIN1]][2]
192; CHECK-DAG:  %[[CHAIN3:.+]] = llvm.insertvalue %[[C4]], %[[CHAIN2]][3]
193; CHECK-DAG:  %[[NULL:.+]] = llvm.mlir.zero : !llvm.ptr
194; CHECK-DAG:  %[[ROOT:.+]] = llvm.mlir.undef : !llvm.struct<"nested_agg_type", (struct<"simple_agg_type", (i32, i8, i16, i32)>, ptr)>
195; CHECK-DAG:  %[[CHAIN4:.+]] = llvm.insertvalue %[[CHAIN3]], %[[ROOT]][0]
196; CHECK-DAG:  %[[CHAIN5:.+]] = llvm.insertvalue %[[NULL]], %[[CHAIN4]][1]
197; CHECK-DAG:  llvm.return %[[CHAIN5]]
198%nested_agg_type = type {%simple_agg_type, ptr}
199@nested_agg = global %nested_agg_type { %simple_agg_type{i32 1, i8 2, i16 3, i32 4}, ptr null }
200
201; CHECK-DAG:  %[[NULL:.+]] = llvm.mlir.zero : !llvm.ptr
202; CHECK-DAG:  %[[ROOT:.+]] = llvm.mlir.undef : !llvm.vec<2 x ptr>
203; CHECK-DAG:  %[[P0:.+]] = llvm.mlir.constant(0 : i32) : i32
204; CHECK-DAG:  %[[CHAIN0:.+]] = llvm.insertelement %[[NULL]], %[[ROOT]][%[[P0]] : i32] : !llvm.vec<2 x ptr>
205; CHECK-DAG:  %[[P1:.+]] = llvm.mlir.constant(1 : i32) : i32
206; CHECK-DAG:  %[[CHAIN1:.+]] = llvm.insertelement %[[NULL]], %[[CHAIN0]][%[[P1]] : i32] : !llvm.vec<2 x ptr>
207; CHECK-DAG:  llvm.return %[[CHAIN1]] : !llvm.vec<2 x ptr>
208@vector_agg = global <2 x ptr> <ptr null, ptr null>
209
210; // -----
211
212; Verfiy the import of subsequent constant expressions with duplicates.
213
214@global = external global i32, align 8
215
216; CHECK-LABEL: @const_exprs_with_duplicate
217define i64 @const_exprs_with_duplicate() {
218  ; CHECK: %[[ADDR:.+]] = llvm.mlir.addressof @global : !llvm.ptr
219  ; CHECK: llvm.getelementptr %[[ADDR]][%{{.*}}] : (!llvm.ptr, i32) -> !llvm.ptr
220  %1 = add i64 1, ptrtoint (ptr getelementptr (i32, ptr @global, i32 7) to i64)
221
222  ; Verify the address value is reused.
223  ; CHECK: llvm.getelementptr %[[ADDR]][%{{.*}}] : (!llvm.ptr, i32) -> !llvm.ptr
224  %2 = add i64 %1, ptrtoint (ptr getelementptr (i32, ptr @global, i32 42) to i64)
225  ret i64 %2
226}
227
228; // -----
229
230; Verify the import of constant expressions with cyclic dependencies.
231
232@cyclic = internal constant i64 add (i64 ptrtoint (ptr @cyclic to i64), i64 ptrtoint (ptr @cyclic to i64))
233
234; CHECK-LABEL: @cyclic
235; CHECK:  %[[ADDR:.+]] = llvm.mlir.addressof @cyclic
236; CHECK:  %[[VAL0:.+]] = llvm.ptrtoint %[[ADDR]]
237; CHECK:  %[[VAL1:.+]] = llvm.add %[[VAL0]], %[[VAL0]]
238; CHECK:  llvm.return %[[VAL1]]
239