brintos

brintos / llvm-project-archived public Read only

0
0
Text · 14.0 KiB · 977942a Raw
372 lines · plain
1; NOTE: Assertions have been autogenerated by utils/update_test_checks.py2; RUN: opt -passes=slp-vectorizer -slp-threshold=-999 -S -mtriple=x86_64-unknown-linux-gnu -mcpu=skylake < %s | FileCheck %s3 4declare i64 @may_inf_loop_ro() nounwind readonly5 6; Base case without allocas or stacksave7define void @basecase(ptr %a, ptr %b, ptr %c) {8; CHECK-LABEL: @basecase(9; CHECK-NEXT:    [[TMP1:%.*]] = load <2 x ptr>, ptr [[A:%.*]], align 810; CHECK-NEXT:    store ptr null, ptr [[A]], align 811; CHECK-NEXT:    [[TMP2:%.*]] = getelementptr i8, <2 x ptr> [[TMP1]], <2 x i32> splat (i32 1)12; CHECK-NEXT:    store <2 x ptr> [[TMP2]], ptr [[B:%.*]], align 813; CHECK-NEXT:    ret void14;15 16  %v1 = load ptr, ptr %a17  store ptr zeroinitializer, ptr %a18  %a2 = getelementptr ptr, ptr %a, i32 119  %v2 = load ptr, ptr %a220 21  %add1 = getelementptr i8, ptr %v1, i32 122  %add2 = getelementptr i8, ptr %v2, i32 123 24  store ptr %add1, ptr %b25  %b2 = getelementptr ptr, ptr %b, i32 126  store ptr %add2, ptr %b227  ret void28}29 30; Using two allocas and a buildvector31define void @allocas(ptr %a, ptr %b, ptr %c) {32; CHECK-LABEL: @allocas(33; CHECK-NEXT:    [[V1:%.*]] = alloca i8, align 134; CHECK-NEXT:    [[V2:%.*]] = alloca i8, align 135; CHECK-NEXT:    [[TMP1:%.*]] = insertelement <2 x ptr> poison, ptr [[V1]], i32 036; CHECK-NEXT:    [[TMP2:%.*]] = insertelement <2 x ptr> [[TMP1]], ptr [[V2]], i32 137; CHECK-NEXT:    [[TMP3:%.*]] = getelementptr i8, <2 x ptr> [[TMP2]], <2 x i32> splat (i32 1)38; CHECK-NEXT:    [[TMP4:%.*]] = getelementptr i8, ptr [[V1]], i32 139; CHECK-NEXT:    store ptr [[TMP4]], ptr [[A:%.*]], align 840; CHECK-NEXT:    store <2 x ptr> [[TMP3]], ptr [[B:%.*]], align 841; CHECK-NEXT:    ret void42;43 44  %v1 = alloca i845  %add1 = getelementptr i8, ptr %v1, i32 146  store ptr %add1, ptr %a47  %v2 = alloca i848 49  %add2 = getelementptr i8, ptr %v2, i32 150 51  store ptr %add1, ptr %b52  %b2 = getelementptr ptr, ptr %b, i32 153  store ptr %add2, ptr %b254  ret void55}56 57; Allocas can not be speculated above a potentially non-returning call58define void @allocas_speculation(ptr %a, ptr %b, ptr %c) {59; CHECK-LABEL: @allocas_speculation(60; CHECK-NEXT:    [[V1:%.*]] = alloca i8, align 161; CHECK-NEXT:    [[ADD1:%.*]] = getelementptr i8, ptr [[V1]], i32 162; CHECK-NEXT:    store ptr [[ADD1]], ptr [[A:%.*]], align 863; CHECK-NEXT:    [[TMP1:%.*]] = call i64 @may_inf_loop_ro()64; CHECK-NEXT:    [[V2:%.*]] = alloca i8, align 165; CHECK-NEXT:    [[ADD2:%.*]] = getelementptr i8, ptr [[V2]], i32 166; CHECK-NEXT:    store ptr [[ADD1]], ptr [[B:%.*]], align 867; CHECK-NEXT:    [[B2:%.*]] = getelementptr ptr, ptr [[B]], i32 168; CHECK-NEXT:    store ptr [[ADD2]], ptr [[B2]], align 869; CHECK-NEXT:    ret void70;71 72  %v1 = alloca i873  %add1 = getelementptr i8, ptr %v1, i32 174  store ptr %add1, ptr %a75  call i64 @may_inf_loop_ro()76  %v2 = alloca i877 78  %add2 = getelementptr i8, ptr %v2, i32 179 80  store ptr %add1, ptr %b81  %b2 = getelementptr ptr, ptr %b, i32 182  store ptr %add2, ptr %b283  ret void84}85 86; We must be careful not to lift the inalloca alloc above the stacksave here.87; We used to miscompile this example before adding explicit dependency handling88; for stacksave.89define void @stacksave(ptr %a, ptr %b, ptr %c) {90; CHECK-LABEL: @stacksave(91; CHECK-NEXT:    [[V1:%.*]] = alloca i8, align 192; CHECK-NEXT:    [[ADD1:%.*]] = getelementptr i8, ptr [[V1]], i32 193; CHECK-NEXT:    store ptr [[ADD1]], ptr [[A:%.*]], align 894; CHECK-NEXT:    [[STACK:%.*]] = call ptr @llvm.stacksave.p0()95; CHECK-NEXT:    [[V2:%.*]] = alloca inalloca i8, align 196; CHECK-NEXT:    call void @use(ptr inalloca(i8) [[V2]]) #[[ATTR4:[0-9]+]]97; CHECK-NEXT:    call void @llvm.stackrestore.p0(ptr [[STACK]])98; CHECK-NEXT:    [[ADD2:%.*]] = getelementptr i8, ptr [[V2]], i32 199; CHECK-NEXT:    store ptr [[ADD1]], ptr [[B:%.*]], align 8100; CHECK-NEXT:    [[B2:%.*]] = getelementptr ptr, ptr [[B]], i32 1101; CHECK-NEXT:    store ptr [[ADD2]], ptr [[B2]], align 8102; CHECK-NEXT:    ret void103;104 105  %v1 = alloca i8106  %add1 = getelementptr i8, ptr %v1, i32 1107  store ptr %add1, ptr %a108 109  %stack = call ptr @llvm.stacksave()110  %v2 = alloca inalloca i8111  call void @use(ptr inalloca(i8) %v2) readnone112  call void @llvm.stackrestore(ptr %stack)113 114  %add2 = getelementptr i8, ptr %v2, i32 1115 116  store ptr %add1, ptr %b117  %b2 = getelementptr ptr, ptr %b, i32 1118  store ptr %add2, ptr %b2119  ret void120}121 122define void @stacksave2(ptr %a, ptr %b, ptr %c) {123; CHECK-LABEL: @stacksave2(124; CHECK-NEXT:    [[V1:%.*]] = alloca i8, align 1125; CHECK-NEXT:    [[STACK:%.*]] = call ptr @llvm.stacksave.p0()126; CHECK-NEXT:    [[V2:%.*]] = alloca inalloca i8, align 1127; CHECK-NEXT:    [[TMP1:%.*]] = insertelement <2 x ptr> poison, ptr [[V1]], i32 0128; CHECK-NEXT:    [[TMP2:%.*]] = insertelement <2 x ptr> [[TMP1]], ptr [[V2]], i32 1129; CHECK-NEXT:    [[TMP3:%.*]] = getelementptr i8, <2 x ptr> [[TMP2]], <2 x i32> splat (i32 1)130; CHECK-NEXT:    [[TMP4:%.*]] = getelementptr i8, ptr [[V1]], i32 1131; CHECK-NEXT:    store ptr [[TMP4]], ptr [[A:%.*]], align 8132; CHECK-NEXT:    call void @use(ptr inalloca(i8) [[V2]]) #[[ATTR5:[0-9]+]]133; CHECK-NEXT:    call void @llvm.stackrestore.p0(ptr [[STACK]])134; CHECK-NEXT:    store <2 x ptr> [[TMP3]], ptr [[B:%.*]], align 8135; CHECK-NEXT:    ret void136;137 138  %v1 = alloca i8139  %add1 = getelementptr i8, ptr %v1, i32 1140 141  %stack = call ptr @llvm.stacksave()142  store ptr %add1, ptr %a143  %v2 = alloca inalloca i8144  call void @use(ptr inalloca(i8) %v2) readonly145  call void @llvm.stackrestore(ptr %stack)146 147  %add2 = getelementptr i8, ptr %v2, i32 1148 149  store ptr %add1, ptr %b150  %b2 = getelementptr ptr, ptr %b, i32 1151  store ptr %add2, ptr %b2152  ret void153}154 155define void @stacksave3(ptr %a, ptr %b, ptr %c) {156; CHECK-LABEL: @stacksave3(157; CHECK-NEXT:    [[STACK:%.*]] = call ptr @llvm.stacksave.p0()158; CHECK-NEXT:    [[V1:%.*]] = alloca i8, align 1159; CHECK-NEXT:    [[V2:%.*]] = alloca inalloca i8, align 1160; CHECK-NEXT:    call void @use(ptr inalloca(i8) [[V2]]) #[[ATTR4]]161; CHECK-NEXT:    call void @llvm.stackrestore.p0(ptr [[STACK]])162; CHECK-NEXT:    [[TMP1:%.*]] = insertelement <2 x ptr> poison, ptr [[V1]], i32 0163; CHECK-NEXT:    [[TMP2:%.*]] = insertelement <2 x ptr> [[TMP1]], ptr [[V2]], i32 1164; CHECK-NEXT:    [[TMP3:%.*]] = getelementptr i8, <2 x ptr> [[TMP2]], <2 x i32> splat (i32 1)165; CHECK-NEXT:    store <2 x ptr> [[TMP3]], ptr [[B:%.*]], align 8166; CHECK-NEXT:    ret void167;168 169  %stack = call ptr @llvm.stacksave()170  %v1 = alloca i8171 172  %v2 = alloca inalloca i8173  call void @use(ptr inalloca(i8) %v2) readnone174  call void @llvm.stackrestore(ptr %stack)175 176  %add1 = getelementptr i8, ptr %v1, i32 1177  %add2 = getelementptr i8, ptr %v2, i32 1178 179  store ptr %add1, ptr %b180  %b2 = getelementptr ptr, ptr %b, i32 1181  store ptr %add2, ptr %b2182  ret void183}184 185; Here we have an alloca which needs to stay under the stacksave, but is not186; directly part of the vectorization tree.  Instead, the stacksave is187; encountered during dependency scanning via the memory chain.188define void @stacksave4(ptr %a, ptr %b, ptr %c) {189; CHECK-LABEL: @stacksave4(190; CHECK-NEXT:    [[TMP1:%.*]] = load <2 x ptr>, ptr [[A:%.*]], align 8191; CHECK-NEXT:    [[TMP2:%.*]] = getelementptr i8, <2 x ptr> [[TMP1]], <2 x i32> splat (i32 1)192; CHECK-NEXT:    [[STACK:%.*]] = call ptr @llvm.stacksave.p0()193; CHECK-NEXT:    [[X:%.*]] = alloca inalloca i8, align 1194; CHECK-NEXT:    call void @use(ptr inalloca(i8) [[X]]) #[[ATTR4]]195; CHECK-NEXT:    call void @llvm.stackrestore.p0(ptr [[STACK]])196; CHECK-NEXT:    store <2 x ptr> [[TMP2]], ptr [[B:%.*]], align 8197; CHECK-NEXT:    ret void198;199 200  %v1 = load ptr, ptr %a201  %a2 = getelementptr ptr, ptr %a, i32 1202  %v2 = load ptr, ptr %a2203 204  %add1 = getelementptr i8, ptr %v1, i32 1205  %add2 = getelementptr i8, ptr %v2, i32 1206 207  %stack = call ptr @llvm.stacksave()208  %x = alloca inalloca i8209  call void @use(ptr inalloca(i8) %x) readnone210  call void @llvm.stackrestore(ptr %stack)211 212  store ptr %add1, ptr %b213  %b2 = getelementptr ptr, ptr %b, i32 1214  store ptr %add2, ptr %b2215  ret void216}217 218define void @stacksave5(ptr %a, ptr %b, ptr %c) {219; CHECK-LABEL: @stacksave5(220; CHECK-NEXT:    [[TMP1:%.*]] = load <2 x ptr>, ptr [[A:%.*]], align 8221; CHECK-NEXT:    [[TMP2:%.*]] = getelementptr i8, <2 x ptr> [[TMP1]], <2 x i32> splat (i32 1)222; CHECK-NEXT:    [[STACK:%.*]] = call ptr @llvm.stacksave.p0()223; CHECK-NEXT:    [[X:%.*]] = alloca inalloca i8, align 1224; CHECK-NEXT:    call void @use(ptr inalloca(i8) [[X]]) #[[ATTR4]]225; CHECK-NEXT:    call void @llvm.stackrestore.p0(ptr [[STACK]])226; CHECK-NEXT:    store <2 x ptr> [[TMP2]], ptr [[B:%.*]], align 8227; CHECK-NEXT:    ret void228;229 230  %v1 = load ptr, ptr %a231  %a2 = getelementptr ptr, ptr %a, i32 1232  %v2 = load ptr, ptr %a2233 234  %add1 = getelementptr i8, ptr %v1, i32 1235  %add2 = getelementptr i8, ptr %v2, i32 1236 237  %stack = call ptr @llvm.stacksave()238  %x = alloca inalloca i8239  call void @use(ptr inalloca(i8) %x) readnone240  call void @llvm.stackrestore(ptr %stack)241 242  store ptr %add1, ptr %b243  %b2 = getelementptr ptr, ptr %b, i32 1244  store ptr %add2, ptr %b2245  ret void246}247 248; Reordering the second alloca above the stackrestore while249; leaving the write to it below would introduce a write-after-free250; bug.251define void @stackrestore1(ptr %a, ptr %b, ptr %c) {252; CHECK-LABEL: @stackrestore1(253; CHECK-NEXT:    [[STACK:%.*]] = call ptr @llvm.stacksave.p0()254; CHECK-NEXT:    [[V1:%.*]] = alloca i8, align 1255; CHECK-NEXT:    store i8 0, ptr [[V1]], align 1256; CHECK-NEXT:    call void @llvm.stackrestore.p0(ptr [[STACK]])257; CHECK-NEXT:    [[V2:%.*]] = alloca i8, align 1258; CHECK-NEXT:    store i8 0, ptr [[V2]], align 1259; CHECK-NEXT:    [[TMP1:%.*]] = insertelement <2 x ptr> poison, ptr [[V1]], i32 0260; CHECK-NEXT:    [[TMP2:%.*]] = insertelement <2 x ptr> [[TMP1]], ptr [[V2]], i32 1261; CHECK-NEXT:    [[TMP3:%.*]] = getelementptr i8, <2 x ptr> [[TMP2]], <2 x i32> splat (i32 1)262; CHECK-NEXT:    store <2 x ptr> [[TMP3]], ptr [[B:%.*]], align 8263; CHECK-NEXT:    ret void264;265 266  %stack = call ptr @llvm.stacksave()267  %v1 = alloca i8268  store i8 0, ptr %v1269  call void @llvm.stackrestore(ptr %stack)270  %v2 = alloca i8271  store i8 0, ptr %v2272 273  %add1 = getelementptr i8, ptr %v1, i32 1274  %add2 = getelementptr i8, ptr %v2, i32 1275 276  store ptr %add1, ptr %b277  %b2 = getelementptr ptr, ptr %b, i32 1278  store ptr %add2, ptr %b2279  ret void280}281 282declare void @use(ptr inalloca(i8))283declare ptr @llvm.stacksave()284declare void @llvm.stackrestore(ptr)285 286; The next set are reduced from previous regressions.287 288declare ptr @wibble(ptr)289declare void @quux(ptr inalloca(i32))290 291define void @ham() #1 {292; CHECK-LABEL: @ham(293; CHECK-NEXT:    [[VAR2:%.*]] = alloca i8, align 1294; CHECK-NEXT:    [[VAR3:%.*]] = alloca i8, align 1295; CHECK-NEXT:    [[VAR4:%.*]] = alloca i8, align 1296; CHECK-NEXT:    [[VAR5:%.*]] = alloca i8, align 1297; CHECK-NEXT:    [[VAR12:%.*]] = alloca [12 x ptr], align 8298; CHECK-NEXT:    [[VAR15:%.*]] = call ptr @wibble(ptr [[VAR2]])299; CHECK-NEXT:    [[VAR16:%.*]] = call ptr @wibble(ptr [[VAR3]])300; CHECK-NEXT:    [[VAR17:%.*]] = call ptr @wibble(ptr [[VAR4]])301; CHECK-NEXT:    [[VAR23:%.*]] = call ptr @llvm.stacksave.p0()302; CHECK-NEXT:    [[VAR24:%.*]] = alloca inalloca i32, align 4303; CHECK-NEXT:    call void @quux(ptr inalloca(i32) [[VAR24]])304; CHECK-NEXT:    call void @llvm.stackrestore.p0(ptr [[VAR23]])305; CHECK-NEXT:    [[TMP1:%.*]] = insertelement <4 x ptr> poison, ptr [[VAR4]], i32 0306; CHECK-NEXT:    [[TMP2:%.*]] = shufflevector <4 x ptr> [[TMP1]], <4 x ptr> poison, <4 x i32> zeroinitializer307; CHECK-NEXT:    store <4 x ptr> [[TMP2]], ptr [[VAR12]], align 8308; CHECK-NEXT:    [[VAR36:%.*]] = getelementptr inbounds [12 x ptr], ptr [[VAR12]], i32 0, i32 4309; CHECK-NEXT:    [[TMP3:%.*]] = insertelement <4 x ptr> [[TMP1]], ptr [[VAR5]], i32 1310; CHECK-NEXT:    [[TMP4:%.*]] = shufflevector <4 x ptr> [[TMP3]], <4 x ptr> poison, <4 x i32> <i32 0, i32 1, i32 1, i32 1>311; CHECK-NEXT:    store <4 x ptr> [[TMP4]], ptr [[VAR36]], align 8312; CHECK-NEXT:    ret void313;314  %var2 = alloca i8315  %var3 = alloca i8316  %var4 = alloca i8317  %var5 = alloca i8318  %var12 = alloca [12 x ptr]319  %var15 = call ptr @wibble(ptr %var2)320  %var16 = call ptr @wibble(ptr %var3)321  %var17 = call ptr @wibble(ptr %var4)322  %var23 = call ptr @llvm.stacksave()323  %var24 = alloca inalloca i32324  call void @quux(ptr inalloca(i32) %var24)325  call void @llvm.stackrestore(ptr %var23)326  store ptr %var4, ptr %var12327  %var33 = getelementptr inbounds [12 x ptr], ptr %var12, i32 0, i32 1328  store ptr %var4, ptr %var33329  %var34 = getelementptr inbounds [12 x ptr], ptr %var12, i32 0, i32 2330  store ptr %var4, ptr %var34331  %var35 = getelementptr inbounds [12 x ptr], ptr %var12, i32 0, i32 3332  store ptr %var4, ptr %var35333  %var36 = getelementptr inbounds [12 x ptr], ptr %var12, i32 0, i32 4334  store ptr %var4, ptr %var36335  %var37 = getelementptr inbounds [12 x ptr], ptr %var12, i32 0, i32 5336  store ptr %var5, ptr %var37337  %var38 = getelementptr inbounds [12 x ptr], ptr %var12, i32 0, i32 6338  store ptr %var5, ptr %var38339  %var39 = getelementptr inbounds [12 x ptr], ptr %var12, i32 0, i32 7340  store ptr %var5, ptr %var39341  ret void342}343 344define void @spam() #1 {345; CHECK-LABEL: @spam(346; CHECK-NEXT:    [[VAR4:%.*]] = alloca i8, align 1347; CHECK-NEXT:    [[VAR5:%.*]] = alloca i8, align 1348; CHECK-NEXT:    [[VAR12:%.*]] = alloca [12 x ptr], align 8349; CHECK-NEXT:    [[VAR36:%.*]] = getelementptr inbounds [12 x ptr], ptr [[VAR12]], i32 0, i32 4350; CHECK-NEXT:    [[TMP1:%.*]] = insertelement <4 x ptr> poison, ptr [[VAR4]], i32 0351; CHECK-NEXT:    [[TMP2:%.*]] = insertelement <4 x ptr> [[TMP1]], ptr [[VAR5]], i32 1352; CHECK-NEXT:    [[TMP3:%.*]] = shufflevector <4 x ptr> [[TMP2]], <4 x ptr> poison, <4 x i32> <i32 0, i32 1, i32 1, i32 1>353; CHECK-NEXT:    store <4 x ptr> [[TMP3]], ptr [[VAR36]], align 8354; CHECK-NEXT:    ret void355;356  %var4 = alloca i8357  %var5 = alloca i8358  %var12 = alloca [12 x ptr]359  %var36 = getelementptr inbounds [12 x ptr], ptr %var12, i32 0, i32 4360  store ptr %var4, ptr %var36361  %var37 = getelementptr inbounds [12 x ptr], ptr %var12, i32 0, i32 5362  store ptr %var5, ptr %var37363  %var38 = getelementptr inbounds [12 x ptr], ptr %var12, i32 0, i32 6364  store ptr %var5, ptr %var38365  %var39 = getelementptr inbounds [12 x ptr], ptr %var12, i32 0, i32 7366  store ptr %var5, ptr %var39367  ret void368}369 370attributes #0 = { nofree nosync nounwind willreturn }371attributes #1 = { "target-features"="+cx8,+fxsr,+mmx,+sse,+sse2,+sse3,+x87" }372