xref: /llvm-project/llvm/test/Bitcode/constexpr-to-instr.ll (revision d452d5e2de70a180e5af26dbda40cfb8b2506590)
1; RUN: llvm-dis -expand-constant-exprs < %s.bc | FileCheck %s
2
3@g = extern_weak global i32
4@g2 = extern_weak global i32
5
6define i64 @test_cast() {
7; CHECK-LABEL: define i64 @test_cast() {
8; CHECK-NEXT: %constexpr = ptrtoint ptr @g to i64
9; CHECK-NEXT: ret i64 %constexpr
10  ret i64 ptrtoint (ptr @g to i64)
11}
12
13define i1 @test_icmp() {
14; CHECK-LABEL: define i1 @test_icmp() {
15; CHECK-NEXT: %constexpr = ptrtoint ptr @g to i64
16; CHECK-NEXT: %constexpr1 = icmp ne i64 %constexpr, 0
17; CHECK-NEXT: ret i1 %constexpr1
18  ret i1 icmp ne (i64 ptrtoint (ptr @g to i64), i64 0)
19}
20
21define i32 @test_select() {
22; CHECK-LABEL: define i32 @test_select() {
23; CHECK-NEXT: %constexpr = ptrtoint ptr @g to i64
24; CHECK-NEXT: %constexpr1 = icmp ne i64 %constexpr, 0
25; CHECK-NEXT: %constexpr2 = select i1 %constexpr1, i32 1, i32 2
26; CHECK-NEXT: ret i32 %constexpr2
27  ret i32 select (i1 icmp ne (i64 ptrtoint (ptr @g to i64), i64 0), i32 1, i32 2)
28}
29
30define i8 @test_extractelement() {
31; CHECK-LABEL: define i8 @test_extractelement() {
32; CHECK-NEXT: %constexpr = ptrtoint ptr @g to i64
33; CHECK-NEXT: %constexpr1 = icmp ne i64 %constexpr, 0
34; CHECK-NEXT: %constexpr2 = select i1 %constexpr1, <2 x i8> zeroinitializer, <2 x i8> <i8 0, i8 1>
35; CHECK-NEXT: %constexpr3 = extractelement <2 x i8> %constexpr2, i32 0
36; CHECK-NEXT: ret i8 %constexpr3
37  ret i8 extractelement (<2 x i8> select (i1 icmp ne (i64 ptrtoint (ptr @g to i64), i64 0), <2 x i8> zeroinitializer, <2 x i8> <i8 0, i8 1>), i32 0)
38}
39
40define <2 x i8> @test_insertelement() {
41; CHECK-LABEL: define <2 x i8> @test_insertelement() {
42; CHECK-NEXT: %constexpr = ptrtoint ptr @g to i32
43; CHECK-NEXT: %constexpr1 = insertelement <2 x i8> poison, i8 42, i32 %constexpr
44; CHECK-NEXT: ret <2 x i8> %constexpr1
45  ret <2 x i8> insertelement (<2 x i8> poison, i8 42, i32 ptrtoint (ptr @g to i32))
46}
47
48define double @test_fneg() {
49; CHECK-LABEL: define double @test_fneg() {
50; CHECK-NEXT: %constexpr = ptrtoint ptr @g to i64
51; CHECK-NEXT: %constexpr1 = bitcast i64 %constexpr to double
52; CHECK-NEXT: %constexpr2 = fneg double %constexpr1
53  ret double fneg (double bitcast (i64 ptrtoint (ptr @g to i64) to double))
54}
55
56define i64 @test_flags() {
57; CHECK-LABEL: define i64 @test_flags() {
58; CHECK-NEXT: %constexpr = ptrtoint ptr @g to i64
59; CHECK-NEXT: %constexpr1 = add nuw i64 %constexpr, 1
60; CHECK-NEXT: ret i64 %constexpr1
61  ret i64 add nuw (i64 ptrtoint (ptr @g to i64), i64 1)
62}
63
64define <3 x i64> @test_vector() {
65; CHECK-LABEL: define <3 x i64> @test_vector() {
66; CHECK-NEXT: %constexpr = ptrtoint ptr @g to i64
67; CHECK-NEXT: %constexpr.ins = insertelement <3 x i64> poison, i64 5, i32 0
68; CHECK-NEXT: %constexpr.ins1 = insertelement <3 x i64> %constexpr.ins, i64 %constexpr, i32 1
69; CHECK-NEXT: %constexpr.ins2 = insertelement <3 x i64> %constexpr.ins1, i64 7, i32 2
70  ret <3 x i64> <i64 5, i64 ptrtoint (ptr @g to i64), i64 7>
71}
72
73define [3 x i64] @test_array() {
74; CHECK-LABEL: define [3 x i64] @test_array() {
75; CHECK-NEXT: %constexpr = ptrtoint ptr @g to i64
76; CHECK-NEXT: %constexpr.ins = insertvalue [3 x i64] poison, i64 5, 0
77; CHECK-NEXT: %constexpr.ins1 = insertvalue [3 x i64] %constexpr.ins, i64 %constexpr, 1
78; CHECK-NEXT: %constexpr.ins2 = insertvalue [3 x i64] %constexpr.ins1, i64 7, 2
79  ret [3 x i64] [i64 5, i64 ptrtoint (ptr @g to i64), i64 7]
80}
81
82define { i64, i64, i64 } @test_struct() {
83; CHECK-LABEL: define { i64, i64, i64 } @test_struct() {
84; CHECK-NEXT: %constexpr = ptrtoint ptr @g to i64
85; CHECK-NEXT: %constexpr.ins = insertvalue { i64, i64, i64 } poison, i64 5, 0
86; CHECK-NEXT: %constexpr.ins1 = insertvalue { i64, i64, i64 } %constexpr.ins, i64 %constexpr, 1
87; CHECK-NEXT: %constexpr.ins2 = insertvalue { i64, i64, i64 } %constexpr.ins1, i64 7, 2
88  ret { i64, i64, i64 } {i64 5, i64 ptrtoint (ptr @g to i64), i64 7}
89}
90
91define i64 @test_reused_expr() {
92; CHECK-LABEL: define i64 @test_reused_expr() {
93; CHECK-NEXT: %constexpr = ptrtoint ptr @g to i64
94; CHECK-NEXT: %constexpr1 = add i64 %constexpr, %constexpr
95; CHECK-NEXT: ret i64 %constexpr1
96  ret i64 add (i64 ptrtoint (ptr @g to i64), i64 ptrtoint (ptr @g to i64))
97}
98
99define i64 @test_multiple_expanded_operands() {
100; CHECK-LABEL: define i64 @test_multiple_expanded_operands() {
101; CHECK-NEXT: %constexpr = ptrtoint ptr @g to i64
102; CHECK-NEXT: %constexpr1 = ptrtoint ptr @g2 to i64
103; CHECK-NEXT: %constexpr2 = add i64 %constexpr, %constexpr1
104; CHECK-NEXT: ret i64 %constexpr2
105  ret i64 add (i64 ptrtoint (ptr @g to i64), i64 ptrtoint (ptr @g2 to i64))
106}
107
108define i64 @test_mid_block(i64 %arg) {
109; CHECK-LABEL: define i64 @test_mid_block(i64 %arg) {
110; CHECK-NEXT: %x = mul i64 %arg, 3
111; CHECK-NEXT: %constexpr = ptrtoint ptr @g to i64
112; CHECK-NEXT: %add = add i64 %x, %constexpr
113; CHECK-NEXT: ret i64 %add
114  %x = mul i64 %arg, 3
115  %add = add i64 %x, ptrtoint (ptr @g to i64)
116  ret i64 %add
117}
118
119define i64 @test_phi_non_critical_edge_block_before(i1 %c) {
120; CHECK-LABEL: define i64 @test_phi_non_critical_edge_block_before(i1 %c) {
121; CHECK: entry:
122; CHECK-NEXT: br i1 %c, label %if, label %join
123; CHECK: if:
124; CHECK-NEXT: br label %phi.constexpr
125; CHECK: phi.constexpr:
126; CHECK-NEXT: %constexpr = ptrtoint ptr @g to i64
127; CHECK-NEXT: br label %join
128; CHECK: join:
129; CHECK-NEXT: %phi = phi i64 [ 0, %entry ], [ %constexpr, %phi.constexpr ]
130; CHECK-NEXT: ret i64 %phi
131entry:
132  br i1 %c, label %if, label %join
133
134if:
135  br label %join
136
137join:
138  %phi = phi i64 [ 0, %entry ], [ ptrtoint (ptr @g to i64), %if ]
139  ret i64 %phi
140}
141
142define i64 @test_phi_non_critical_edge_block_after(i1 %c) {
143; CHECK-LABEL: define i64 @test_phi_non_critical_edge_block_after(i1 %c) {
144; CHECK: entry:
145; CHECK-NEXT: br i1 %c, label %if, label %join
146; CHECK: phi.constexpr:
147; CHECK-NEXT: %constexpr = ptrtoint ptr @g to i64
148; CHECK-NEXT: br label %join
149; CHECK: join:
150; CHECK-NEXT: %phi = phi i64 [ 0, %entry ], [ %constexpr, %phi.constexpr ]
151; CHECK-NEXT: ret i64 %phi
152; CHECK: if:
153; CHECK-NEXT: br label %phi.constexpr
154entry:
155  br i1 %c, label %if, label %join
156
157join:
158  %phi = phi i64 [ 0, %entry ], [ ptrtoint (ptr @g to i64), %if ]
159  ret i64 %phi
160
161if:
162  br label %join
163}
164
165define i64 @test_phi_critical_edge(i1 %c) {
166; CHECK-LABEL: define i64 @test_phi_critical_edge(i1 %c) {
167; CHECK: entry:
168; CHECK-NEXT: br i1 %c, label %if, label %phi.constexpr
169; CHECK: if:
170; CHECK-NEXT: br label %join
171; CHECK: phi.constexpr:
172; CHECK-NEXT: %constexpr = ptrtoint ptr @g to i64
173; CHECK-NEXT: br label %join
174; CHECK: join:
175; CHECK-NEXT: %phi = phi i64 [ %constexpr, %phi.constexpr ], [ 0, %if ]
176; CHECK-NEXT: ret i64 %phi
177entry:
178  br i1 %c, label %if, label %join
179
180if:
181  br label %join
182
183join:
184  %phi = phi i64 [ ptrtoint (ptr @g to i64), %entry ], [ 0, %if ]
185  ret i64 %phi
186}
187
188define i64 @test_phi_multiple_nodes(i1 %c) {
189; CHECK-LABEL: define i64 @test_phi_multiple_nodes(i1 %c) {
190; CHECK: entry:
191; CHECK-NEXT: br i1 %c, label %if, label %join
192; CHECK: if:
193; CHECK-NEXT: br label %phi.constexpr
194; CHECK: phi.constexpr:
195; CHECK-NEXT: %constexpr = ptrtoint ptr @g to i64
196; CHECK-NEXT: %constexpr2 = ptrtoint ptr @g2 to i64
197; CHECK-NEXT: br label %join
198; CHECK: join:
199; CHECK-NEXT: %phi = phi i64 [ 0, %entry ], [ %constexpr, %phi.constexpr ]
200; CHECK-NEXT: %phi2 = phi i64 [ 0, %entry ], [ %constexpr2, %phi.constexpr ]
201; CHECK-NEXT: ret i64 %phi
202entry:
203  br i1 %c, label %if, label %join
204
205if:
206  br label %join
207
208join:
209  %phi = phi i64 [ 0, %entry ], [ ptrtoint (ptr @g to i64), %if ]
210  %phi2 = phi i64 [ 0, %entry ], [ ptrtoint (ptr @g2 to i64), %if ]
211  ret i64 %phi
212}
213
214
215define i64 @test_phi_multiple_identical_predecessors(i32 %x) {
216; CHECK-LABEL: define i64 @test_phi_multiple_identical_predecessors(i32 %x) {
217; CHECK: entry:
218; CHECK-NEXT: switch i32 %x, label %default [
219; CHECK-NEXT:   i32 0, label %phi.constexpr
220; CHECK-NEXT:   i32 1, label %phi.constexpr
221; CHECK-NEXT: ]
222; CHECK: default:
223; CHECK-NEXT: br label %join
224; CHECK: phi.constexpr:
225; CHECK-NEXT: %constexpr = ptrtoint ptr @g to i64
226; CHECK-NEXT: br label %join
227; CHECK: join:
228; CHECK-NEXT: %phi = phi i64 [ %constexpr, %phi.constexpr ], [ %constexpr, %phi.constexpr ], [ 0, %default ]
229; CHECK-NEXT: ret i64 %phi
230entry:
231  switch i32 %x, label %default [
232    i32 0, label %join
233    i32 1, label %join
234  ]
235
236default:
237  br label %join
238
239join:
240  %phi = phi i64 [ ptrtoint (ptr @g to i64), %entry ], [ ptrtoint (ptr @g to i64), %entry ], [ 0, %default ]
241  ret i64 %phi
242}
243