Matt Arsenault | 2639f77 | 2014-07-15 00:07:27 +0000 | [diff] [blame] | 1 | ; RUN: opt -instcombine -S < %s | FileCheck %s |
Chandler Carruth | 7a98df7 | 2015-01-24 04:19:17 +0000 | [diff] [blame] | 2 | ; RUN: opt -passes=instcombine -S < %s | FileCheck %s |
Matt Arsenault | 2639f77 | 2014-07-15 00:07:27 +0000 | [diff] [blame] | 3 | |
Chris Lattner | b75e1e7 | 2003-06-26 05:05:51 +0000 | [diff] [blame] | 4 | ; This test makes sure that these instructions are properly eliminated. |
Matt Arsenault | 2639f77 | 2014-07-15 00:07:27 +0000 | [diff] [blame] | 5 | |
Chandler Carruth | b778cbc | 2015-01-22 05:08:12 +0000 | [diff] [blame] | 6 | target datalayout = "e-m:e-p:64:64:64-i64:64-f80:128-n8:16:32:64-S128" |
Chris Lattner | b75e1e7 | 2003-06-26 05:05:51 +0000 | [diff] [blame] | 7 | |
Tanya Lattner | 6f729d6 | 2008-03-25 04:26:08 +0000 | [diff] [blame] | 8 | @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 Lattner | b75e1e7 | 2003-06-26 05:05:51 +0000 | [diff] [blame] | 12 | |
Chris Lattner | 243a73d | 2010-07-12 00:19:47 +0000 | [diff] [blame] | 13 | @GLOBAL = internal constant [4 x i32] zeroinitializer |
| 14 | |
| 15 | |
Matt Arsenault | 2639f77 | 2014-07-15 00:07:27 +0000 | [diff] [blame] | 16 | ; CHECK-LABEL: @test1( |
| 17 | ; CHECK-NOT: load |
Tanya Lattner | 6f729d6 | 2008-03-25 04:26:08 +0000 | [diff] [blame] | 18 | define i32 @test1() { |
David Blaikie | 7c9c6ed | 2015-02-27 21:17:42 +0000 | [diff] [blame] | 19 | %B = load i32, i32* @X ; <i32> [#uses=1] |
Tanya Lattner | 6f729d6 | 2008-03-25 04:26:08 +0000 | [diff] [blame] | 20 | ret i32 %B |
Chris Lattner | 8152f5f | 2004-05-27 17:43:33 +0000 | [diff] [blame] | 21 | } |
| 22 | |
Matt Arsenault | 2639f77 | 2014-07-15 00:07:27 +0000 | [diff] [blame] | 23 | ; CHECK-LABEL: @test2( |
| 24 | ; CHECK-NOT: load |
Tanya Lattner | 6f729d6 | 2008-03-25 04:26:08 +0000 | [diff] [blame] | 25 | define float @test2() { |
David Blaikie | 198d8ba | 2015-02-27 19:29:02 +0000 | [diff] [blame] | 26 | %A = getelementptr [2 x { i32, float }], [2 x { i32, float }]* @Y, i64 0, i64 1, i32 1 ; <float*> [#uses=1] |
David Blaikie | 7c9c6ed | 2015-02-27 21:17:42 +0000 | [diff] [blame] | 27 | %B = load float, float* %A ; <float> [#uses=1] |
Chris Lattner | b75e1e7 | 2003-06-26 05:05:51 +0000 | [diff] [blame] | 28 | ret float %B |
| 29 | } |
| 30 | |
Matt Arsenault | 2639f77 | 2014-07-15 00:07:27 +0000 | [diff] [blame] | 31 | ; CHECK-LABEL: @test3( |
| 32 | ; CHECK-NOT: load |
Tanya Lattner | 6f729d6 | 2008-03-25 04:26:08 +0000 | [diff] [blame] | 33 | define i32 @test3() { |
David Blaikie | 198d8ba | 2015-02-27 19:29:02 +0000 | [diff] [blame] | 34 | %A = getelementptr [2 x { i32, float }], [2 x { i32, float }]* @Y, i64 0, i64 0, i32 0 ; <i32*> [#uses=1] |
David Blaikie | 7c9c6ed | 2015-02-27 21:17:42 +0000 | [diff] [blame] | 35 | %B = load i32, i32* %A ; <i32> [#uses=1] |
Tanya Lattner | 6f729d6 | 2008-03-25 04:26:08 +0000 | [diff] [blame] | 36 | ret i32 %B |
Chris Lattner | b75e1e7 | 2003-06-26 05:05:51 +0000 | [diff] [blame] | 37 | } |
| 38 | |
Matt Arsenault | 2639f77 | 2014-07-15 00:07:27 +0000 | [diff] [blame] | 39 | ; CHECK-LABEL: @test4( |
| 40 | ; CHECK-NOT: load |
Tanya Lattner | 6f729d6 | 2008-03-25 04:26:08 +0000 | [diff] [blame] | 41 | define i32 @test4() { |
David Blaikie | 198d8ba | 2015-02-27 19:29:02 +0000 | [diff] [blame] | 42 | %A = getelementptr [2 x { i32, float }], [2 x { i32, float }]* @Z, i64 0, i64 1, i32 0 ; <i32*> [#uses=1] |
David Blaikie | 7c9c6ed | 2015-02-27 21:17:42 +0000 | [diff] [blame] | 43 | %B = load i32, i32* %A ; <i32> [#uses=1] |
Tanya Lattner | 6f729d6 | 2008-03-25 04:26:08 +0000 | [diff] [blame] | 44 | ret i32 %B |
Chris Lattner | 3ba3097 | 2004-05-27 17:28:55 +0000 | [diff] [blame] | 45 | } |
Chris Lattner | b4f5c68 | 2004-09-19 18:43:01 +0000 | [diff] [blame] | 46 | |
Matt Arsenault | 2639f77 | 2014-07-15 00:07:27 +0000 | [diff] [blame] | 47 | ; CHECK-LABEL: @test5( |
| 48 | ; CHECK-NOT: load |
Tanya Lattner | 6f729d6 | 2008-03-25 04:26:08 +0000 | [diff] [blame] | 49 | define i32 @test5(i1 %C) { |
| 50 | %Y = select i1 %C, i32* @X, i32* @X2 ; <i32*> [#uses=1] |
David Blaikie | 7c9c6ed | 2015-02-27 21:17:42 +0000 | [diff] [blame] | 51 | %Z = load i32, i32* %Y ; <i32> [#uses=1] |
Tanya Lattner | 6f729d6 | 2008-03-25 04:26:08 +0000 | [diff] [blame] | 52 | ret i32 %Z |
Chris Lattner | b4f5c68 | 2004-09-19 18:43:01 +0000 | [diff] [blame] | 53 | } |
| 54 | |
Matt Arsenault | 2639f77 | 2014-07-15 00:07:27 +0000 | [diff] [blame] | 55 | ; CHECK-LABEL: @test7( |
| 56 | ; CHECK-NOT: load |
Tanya Lattner | 6f729d6 | 2008-03-25 04:26:08 +0000 | [diff] [blame] | 57 | define i32 @test7(i32 %X) { |
David Blaikie | 198d8ba | 2015-02-27 19:29:02 +0000 | [diff] [blame] | 58 | %V = getelementptr i32, i32* null, i32 %X ; <i32*> [#uses=1] |
David Blaikie | 7c9c6ed | 2015-02-27 21:17:42 +0000 | [diff] [blame] | 59 | %R = load i32, i32* %V ; <i32> [#uses=1] |
Tanya Lattner | 6f729d6 | 2008-03-25 04:26:08 +0000 | [diff] [blame] | 60 | ret i32 %R |
Chris Lattner | 45c2bdd | 2005-05-01 04:24:15 +0000 | [diff] [blame] | 61 | } |
Chris Lattner | 598fbf7 | 2005-09-12 21:59:22 +0000 | [diff] [blame] | 62 | |
Matt Arsenault | 2639f77 | 2014-07-15 00:07:27 +0000 | [diff] [blame] | 63 | ; CHECK-LABEL: @test8( |
| 64 | ; CHECK-NOT: load |
Tanya Lattner | 6f729d6 | 2008-03-25 04:26:08 +0000 | [diff] [blame] | 65 | define i32 @test8(i32* %P) { |
| 66 | store i32 1, i32* %P |
David Blaikie | 7c9c6ed | 2015-02-27 21:17:42 +0000 | [diff] [blame] | 67 | %X = load i32, i32* %P ; <i32> [#uses=1] |
Tanya Lattner | 6f729d6 | 2008-03-25 04:26:08 +0000 | [diff] [blame] | 68 | ret i32 %X |
Chris Lattner | 598fbf7 | 2005-09-12 21:59:22 +0000 | [diff] [blame] | 69 | } |
Chris Lattner | 128a003 | 2005-09-12 22:19:46 +0000 | [diff] [blame] | 70 | |
Matt Arsenault | 2639f77 | 2014-07-15 00:07:27 +0000 | [diff] [blame] | 71 | ; CHECK-LABEL: @test9( |
| 72 | ; CHECK-NOT: load |
Tanya Lattner | 6f729d6 | 2008-03-25 04:26:08 +0000 | [diff] [blame] | 73 | define i32 @test9(i32* %P) { |
David Blaikie | 7c9c6ed | 2015-02-27 21:17:42 +0000 | [diff] [blame] | 74 | %X = load i32, i32* %P ; <i32> [#uses=1] |
| 75 | %Y = load i32, i32* %P ; <i32> [#uses=1] |
Tanya Lattner | 6f729d6 | 2008-03-25 04:26:08 +0000 | [diff] [blame] | 76 | %Z = sub i32 %X, %Y ; <i32> [#uses=1] |
| 77 | ret i32 %Z |
Chris Lattner | 128a003 | 2005-09-12 22:19:46 +0000 | [diff] [blame] | 78 | } |
Chris Lattner | 15cc608 | 2005-09-12 23:22:17 +0000 | [diff] [blame] | 79 | |
Matt Arsenault | 2639f77 | 2014-07-15 00:07:27 +0000 | [diff] [blame] | 80 | ; CHECK-LABEL: @test10( |
| 81 | ; CHECK-NOT: load |
Tanya Lattner | 6f729d6 | 2008-03-25 04:26:08 +0000 | [diff] [blame] | 82 | define i32 @test10(i1 %C.upgrd.1, i32* %P, i32* %Q) { |
| 83 | br i1 %C.upgrd.1, label %T, label %F |
| 84 | T: ; preds = %0 |
| 85 | store i32 1, i32* %Q |
| 86 | store i32 0, i32* %P |
Chris Lattner | 15cc608 | 2005-09-12 23:22:17 +0000 | [diff] [blame] | 87 | br label %C |
Tanya Lattner | 6f729d6 | 2008-03-25 04:26:08 +0000 | [diff] [blame] | 88 | F: ; preds = %0 |
| 89 | store i32 0, i32* %P |
Chris Lattner | 15cc608 | 2005-09-12 23:22:17 +0000 | [diff] [blame] | 90 | br label %C |
Tanya Lattner | 6f729d6 | 2008-03-25 04:26:08 +0000 | [diff] [blame] | 91 | C: ; preds = %F, %T |
David Blaikie | 7c9c6ed | 2015-02-27 21:17:42 +0000 | [diff] [blame] | 92 | %V = load i32, i32* %P ; <i32> [#uses=1] |
Tanya Lattner | 6f729d6 | 2008-03-25 04:26:08 +0000 | [diff] [blame] | 93 | ret i32 %V |
Chris Lattner | 15cc608 | 2005-09-12 23:22:17 +0000 | [diff] [blame] | 94 | } |
Dan Gohman | 2276a7b | 2008-10-15 23:19:35 +0000 | [diff] [blame] | 95 | |
Matt Arsenault | 2639f77 | 2014-07-15 00:07:27 +0000 | [diff] [blame] | 96 | ; CHECK-LABEL: @test11( |
| 97 | ; CHECK-NOT: load |
Dan Gohman | 2276a7b | 2008-10-15 23:19:35 +0000 | [diff] [blame] | 98 | define double @test11(double* %p) { |
David Blaikie | 198d8ba | 2015-02-27 19:29:02 +0000 | [diff] [blame] | 99 | %t0 = getelementptr double, double* %p, i32 1 |
Dan Gohman | 2276a7b | 2008-10-15 23:19:35 +0000 | [diff] [blame] | 100 | store double 2.0, double* %t0 |
David Blaikie | 198d8ba | 2015-02-27 19:29:02 +0000 | [diff] [blame] | 101 | %t1 = getelementptr double, double* %p, i32 1 |
David Blaikie | 7c9c6ed | 2015-02-27 21:17:42 +0000 | [diff] [blame] | 102 | %x = load double, double* %t1 |
Dan Gohman | 2276a7b | 2008-10-15 23:19:35 +0000 | [diff] [blame] | 103 | ret double %x |
| 104 | } |
Chris Lattner | a8f3ebb | 2010-01-05 21:32:59 +0000 | [diff] [blame] | 105 | |
Matt Arsenault | 2639f77 | 2014-07-15 00:07:27 +0000 | [diff] [blame] | 106 | ; CHECK-LABEL: @test12( |
| 107 | ; CHECK-NOT: load |
Chris Lattner | a8f3ebb | 2010-01-05 21:32:59 +0000 | [diff] [blame] | 108 | define i32 @test12(i32* %P) { |
Matt Arsenault | 2639f77 | 2014-07-15 00:07:27 +0000 | [diff] [blame] | 109 | %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 Blaikie | 7c9c6ed | 2015-02-27 21:17:42 +0000 | [diff] [blame] | 113 | %V = load i32, i32* %Q |
Matt Arsenault | 2639f77 | 2014-07-15 00:07:27 +0000 | [diff] [blame] | 114 | ret i32 %V |
Chris Lattner | a8f3ebb | 2010-01-05 21:32:59 +0000 | [diff] [blame] | 115 | } |
Chris Lattner | 243a73d | 2010-07-12 00:19:47 +0000 | [diff] [blame] | 116 | |
Matt Arsenault | 2639f77 | 2014-07-15 00:07:27 +0000 | [diff] [blame] | 117 | ; CHECK-LABEL: @test13( |
| 118 | ; CHECK-NOT: load |
Chris Lattner | 243a73d | 2010-07-12 00:19:47 +0000 | [diff] [blame] | 119 | define <16 x i8> @test13(<2 x i64> %x) { |
David Blaikie | 7c9c6ed | 2015-02-27 21:17:42 +0000 | [diff] [blame] | 120 | %tmp = load <16 x i8>, <16 x i8>* bitcast ([4 x i32]* @GLOBAL to <16 x i8>*) |
Matt Arsenault | 2639f77 | 2014-07-15 00:07:27 +0000 | [diff] [blame] | 121 | ret <16 x i8> %tmp |
Chris Lattner | 243a73d | 2010-07-12 00:19:47 +0000 | [diff] [blame] | 122 | } |
Chandler Carruth | 3ac929c | 2014-10-20 10:03:01 +0000 | [diff] [blame] | 123 | |
| 124 | define 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 Blaikie | 7c9c6ed | 2015-02-27 21:17:42 +0000 | [diff] [blame] | 131 | ; CHECK: %[[R:.*]] = load i8, i8* |
Chandler Carruth | 3ac929c | 2014-10-20 10:03:01 +0000 | [diff] [blame] | 132 | ; 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 Blaikie | 7c9c6ed | 2015-02-27 21:17:42 +0000 | [diff] [blame] | 137 | %r = load i8, i8* %a.i8 |
Chandler Carruth | 3ac929c | 2014-10-20 10:03:01 +0000 | [diff] [blame] | 138 | ret i8 %r |
| 139 | } |
| 140 | |
| 141 | @test15_global = external global i32 |
| 142 | |
| 143 | define 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 Blaikie | 7c9c6ed | 2015-02-27 21:17:42 +0000 | [diff] [blame] | 146 | ; CHECK: %[[R:.*]] = load i8, i8* |
Chandler Carruth | 3ac929c | 2014-10-20 10:03:01 +0000 | [diff] [blame] | 147 | ; 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 Blaikie | 7c9c6ed | 2015-02-27 21:17:42 +0000 | [diff] [blame] | 151 | %r = load i8, i8* %g.i8 |
Chandler Carruth | 3ac929c | 2014-10-20 10:03:01 +0000 | [diff] [blame] | 152 | ret i8 %r |
| 153 | } |
Chandler Carruth | b778cbc | 2015-01-22 05:08:12 +0000 | [diff] [blame] | 154 | |
| 155 | define 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 Blaikie | 7c9c6ed | 2015-02-27 21:17:42 +0000 | [diff] [blame] | 159 | ; CHECK: %[[L1:.*]] = load i32, i32* |
Chandler Carruth | b778cbc | 2015-01-22 05:08:12 +0000 | [diff] [blame] | 160 | ; CHECK-NOT: load |
| 161 | ; CHECK: store i32 %[[L1]], i32* |
| 162 | ; CHECK: store i32 %[[L1]], i32* |
| 163 | ; CHECK-NOT: store |
David Blaikie | 7c9c6ed | 2015-02-27 21:17:42 +0000 | [diff] [blame] | 164 | ; CHECK: %[[L1:.*]] = load i32, i32* |
Chandler Carruth | b778cbc | 2015-01-22 05:08:12 +0000 | [diff] [blame] | 165 | ; CHECK-NOT: load |
| 166 | ; CHECK: store i32 %[[L1]], i32* |
| 167 | ; CHECK: store i32 %[[L1]], i32* |
| 168 | ; CHECK-NOT: store |
| 169 | ; CHECK: ret |
| 170 | |
| 171 | entry: |
| 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 Blaikie | 7c9c6ed | 2015-02-27 21:17:42 +0000 | [diff] [blame] | 177 | %x1 = load float, float* %x.cast |
Chandler Carruth | b778cbc | 2015-01-22 05:08:12 +0000 | [diff] [blame] | 178 | store float %x1, float* %a.cast |
| 179 | store float %x1, float* %b.cast |
| 180 | |
David Blaikie | 7c9c6ed | 2015-02-27 21:17:42 +0000 | [diff] [blame] | 181 | %x2 = load float, float* %x.cast |
Chandler Carruth | b778cbc | 2015-01-22 05:08:12 +0000 | [diff] [blame] | 182 | 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 | |
| 189 | define 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 Blaikie | 7c9c6ed | 2015-02-27 21:17:42 +0000 | [diff] [blame] | 195 | ; CHECK: %[[L:.*]] = load i8*, i8** |
Chandler Carruth | b778cbc | 2015-01-22 05:08:12 +0000 | [diff] [blame] | 196 | ; CHECK: store i8 %y, i8* %[[L]] |
| 197 | |
| 198 | entry: |
David Blaikie | 7c9c6ed | 2015-02-27 21:17:42 +0000 | [diff] [blame] | 199 | %x.load = load i8*, i8** %x |
Chandler Carruth | b778cbc | 2015-01-22 05:08:12 +0000 | [diff] [blame] | 200 | store i8 %y, i8* %x.load |
| 201 | |
| 202 | ret void |
| 203 | } |
Arnold Schwaighofer | 17648b3 | 2016-09-10 18:14:57 +0000 | [diff] [blame] | 204 | |
| 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 |
| 211 | declare void @useSwiftError(%swift.error** swifterror) |
| 212 | |
| 213 | define void @test18(%swift.error** swifterror %err) { |
| 214 | entry: |
| 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 Schwaighofer | b779435 | 2017-01-31 17:53:49 +0000 | [diff] [blame^] | 222 | |
| 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 |
| 231 | declare void @initi8(i8**) |
| 232 | define void @test19(%swift.error** swifterror %err) { |
| 233 | entry: |
| 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 | } |