blob: 49ed897fd2ead1af662d352e5ae7cb7b4d0798fa [file] [log] [blame]
Matt Arsenault2639f772014-07-15 00:07:27 +00001; RUN: opt -instcombine -S < %s | FileCheck %s
Chandler Carruth7a98df72015-01-24 04:19:17 +00002; RUN: opt -passes=instcombine -S < %s | FileCheck %s
Matt Arsenault2639f772014-07-15 00:07:27 +00003
Chris Lattnerb75e1e72003-06-26 05:05:51 +00004; This test makes sure that these instructions are properly eliminated.
Matt Arsenault2639f772014-07-15 00:07:27 +00005
Chandler Carruthb778cbc2015-01-22 05:08:12 +00006target datalayout = "e-m:e-p:64:64:64-i64:64-f80:128-n8:16:32:64-S128"
Chris Lattnerb75e1e72003-06-26 05:05:51 +00007
Tanya Lattner6f729d62008-03-25 04:26:08 +00008@X = constant i32 42 ; <i32*> [#uses=2]
9@X2 = constant i32 47 ; <i32*> [#uses=1]
10@Y = constant [2 x { i32, float }] [ { i32, float } { i32 12, float 1.000000e+00 }, { i32, float } { i32 37, float 0x3FF3B2FEC0000000 } ] ; <[2 x { i32, float }]*> [#uses=2]
11@Z = constant [2 x { i32, float }] zeroinitializer ; <[2 x { i32, float }]*> [#uses=1]
Chris Lattnerb75e1e72003-06-26 05:05:51 +000012
Chris Lattner243a73d2010-07-12 00:19:47 +000013@GLOBAL = internal constant [4 x i32] zeroinitializer
14
15
Matt Arsenault2639f772014-07-15 00:07:27 +000016; CHECK-LABEL: @test1(
17; CHECK-NOT: load
Tanya Lattner6f729d62008-03-25 04:26:08 +000018define i32 @test1() {
David Blaikie7c9c6ed2015-02-27 21:17:42 +000019 %B = load i32, i32* @X ; <i32> [#uses=1]
Tanya Lattner6f729d62008-03-25 04:26:08 +000020 ret i32 %B
Chris Lattner8152f5f2004-05-27 17:43:33 +000021}
22
Matt Arsenault2639f772014-07-15 00:07:27 +000023; CHECK-LABEL: @test2(
24; CHECK-NOT: load
Tanya Lattner6f729d62008-03-25 04:26:08 +000025define float @test2() {
David Blaikie198d8ba2015-02-27 19:29:02 +000026 %A = getelementptr [2 x { i32, float }], [2 x { i32, float }]* @Y, i64 0, i64 1, i32 1 ; <float*> [#uses=1]
David Blaikie7c9c6ed2015-02-27 21:17:42 +000027 %B = load float, float* %A ; <float> [#uses=1]
Chris Lattnerb75e1e72003-06-26 05:05:51 +000028 ret float %B
29}
30
Matt Arsenault2639f772014-07-15 00:07:27 +000031; CHECK-LABEL: @test3(
32; CHECK-NOT: load
Tanya Lattner6f729d62008-03-25 04:26:08 +000033define i32 @test3() {
David Blaikie198d8ba2015-02-27 19:29:02 +000034 %A = getelementptr [2 x { i32, float }], [2 x { i32, float }]* @Y, i64 0, i64 0, i32 0 ; <i32*> [#uses=1]
David Blaikie7c9c6ed2015-02-27 21:17:42 +000035 %B = load i32, i32* %A ; <i32> [#uses=1]
Tanya Lattner6f729d62008-03-25 04:26:08 +000036 ret i32 %B
Chris Lattnerb75e1e72003-06-26 05:05:51 +000037}
38
Matt Arsenault2639f772014-07-15 00:07:27 +000039; CHECK-LABEL: @test4(
40; CHECK-NOT: load
Tanya Lattner6f729d62008-03-25 04:26:08 +000041define i32 @test4() {
David Blaikie198d8ba2015-02-27 19:29:02 +000042 %A = getelementptr [2 x { i32, float }], [2 x { i32, float }]* @Z, i64 0, i64 1, i32 0 ; <i32*> [#uses=1]
David Blaikie7c9c6ed2015-02-27 21:17:42 +000043 %B = load i32, i32* %A ; <i32> [#uses=1]
Tanya Lattner6f729d62008-03-25 04:26:08 +000044 ret i32 %B
Chris Lattner3ba30972004-05-27 17:28:55 +000045}
Chris Lattnerb4f5c682004-09-19 18:43:01 +000046
Matt Arsenault2639f772014-07-15 00:07:27 +000047; CHECK-LABEL: @test5(
48; CHECK-NOT: load
Tanya Lattner6f729d62008-03-25 04:26:08 +000049define i32 @test5(i1 %C) {
50 %Y = select i1 %C, i32* @X, i32* @X2 ; <i32*> [#uses=1]
David Blaikie7c9c6ed2015-02-27 21:17:42 +000051 %Z = load i32, i32* %Y ; <i32> [#uses=1]
Tanya Lattner6f729d62008-03-25 04:26:08 +000052 ret i32 %Z
Chris Lattnerb4f5c682004-09-19 18:43:01 +000053}
54
Matt Arsenault2639f772014-07-15 00:07:27 +000055; CHECK-LABEL: @test7(
56; CHECK-NOT: load
Tanya Lattner6f729d62008-03-25 04:26:08 +000057define i32 @test7(i32 %X) {
David Blaikie198d8ba2015-02-27 19:29:02 +000058 %V = getelementptr i32, i32* null, i32 %X ; <i32*> [#uses=1]
David Blaikie7c9c6ed2015-02-27 21:17:42 +000059 %R = load i32, i32* %V ; <i32> [#uses=1]
Tanya Lattner6f729d62008-03-25 04:26:08 +000060 ret i32 %R
Chris Lattner45c2bdd2005-05-01 04:24:15 +000061}
Chris Lattner598fbf72005-09-12 21:59:22 +000062
Matt Arsenault2639f772014-07-15 00:07:27 +000063; CHECK-LABEL: @test8(
64; CHECK-NOT: load
Tanya Lattner6f729d62008-03-25 04:26:08 +000065define i32 @test8(i32* %P) {
66 store i32 1, i32* %P
David Blaikie7c9c6ed2015-02-27 21:17:42 +000067 %X = load i32, i32* %P ; <i32> [#uses=1]
Tanya Lattner6f729d62008-03-25 04:26:08 +000068 ret i32 %X
Chris Lattner598fbf72005-09-12 21:59:22 +000069}
Chris Lattner128a0032005-09-12 22:19:46 +000070
Matt Arsenault2639f772014-07-15 00:07:27 +000071; CHECK-LABEL: @test9(
72; CHECK-NOT: load
Tanya Lattner6f729d62008-03-25 04:26:08 +000073define i32 @test9(i32* %P) {
David Blaikie7c9c6ed2015-02-27 21:17:42 +000074 %X = load i32, i32* %P ; <i32> [#uses=1]
75 %Y = load i32, i32* %P ; <i32> [#uses=1]
Tanya Lattner6f729d62008-03-25 04:26:08 +000076 %Z = sub i32 %X, %Y ; <i32> [#uses=1]
77 ret i32 %Z
Chris Lattner128a0032005-09-12 22:19:46 +000078}
Chris Lattner15cc6082005-09-12 23:22:17 +000079
Matt Arsenault2639f772014-07-15 00:07:27 +000080; CHECK-LABEL: @test10(
81; CHECK-NOT: load
Tanya Lattner6f729d62008-03-25 04:26:08 +000082define i32 @test10(i1 %C.upgrd.1, i32* %P, i32* %Q) {
83 br i1 %C.upgrd.1, label %T, label %F
84T: ; preds = %0
85 store i32 1, i32* %Q
86 store i32 0, i32* %P
Chris Lattner15cc6082005-09-12 23:22:17 +000087 br label %C
Tanya Lattner6f729d62008-03-25 04:26:08 +000088F: ; preds = %0
89 store i32 0, i32* %P
Chris Lattner15cc6082005-09-12 23:22:17 +000090 br label %C
Tanya Lattner6f729d62008-03-25 04:26:08 +000091C: ; preds = %F, %T
David Blaikie7c9c6ed2015-02-27 21:17:42 +000092 %V = load i32, i32* %P ; <i32> [#uses=1]
Tanya Lattner6f729d62008-03-25 04:26:08 +000093 ret i32 %V
Chris Lattner15cc6082005-09-12 23:22:17 +000094}
Dan Gohman2276a7b2008-10-15 23:19:35 +000095
Matt Arsenault2639f772014-07-15 00:07:27 +000096; CHECK-LABEL: @test11(
97; CHECK-NOT: load
Dan Gohman2276a7b2008-10-15 23:19:35 +000098define double @test11(double* %p) {
David Blaikie198d8ba2015-02-27 19:29:02 +000099 %t0 = getelementptr double, double* %p, i32 1
Dan Gohman2276a7b2008-10-15 23:19:35 +0000100 store double 2.0, double* %t0
David Blaikie198d8ba2015-02-27 19:29:02 +0000101 %t1 = getelementptr double, double* %p, i32 1
David Blaikie7c9c6ed2015-02-27 21:17:42 +0000102 %x = load double, double* %t1
Dan Gohman2276a7b2008-10-15 23:19:35 +0000103 ret double %x
104}
Chris Lattnera8f3ebb2010-01-05 21:32:59 +0000105
Matt Arsenault2639f772014-07-15 00:07:27 +0000106; CHECK-LABEL: @test12(
107; CHECK-NOT: load
Chris Lattnera8f3ebb2010-01-05 21:32:59 +0000108define i32 @test12(i32* %P) {
Matt Arsenault2639f772014-07-15 00:07:27 +0000109 %A = alloca i32
110 store i32 123, i32* %A
111 ; Cast the result of the load not the source
112 %Q = bitcast i32* %A to i32*
David Blaikie7c9c6ed2015-02-27 21:17:42 +0000113 %V = load i32, i32* %Q
Matt Arsenault2639f772014-07-15 00:07:27 +0000114 ret i32 %V
Chris Lattnera8f3ebb2010-01-05 21:32:59 +0000115}
Chris Lattner243a73d2010-07-12 00:19:47 +0000116
Matt Arsenault2639f772014-07-15 00:07:27 +0000117; CHECK-LABEL: @test13(
118; CHECK-NOT: load
Chris Lattner243a73d2010-07-12 00:19:47 +0000119define <16 x i8> @test13(<2 x i64> %x) {
David Blaikie7c9c6ed2015-02-27 21:17:42 +0000120 %tmp = load <16 x i8>, <16 x i8>* bitcast ([4 x i32]* @GLOBAL to <16 x i8>*)
Matt Arsenault2639f772014-07-15 00:07:27 +0000121 ret <16 x i8> %tmp
Chris Lattner243a73d2010-07-12 00:19:47 +0000122}
Chandler Carruth3ac929c2014-10-20 10:03:01 +0000123
124define i8 @test14(i8 %x, i32 %y) {
125; This test must not have the store of %x forwarded to the load -- there is an
126; intervening store if %y. However, the intervening store occurs with a different
127; type and size and to a different pointer value. This is ensuring that none of
128; those confuse the analysis into thinking that the second store does not alias
129; the first.
130; CHECK-LABEL: @test14(
David Blaikie7c9c6ed2015-02-27 21:17:42 +0000131; CHECK: %[[R:.*]] = load i8, i8*
Chandler Carruth3ac929c2014-10-20 10:03:01 +0000132; CHECK-NEXT: ret i8 %[[R]]
133 %a = alloca i32
134 %a.i8 = bitcast i32* %a to i8*
135 store i8 %x, i8* %a.i8
136 store i32 %y, i32* %a
David Blaikie7c9c6ed2015-02-27 21:17:42 +0000137 %r = load i8, i8* %a.i8
Chandler Carruth3ac929c2014-10-20 10:03:01 +0000138 ret i8 %r
139}
140
141@test15_global = external global i32
142
143define i8 @test15(i8 %x, i32 %y) {
144; Same test as @test14 essentially, but using a global instead of an alloca.
145; CHECK-LABEL: @test15(
David Blaikie7c9c6ed2015-02-27 21:17:42 +0000146; CHECK: %[[R:.*]] = load i8, i8*
Chandler Carruth3ac929c2014-10-20 10:03:01 +0000147; CHECK-NEXT: ret i8 %[[R]]
148 %g.i8 = bitcast i32* @test15_global to i8*
149 store i8 %x, i8* %g.i8
150 store i32 %y, i32* @test15_global
David Blaikie7c9c6ed2015-02-27 21:17:42 +0000151 %r = load i8, i8* %g.i8
Chandler Carruth3ac929c2014-10-20 10:03:01 +0000152 ret i8 %r
153}
Chandler Carruthb778cbc2015-01-22 05:08:12 +0000154
155define void @test16(i8* %x, i8* %a, i8* %b, i8* %c) {
156; Check that we canonicalize loads which are only stored to use integer types
157; when there is a valid integer type.
158; CHECK-LABEL: @test16(
David Blaikie7c9c6ed2015-02-27 21:17:42 +0000159; CHECK: %[[L1:.*]] = load i32, i32*
Chandler Carruthb778cbc2015-01-22 05:08:12 +0000160; CHECK-NOT: load
161; CHECK: store i32 %[[L1]], i32*
162; CHECK: store i32 %[[L1]], i32*
163; CHECK-NOT: store
David Blaikie7c9c6ed2015-02-27 21:17:42 +0000164; CHECK: %[[L1:.*]] = load i32, i32*
Chandler Carruthb778cbc2015-01-22 05:08:12 +0000165; CHECK-NOT: load
166; CHECK: store i32 %[[L1]], i32*
167; CHECK: store i32 %[[L1]], i32*
168; CHECK-NOT: store
169; CHECK: ret
170
171entry:
172 %x.cast = bitcast i8* %x to float*
173 %a.cast = bitcast i8* %a to float*
174 %b.cast = bitcast i8* %b to float*
175 %c.cast = bitcast i8* %c to i32*
176
David Blaikie7c9c6ed2015-02-27 21:17:42 +0000177 %x1 = load float, float* %x.cast
Chandler Carruthb778cbc2015-01-22 05:08:12 +0000178 store float %x1, float* %a.cast
179 store float %x1, float* %b.cast
180
David Blaikie7c9c6ed2015-02-27 21:17:42 +0000181 %x2 = load float, float* %x.cast
Chandler Carruthb778cbc2015-01-22 05:08:12 +0000182 store float %x2, float* %b.cast
183 %x2.cast = bitcast float %x2 to i32
184 store i32 %x2.cast, i32* %c.cast
185
186 ret void
187}
188
189define void @test17(i8** %x, i8 %y) {
190; Check that in cases similar to @test16 we don't try to rewrite a load when
191; its only use is a store but it is used as the pointer to that store rather
192; than the value.
193;
194; CHECK-LABEL: @test17(
David Blaikie7c9c6ed2015-02-27 21:17:42 +0000195; CHECK: %[[L:.*]] = load i8*, i8**
Chandler Carruthb778cbc2015-01-22 05:08:12 +0000196; CHECK: store i8 %y, i8* %[[L]]
197
198entry:
David Blaikie7c9c6ed2015-02-27 21:17:42 +0000199 %x.load = load i8*, i8** %x
Chandler Carruthb778cbc2015-01-22 05:08:12 +0000200 store i8 %y, i8* %x.load
201
202 ret void
203}
Arnold Schwaighofer17648b32016-09-10 18:14:57 +0000204
205; Check that we don't try change the type of the load by inserting a bitcast
206; generating invalid IR.
207; CHECK-LABEL: @test18(
208; CHECK-NOT: bitcast
209; CHECK: ret
210%swift.error = type opaque
211declare void @useSwiftError(%swift.error** swifterror)
212
213define void @test18(%swift.error** swifterror %err) {
214entry:
215 %swifterror = alloca swifterror %swift.error*, align 8
216 store %swift.error* null, %swift.error** %swifterror, align 8
217 call void @useSwiftError(%swift.error** nonnull swifterror %swifterror)
218 %err.res = load %swift.error*, %swift.error** %swifterror, align 8
219 store %swift.error* %err.res, %swift.error** %err, align 8
220 ret void
221}
Arnold Schwaighoferb7794352017-01-31 17:53:49 +0000222
223; Make sure we preseve the type of the store to a swifterror pointer.
224; CHECK-LABEL: @test19(
225; CHECK: [[A:%.*]] = alloca
226; CHECK: call
227; CHECK: [[BC:%.*]] = bitcast i8** [[A]] to
228; CHECK: [[ERRVAL:%.*]] = load {{.*}}[[BC]]
229; CHECK: store {{.*}}[[ERRVAL]]
230; CHECK: ret
231declare void @initi8(i8**)
232define void @test19(%swift.error** swifterror %err) {
233entry:
234 %tmp = alloca i8*, align 8
235 call void @initi8(i8** %tmp)
236 %swifterror = bitcast i8** %tmp to %swift.error**
237 %err.res = load %swift.error*, %swift.error** %swifterror, align 8
238 store %swift.error* %err.res, %swift.error** %err, align 8
239 ret void
240}