281 lines · plain
1; RUN: opt < %s -aa-pipeline=basic-aa -passes=gvn,instcombine -S 2>&1 | FileCheck %s2 3target datalayout = "e-p:32:32:32-p1:16:16:16-i1:8:8-i8:8:8-i16:16:16-i32:32:32-i64:32:64-f32:32:32-f64:32:64-v64:64:64-v128:128:128-a0:0:64-f80:128:128"4 5; Make sure that basicaa thinks R and r are must aliases.6define i32 @test1(ptr %P) {7entry:8 %R = getelementptr {i32, i32}, ptr %P, i32 0, i32 19 %S = load i32, ptr %R10 11 %r = getelementptr {i32, i32}, ptr %P, i32 0, i32 112 %s = load i32, ptr %r13 14 %t = sub i32 %S, %s15 ret i32 %t16; CHECK-LABEL: @test1(17; CHECK: ret i32 018}19 20define i32 @test2(ptr %P) {21entry:22 %R = getelementptr {i32, i32, i32}, ptr %P, i32 0, i32 123 %S = load i32, ptr %R24 25 %r = getelementptr {i32, i32, i32}, ptr %P, i32 0, i32 226 store i32 42, ptr %r27 28 %s = load i32, ptr %R29 30 %t = sub i32 %S, %s31 ret i32 %t32; CHECK-LABEL: @test2(33; CHECK: ret i32 034}35 36 37; This was a miscompilation.38define i32 @test3(ptr %P) {39entry:40 %P2 = getelementptr {float, {i32, i32, i32}}, ptr %P, i32 0, i32 141 %R = getelementptr {i32, i32, i32}, ptr %P2, i32 0, i32 142 %S = load i32, ptr %R43 44 %r = getelementptr {i32, i32, i32}, ptr %P2, i32 0, i32 245 store i32 42, ptr %r46 47 %s = load i32, ptr %R48 49 %t = sub i32 %S, %s50 ret i32 %t51; CHECK-LABEL: @test3(52; CHECK: ret i32 053}54 55 56;; This is reduced from the SmallPtrSet constructor.57%SmallPtrSetImpl = type { ptr, i32, i32, i32, [1 x ptr] }58%SmallPtrSet64 = type { %SmallPtrSetImpl, [64 x ptr] }59 60define i32 @test4(ptr %P) {61entry:62 %tmp2 = getelementptr inbounds %SmallPtrSet64, ptr %P, i64 0, i32 0, i32 163 store i32 64, ptr %tmp2, align 864 %tmp3 = getelementptr inbounds %SmallPtrSet64, ptr %P, i64 0, i32 0, i32 4, i64 6465 store ptr null, ptr %tmp3, align 866 %tmp4 = load i32, ptr %tmp2, align 867 ret i32 %tmp468; CHECK-LABEL: @test4(69; CHECK: ret i32 6470}71 72; P[i] != p[i+1]73define i32 @test5(ptr %p, i64 %i) {74 %pi = getelementptr i32, ptr %p, i64 %i75 %i.next = add i64 %i, 176 %pi.next = getelementptr i32, ptr %p, i64 %i.next77 %x = load i32, ptr %pi78 store i32 42, ptr %pi.next79 %y = load i32, ptr %pi80 %z = sub i32 %x, %y81 ret i32 %z82; CHECK-LABEL: @test5(83; CHECK: ret i32 084}85 86define i32 @test5_as1_smaller_size(ptr addrspace(1) %p, i8 %i) {87 %pi = getelementptr i32, ptr addrspace(1) %p, i8 %i88 %i.next = add i8 %i, 189 %pi.next = getelementptr i32, ptr addrspace(1) %p, i8 %i.next90 %x = load i32, ptr addrspace(1) %pi91 store i32 42, ptr addrspace(1) %pi.next92 %y = load i32, ptr addrspace(1) %pi93 %z = sub i32 %x, %y94 ret i32 %z95; CHECK-LABEL: @test5_as1_smaller_size(96; CHECK: sext97; CHECK: ret i32 098}99 100define i32 @test5_as1_same_size(ptr addrspace(1) %p, i16 %i) {101 %pi = getelementptr i32, ptr addrspace(1) %p, i16 %i102 %i.next = add i16 %i, 1103 %pi.next = getelementptr i32, ptr addrspace(1) %p, i16 %i.next104 %x = load i32, ptr addrspace(1) %pi105 store i32 42, ptr addrspace(1) %pi.next106 %y = load i32, ptr addrspace(1) %pi107 %z = sub i32 %x, %y108 ret i32 %z109; CHECK-LABEL: @test5_as1_same_size(110; CHECK: ret i32 0111}112 113; P[i] != p[(i*4)|1]114define i32 @test6(ptr %p, i64 %i1) {115 %i = shl i64 %i1, 2116 %pi = getelementptr i32, ptr %p, i64 %i117 %i.next = or disjoint i64 %i, 1118 %pi.next = getelementptr i32, ptr %p, i64 %i.next119 %x = load i32, ptr %pi120 store i32 42, ptr %pi.next121 %y = load i32, ptr %pi122 %z = sub i32 %x, %y123 ret i32 %z124; CHECK-LABEL: @test6(125; CHECK: ret i32 0126}127 128; P[i] != p[(i*4)|2048] with disjoint or129define i32 @test6_higheror(ptr %p, i64 %i1) {130 %i = shl nuw nsw i64 %i1, 2131 %pi = getelementptr i32, ptr %p, i64 %i132 %i.next = or disjoint i64 %i, 2048133 %pi.next = getelementptr i32, ptr %p, i64 %i.next134 %x = load i32, ptr %pi135 store i32 42, ptr %pi.next136 %y = load i32, ptr %pi137 %z = sub i32 %x, %y138 ret i32 %z139; CHECK-LABEL: @test6_higheror(140; CHECK: ret i32 0141}142 143; P[1] != P[i*4]144define i32 @test7(ptr %p, i64 %i) {145 %pi = getelementptr i32, ptr %p, i64 1146 %i.next = shl i64 %i, 2147 %pi.next = getelementptr i32, ptr %p, i64 %i.next148 %x = load i32, ptr %pi149 store i32 42, ptr %pi.next150 %y = load i32, ptr %pi151 %z = sub i32 %x, %y152 ret i32 %z153; CHECK-LABEL: @test7(154; CHECK: ret i32 0155}156 157; P[zext(i)] != p[zext(i+1)]158; PR1143159define i32 @test8(ptr %p, i16 %i) {160 %i1 = zext i16 %i to i32161 %pi = getelementptr i32, ptr %p, i32 %i1162 %i.next = add i16 %i, 1163 %i.next2 = zext i16 %i.next to i32164 %pi.next = getelementptr i32, ptr %p, i32 %i.next2165 %x = load i32, ptr %pi166 store i32 42, ptr %pi.next167 %y = load i32, ptr %pi168 %z = sub i32 %x, %y169 ret i32 %z170; CHECK-LABEL: @test8(171; CHECK: ret i32 0172}173 174define i8 @test9(ptr %P, i32 %i, i32 %j) {175 %i2 = shl i32 %i, 2176 %i3 = add i32 %i2, 1177 ; P2 = P + 1 + 4*i178 %P2 = getelementptr [4 x i8], ptr %P, i32 0, i32 %i3179 180 %j2 = shl i32 %j, 2181 182 ; P4 = P + 4*j183 %P4 = getelementptr [4 x i8], ptr %P, i32 0, i32 %j2184 185 %x = load i8, ptr %P2186 store i8 42, ptr %P4187 %y = load i8, ptr %P2188 %z = sub i8 %x, %y189 ret i8 %z190; CHECK-LABEL: @test9(191; CHECK: ret i8 0192}193 194define i8 @test10(ptr %P, i32 %i) {195 %i2 = shl i32 %i, 2196 %i3 = add i32 %i2, 4197 ; P2 = P + 4 + 4*i198 %P2 = getelementptr [4 x i8], ptr %P, i32 0, i32 %i3199 200 ; P4 = P + 4*i201 %P4 = getelementptr [4 x i8], ptr %P, i32 0, i32 %i2202 203 %x = load i8, ptr %P2204 store i8 42, ptr %P4205 %y = load i8, ptr %P2206 %z = sub i8 %x, %y207 ret i8 %z208; CHECK-LABEL: @test10(209; CHECK: ret i8 0210}211 212; (This was a miscompilation.)213define float @test11(i32 %indvar, ptr %q) nounwind ssp {214 %tmp = mul i32 %indvar, -1215 %dec = add i32 %tmp, 3216 %scevgep = getelementptr [4 x [2 x float]], ptr %q, i32 0, i32 %dec217 %y29 = getelementptr inbounds [2 x float], ptr %q, i32 0, i32 1218 store float 1.0, ptr %y29, align 4219 store i64 0, ptr %scevgep, align 4220 %tmp30 = load float, ptr %y29, align 4221 ret float %tmp30222; CHECK-LABEL: @test11(223; CHECK: ret float %tmp30224}225 226; (This was a miscompilation.)227define i32 @test12(i32 %x, i32 %y, ptr %p) nounwind {228 %b = getelementptr [13 x i8], ptr %p, i32 %x229 %d = getelementptr [15 x i8], ptr %b, i32 %y, i32 8230 store i32 1, ptr %p231 store i32 0, ptr %d232 %r = load i32, ptr %p233 ret i32 %r234; CHECK-LABEL: @test12(235; CHECK: ret i32 %r236}237 238@P = internal global i32 715827882, align 4239@Q = internal global i32 715827883, align 4240@.str = private unnamed_addr constant [7 x i8] c"%u %u\0A\00", align 1241 242; Make sure we recognize that u[0] and u[Global + Cst] may alias243; when the addition has wrapping semantic.244; PR24468.245; CHECK-LABEL: @test13(246; Make sure the stores appear before the related loads.247; CHECK: store i8 42,248; CHECK: store i8 99,249; Find the loads and make sure they are used in the arguments to the printf.250; CHECK: [[T0:%[a-zA-Z0-9_]+]] = load i8, ptr %t, align 1251; CHECK: [[T0ARG:%[a-zA-Z0-9_]+]] = zext i8 [[T0]] to i32252; CHECK: [[U0:%[a-zA-Z0-9_]+]] = load i8, ptr %u, align 1253; CHECK: [[U0ARG:%[a-zA-Z0-9_]+]] = zext i8 [[U0]] to i32254; CHECK: call i32 (ptr, ...) @printf(ptr noundef nonnull dereferenceable(1) @.str, i32 [[T0ARG]], i32 [[U0ARG]])255; CHECK: ret256define void @test13() {257entry:258 %t = alloca [3 x i8], align 1259 %u = alloca [3 x i8], align 1260 %tmp = load i32, ptr @P, align 4261 %tmp1 = mul i32 %tmp, 3262 %mul = add i32 %tmp1, -2147483646263 %idxprom = zext i32 %mul to i64264 %arrayidx = getelementptr inbounds [3 x i8], ptr %t, i64 0, i64 %idxprom265 store i8 42, ptr %arrayidx, align 1266 %tmp2 = load i32, ptr @Q, align 4267 %tmp3 = mul i32 %tmp2, 3268 %mul2 = add i32 %tmp3, 2147483647269 %idxprom3 = zext i32 %mul2 to i64270 %arrayidx4 = getelementptr inbounds [3 x i8], ptr %u, i64 0, i64 %idxprom3271 store i8 99, ptr %arrayidx4, align 1272 %tmp4 = load i8, ptr %t, align 1273 %conv = zext i8 %tmp4 to i32274 %tmp5 = load i8, ptr %u, align 1275 %conv7 = zext i8 %tmp5 to i32276 %call = call i32 (ptr, ...) @printf(ptr @.str, i32 %conv, i32 %conv7)277 ret void278}279 280declare i32 @printf(ptr, ...)281