1 ; RUN: opt < %s -S -early-cse | FileCheck %s 2 3 ; CHECK-LABEL: @test12( 4 define i32 @test12(i1 %B, i32* %P1, i32* %P2) { 5 %load0 = load i32, i32* %P1 6 %1 = load atomic i32, i32* %P2 seq_cst, align 4 7 %load1 = load i32, i32* %P1 8 %sel = select i1 %B, i32 %load0, i32 %load1 9 ret i32 %sel 10 ; CHECK: load i32, i32* %P1 11 ; CHECK: load i32, i32* %P1 12 } 13 14 ; CHECK-LABEL: @test13( 15 ; atomic to non-atomic forwarding is legal 16 define i32 @test13(i1 %B, i32* %P1) { 17 %a = load atomic i32, i32* %P1 seq_cst, align 4 18 %b = load i32, i32* %P1 19 %res = sub i32 %a, %b 20 ret i32 %res 21 ; CHECK: load atomic i32, i32* %P1 22 ; CHECK: ret i32 0 23 } 24 25 ; CHECK-LABEL: @test14( 26 ; atomic to unordered atomic forwarding is legal 27 define i32 @test14(i1 %B, i32* %P1) { 28 %a = load atomic i32, i32* %P1 seq_cst, align 4 29 %b = load atomic i32, i32* %P1 unordered, align 4 30 %res = sub i32 %a, %b 31 ret i32 %res 32 ; CHECK: load atomic i32, i32* %P1 seq_cst 33 ; CHECK-NEXT: ret i32 0 34 } 35 36 ; CHECK-LABEL: @test15( 37 ; implementation restriction: can't forward to stonger 38 ; than unordered 39 define i32 @test15(i1 %B, i32* %P1, i32* %P2) { 40 %a = load atomic i32, i32* %P1 seq_cst, align 4 41 %b = load atomic i32, i32* %P1 seq_cst, align 4 42 %res = sub i32 %a, %b 43 ret i32 %res 44 ; CHECK: load atomic i32, i32* %P1 45 ; CHECK: load atomic i32, i32* %P1 46 } 47 48 ; CHECK-LABEL: @test16( 49 ; forwarding non-atomic to atomic is wrong! (However, 50 ; it would be legal to use the later value in place of the 51 ; former in this particular example. We just don't 52 ; do that right now.) 53 define i32 @test16(i1 %B, i32* %P1, i32* %P2) { 54 %a = load i32, i32* %P1, align 4 55 %b = load atomic i32, i32* %P1 unordered, align 4 56 %res = sub i32 %a, %b 57 ret i32 %res 58 ; CHECK: load i32, i32* %P1 59 ; CHECK: load atomic i32, i32* %P1 60 } 61 62 ; Can't DSE across a full fence 63 define void @fence_seq_cst_store(i1 %B, i32* %P1, i32* %P2) { 64 ; CHECK-LABEL: @fence_seq_cst_store 65 ; CHECK: store 66 ; CHECK: store atomic 67 ; CHECK: store 68 store i32 0, i32* %P1, align 4 69 store atomic i32 0, i32* %P2 seq_cst, align 4 70 store i32 0, i32* %P1, align 4 71 ret void 72 } 73 74 ; Can't DSE across a full fence 75 define void @fence_seq_cst(i1 %B, i32* %P1, i32* %P2) { 76 ; CHECK-LABEL: @fence_seq_cst 77 ; CHECK: store 78 ; CHECK: fence seq_cst 79 ; CHECK: store 80 store i32 0, i32* %P1, align 4 81 fence seq_cst 82 store i32 0, i32* %P1, align 4 83 ret void 84 } 85 86 ; Can't DSE across a full fence 87 define void @fence_asm_sideeffect(i1 %B, i32* %P1, i32* %P2) { 88 ; CHECK-LABEL: @fence_asm_sideeffect 89 ; CHECK: store 90 ; CHECK: call void asm sideeffect 91 ; CHECK: store 92 store i32 0, i32* %P1, align 4 93 call void asm sideeffect "", ""() 94 store i32 0, i32* %P1, align 4 95 ret void 96 } 97 98 ; Can't DSE across a full fence 99 define void @fence_asm_memory(i1 %B, i32* %P1, i32* %P2) { 100 ; CHECK-LABEL: @fence_asm_memory 101 ; CHECK: store 102 ; CHECK: call void asm 103 ; CHECK: store 104 store i32 0, i32* %P1, align 4 105 call void asm "", "~{memory}"() 106 store i32 0, i32* %P1, align 4 107 ret void 108 } 109 110 ; Can't remove a volatile load 111 define i32 @volatile_load(i1 %B, i32* %P1, i32* %P2) { 112 %a = load i32, i32* %P1, align 4 113 %b = load volatile i32, i32* %P1, align 4 114 %res = sub i32 %a, %b 115 ret i32 %res 116 ; CHECK-LABEL: @volatile_load 117 ; CHECK: load i32, i32* %P1 118 ; CHECK: load volatile i32, i32* %P1 119 } 120 121 ; Can't remove redundant volatile loads 122 define i32 @redundant_volatile_load(i1 %B, i32* %P1, i32* %P2) { 123 %a = load volatile i32, i32* %P1, align 4 124 %b = load volatile i32, i32* %P1, align 4 125 %res = sub i32 %a, %b 126 ret i32 %res 127 ; CHECK-LABEL: @redundant_volatile_load 128 ; CHECK: load volatile i32, i32* %P1 129 ; CHECK: load volatile i32, i32* %P1 130 ; CHECK: sub 131 } 132 133 ; Can't DSE a volatile store 134 define void @volatile_store(i1 %B, i32* %P1, i32* %P2) { 135 ; CHECK-LABEL: @volatile_store 136 ; CHECK: store volatile 137 ; CHECK: store 138 store volatile i32 0, i32* %P1, align 4 139 store i32 3, i32* %P1, align 4 140 ret void 141 } 142 143 ; Can't DSE a redundant volatile store 144 define void @redundant_volatile_store(i1 %B, i32* %P1, i32* %P2) { 145 ; CHECK-LABEL: @redundant_volatile_store 146 ; CHECK: store volatile 147 ; CHECK: store volatile 148 store volatile i32 0, i32* %P1, align 4 149 store volatile i32 0, i32* %P1, align 4 150 ret void 151 } 152 153 ; Can value forward from volatiles 154 define i32 @test20(i1 %B, i32* %P1, i32* %P2) { 155 %a = load volatile i32, i32* %P1, align 4 156 %b = load i32, i32* %P1, align 4 157 %res = sub i32 %a, %b 158 ret i32 %res 159 ; CHECK-LABEL: @test20 160 ; CHECK: load volatile i32, i32* %P1 161 ; CHECK: ret i32 0 162 } 163 164 ; Can DSE a non-volatile store in favor of a volatile one 165 ; currently a missed optimization 166 define void @test21(i1 %B, i32* %P1, i32* %P2) { 167 ; CHECK-LABEL: @test21 168 ; CHECK: store 169 ; CHECK: store volatile 170 store i32 0, i32* %P1, align 4 171 store volatile i32 3, i32* %P1, align 4 172 ret void 173 } 174 175 ; Can DSE a normal store in favor of a unordered one 176 define void @test22(i1 %B, i32* %P1, i32* %P2) { 177 ; CHECK-LABEL: @test22 178 ; CHECK-NEXT: store atomic 179 store i32 0, i32* %P1, align 4 180 store atomic i32 3, i32* %P1 unordered, align 4 181 ret void 182 } 183 184 ; Can also DSE a unordered store in favor of a normal one 185 define void @test23(i1 %B, i32* %P1, i32* %P2) { 186 ; CHECK-LABEL: @test23 187 ; CHECK-NEXT: store i32 0 188 store atomic i32 3, i32* %P1 unordered, align 4 189 store i32 0, i32* %P1, align 4 190 ret void 191 } 192 193 ; As an implementation limitation, can't remove ordered stores 194 ; Note that we could remove the earlier store if we could 195 ; represent the required ordering. 196 define void @test24(i1 %B, i32* %P1, i32* %P2) { 197 ; CHECK-LABEL: @test24 198 ; CHECK-NEXT: store atomic 199 ; CHECK-NEXT: store i32 0 200 store atomic i32 3, i32* %P1 release, align 4 201 store i32 0, i32* %P1, align 4 202 ret void 203 } 204 205 ; Can't remove volatile stores - each is independently observable and 206 ; the count of such stores is an observable program side effect. 207 define void @test25(i1 %B, i32* %P1, i32* %P2) { 208 ; CHECK-LABEL: @test25 209 ; CHECK-NEXT: store volatile 210 ; CHECK-NEXT: store volatile 211 store volatile i32 3, i32* %P1, align 4 212 store volatile i32 0, i32* %P1, align 4 213 ret void 214 } 215 216 ; Can DSE a unordered store in favor of a unordered one 217 define void @test26(i1 %B, i32* %P1, i32* %P2) { 218 ; CHECK-LABEL: @test26 219 ; CHECK-NEXT: store atomic i32 3, i32* %P1 unordered, align 4 220 ; CHECK-NEXT: ret 221 store atomic i32 0, i32* %P1 unordered, align 4 222 store atomic i32 3, i32* %P1 unordered, align 4 223 ret void 224 } 225 226 ; Can DSE a unordered store in favor of a ordered one, 227 ; but current don't due to implementation limits 228 define void @test27(i1 %B, i32* %P1, i32* %P2) { 229 ; CHECK-LABEL: @test27 230 ; CHECK-NEXT: store atomic i32 0, i32* %P1 unordered, align 4 231 ; CHECK-NEXT: store atomic i32 3, i32* %P1 release, align 4 232 ; CHECK-NEXT: ret 233 store atomic i32 0, i32* %P1 unordered, align 4 234 store atomic i32 3, i32* %P1 release, align 4 235 ret void 236 } 237 238 ; Can DSE an unordered atomic store in favor of an 239 ; ordered one, but current don't due to implementation limits 240 define void @test28(i1 %B, i32* %P1, i32* %P2) { 241 ; CHECK-LABEL: @test28 242 ; CHECK-NEXT: store atomic i32 0, i32* %P1 unordered, align 4 243 ; CHECK-NEXT: store atomic i32 3, i32* %P1 release, align 4 244 ; CHECK-NEXT: ret 245 store atomic i32 0, i32* %P1 unordered, align 4 246 store atomic i32 3, i32* %P1 release, align 4 247 ret void 248 } 249 250 ; As an implementation limitation, can't remove ordered stores 251 ; see also: @test24 252 define void @test29(i1 %B, i32* %P1, i32* %P2) { 253 ; CHECK-LABEL: @test29 254 ; CHECK-NEXT: store atomic 255 ; CHECK-NEXT: store atomic 256 store atomic i32 3, i32* %P1 release, align 4 257 store atomic i32 0, i32* %P1 unordered, align 4 258 ret void 259 } 260