brintos

brintos / llvm-project-archived public Read only

0
0
Text · 12.7 KiB · 69cfdd4 Raw
363 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 readonly5declare i64 @may_inf_loop_rw() nounwind6declare i64 @may_throw() willreturn7 8; Base case with no interesting control dependencies9define void @test_no_control(ptr %a, ptr %b, ptr %c) {10; CHECK-LABEL: @test_no_control(11; CHECK-NEXT:    [[TMP1:%.*]] = load <2 x i64>, ptr [[A:%.*]], align 812; CHECK-NEXT:    [[TMP2:%.*]] = load <2 x i64>, ptr [[C:%.*]], align 813; CHECK-NEXT:    [[TMP3:%.*]] = add <2 x i64> [[TMP1]], [[TMP2]]14; CHECK-NEXT:    store <2 x i64> [[TMP3]], ptr [[B:%.*]], align 815; CHECK-NEXT:    ret void16;17  %v1 = load i64, ptr %a18  %a2 = getelementptr i64, ptr %a, i32 119  %v2 = load i64, ptr %a220 21  %c1 = load i64, ptr %c22  %ca2 = getelementptr i64, ptr %c, i32 123  %c2 = load i64, ptr %ca224  %add1 = add i64 %v1, %c125  %add2 = add i64 %v2, %c226 27  store i64 %add1, ptr %b28  %b2 = getelementptr i64, ptr %b, i32 129  store i64 %add2, ptr %b230  ret void31}32 33define void @test1(ptr %a, ptr %b, ptr %c) {34; CHECK-LABEL: @test1(35; CHECK-NEXT:    [[C1:%.*]] = load i64, ptr [[C:%.*]], align 836; CHECK-NEXT:    [[C2:%.*]] = call i64 @may_inf_loop_ro()37; CHECK-NEXT:    [[TMP1:%.*]] = load <2 x i64>, ptr [[A:%.*]], align 838; CHECK-NEXT:    [[TMP2:%.*]] = insertelement <2 x i64> poison, i64 [[C1]], i32 039; CHECK-NEXT:    [[TMP3:%.*]] = insertelement <2 x i64> [[TMP2]], i64 [[C2]], i32 140; CHECK-NEXT:    [[TMP4:%.*]] = add <2 x i64> [[TMP1]], [[TMP3]]41; CHECK-NEXT:    store <2 x i64> [[TMP4]], ptr [[B:%.*]], align 842; CHECK-NEXT:    ret void43;44  %v1 = load i64, ptr %a45  %a2 = getelementptr i64, ptr %a, i32 146  %v2 = load i64, ptr %a247 48  %c1 = load i64, ptr %c49  %c2 = call i64 @may_inf_loop_ro()50  %add1 = add i64 %v1, %c151  %add2 = add i64 %v2, %c252 53  store i64 %add1, ptr %b54  %b2 = getelementptr i64, ptr %b, i32 155  store i64 %add2, ptr %b256  ret void57}58 59define void @test2(ptr %a, ptr %b, ptr %c) {60; CHECK-LABEL: @test2(61; CHECK-NEXT:    [[C1:%.*]] = load i64, ptr [[C:%.*]], align 862; CHECK-NEXT:    [[C2:%.*]] = call i64 @may_inf_loop_ro()63; CHECK-NEXT:    [[TMP1:%.*]] = load <2 x i64>, ptr [[A:%.*]], align 864; CHECK-NEXT:    [[TMP2:%.*]] = insertelement <2 x i64> poison, i64 [[C1]], i32 065; CHECK-NEXT:    [[TMP3:%.*]] = insertelement <2 x i64> [[TMP2]], i64 [[C2]], i32 166; CHECK-NEXT:    [[TMP4:%.*]] = add <2 x i64> [[TMP1]], [[TMP3]]67; CHECK-NEXT:    store <2 x i64> [[TMP4]], ptr [[B:%.*]], align 868; CHECK-NEXT:    ret void69;70  %c1 = load i64, ptr %c71  %c2 = call i64 @may_inf_loop_ro()72 73  %v1 = load i64, ptr %a74  %a2 = getelementptr i64, ptr %a, i32 175  %v2 = load i64, ptr %a276 77  %add1 = add i64 %v1, %c178  %add2 = add i64 %v2, %c279 80  store i64 %add1, ptr %b81  %b2 = getelementptr i64, ptr %b, i32 182  store i64 %add2, ptr %b283  ret void84}85 86define void @test3(ptr %a, ptr %b, ptr %c) {87; CHECK-LABEL: @test3(88; CHECK-NEXT:    [[C1:%.*]] = load i64, ptr [[C:%.*]], align 889; CHECK-NEXT:    [[C2:%.*]] = call i64 @may_inf_loop_ro()90; CHECK-NEXT:    [[TMP1:%.*]] = load <2 x i64>, ptr [[A:%.*]], align 891; CHECK-NEXT:    [[TMP2:%.*]] = insertelement <2 x i64> poison, i64 [[C1]], i32 092; CHECK-NEXT:    [[TMP3:%.*]] = insertelement <2 x i64> [[TMP2]], i64 [[C2]], i32 193; CHECK-NEXT:    [[TMP4:%.*]] = add <2 x i64> [[TMP1]], [[TMP3]]94; CHECK-NEXT:    store <2 x i64> [[TMP4]], ptr [[B:%.*]], align 895; CHECK-NEXT:    ret void96;97  %v1 = load i64, ptr %a98  %c1 = load i64, ptr %c99  %add1 = add i64 %v1, %c1100 101  %a2 = getelementptr i64, ptr %a, i32 1102  %v2 = load i64, ptr %a2103  %c2 = call i64 @may_inf_loop_ro()104  %add2 = add i64 %v2, %c2105 106  store i64 %add1, ptr %b107  %b2 = getelementptr i64, ptr %b, i32 1108  store i64 %add2, ptr %b2109  ret void110}111 112define void @test4(ptr %a, ptr %b, ptr %c) {113; CHECK-LABEL: @test4(114; CHECK-NEXT:    [[C1:%.*]] = load i64, ptr [[C:%.*]], align 8115; CHECK-NEXT:    [[C2:%.*]] = call i64 @may_inf_loop_ro()116; CHECK-NEXT:    [[TMP1:%.*]] = load <2 x i64>, ptr [[A:%.*]], align 8117; CHECK-NEXT:    [[TMP2:%.*]] = insertelement <2 x i64> poison, i64 [[C1]], i32 0118; CHECK-NEXT:    [[TMP3:%.*]] = insertelement <2 x i64> [[TMP2]], i64 [[C2]], i32 1119; CHECK-NEXT:    [[TMP4:%.*]] = add <2 x i64> [[TMP1]], [[TMP3]]120; CHECK-NEXT:    store <2 x i64> [[TMP4]], ptr [[B:%.*]], align 8121; CHECK-NEXT:    ret void122;123  %v1 = load i64, ptr %a124  %c1 = load i64, ptr %c125  %add1 = add i64 %v1, %c1126 127  %c2 = call i64 @may_inf_loop_ro()128  %a2 = getelementptr i64, ptr %a, i32 1129  %v2 = load i64, ptr %a2130  %add2 = add i64 %v2, %c2131 132  store i64 %add1, ptr %b133  %b2 = getelementptr i64, ptr %b, i32 1134  store i64 %add2, ptr %b2135  ret void136}137 138define void @test5(ptr %a, ptr %b, ptr %c) {139; CHECK-LABEL: @test5(140; CHECK-NEXT:    [[C2:%.*]] = call i64 @may_inf_loop_ro()141; CHECK-NEXT:    [[C1:%.*]] = load i64, ptr [[C:%.*]], align 8142; CHECK-NEXT:    [[TMP1:%.*]] = load <2 x i64>, ptr [[A:%.*]], align 8143; CHECK-NEXT:    [[TMP2:%.*]] = insertelement <2 x i64> poison, i64 [[C1]], i32 0144; CHECK-NEXT:    [[TMP3:%.*]] = insertelement <2 x i64> [[TMP2]], i64 [[C2]], i32 1145; CHECK-NEXT:    [[TMP4:%.*]] = add <2 x i64> [[TMP1]], [[TMP3]]146; CHECK-NEXT:    store <2 x i64> [[TMP4]], ptr [[B:%.*]], align 8147; CHECK-NEXT:    ret void148;149  %a2 = getelementptr i64, ptr %a, i32 1150  %v2 = load i64, ptr %a2151  %c2 = call i64 @may_inf_loop_ro()152  %add2 = add i64 %v2, %c2153 154  %v1 = load i64, ptr %a155  %c1 = load i64, ptr %c156  %add1 = add i64 %v1, %c1157 158  store i64 %add1, ptr %b159  %b2 = getelementptr i64, ptr %b, i32 1160  store i64 %add2, ptr %b2161  ret void162}163 164define void @test6(ptr %a, ptr %b, ptr %c) {165; CHECK-LABEL: @test6(166; CHECK-NEXT:    [[TMP1:%.*]] = call i64 @may_inf_loop_ro()167; CHECK-NEXT:    [[TMP2:%.*]] = load <2 x i64>, ptr [[A:%.*]], align 8168; CHECK-NEXT:    [[TMP3:%.*]] = load <2 x i64>, ptr [[C:%.*]], align 8169; CHECK-NEXT:    [[TMP4:%.*]] = add <2 x i64> [[TMP2]], [[TMP3]]170; CHECK-NEXT:    store <2 x i64> [[TMP4]], ptr [[B:%.*]], align 8171; CHECK-NEXT:    ret void172;173  %v1 = load i64, ptr %a174  call i64 @may_inf_loop_ro()175  %a2 = getelementptr i64, ptr %a, i32 1176  %v2 = load i64, ptr %a2177 178  %c1 = load i64, ptr %c179  %ca2 = getelementptr i64, ptr %c, i32 1180  %c2 = load i64, ptr %ca2181  %add1 = add i64 %v1, %c1182  %add2 = add i64 %v2, %c2183 184  store i64 %add1, ptr %b185  %b2 = getelementptr i64, ptr %b, i32 1186  store i64 %add2, ptr %b2187  ret void188}189 190; In this case, we can't vectorize the load pair because there's no valid191; scheduling point which respects both memory and control dependence.  If192; we scheduled the second load before the store holding the first one in place,193; we'd have hoisted a potentially faulting load above a potentially infinite194; call and thus have introduced a possible fault into a program which didn't195; previously exist.196define void @test7(ptr %a, ptr %b, ptr %c) {197; CHECK-LABEL: @test7(198; CHECK-NEXT:    [[A2:%.*]] = getelementptr i64, ptr [[A:%.*]], i32 1199; CHECK-NEXT:    [[V1:%.*]] = load i64, ptr [[A]], align 8200; CHECK-NEXT:    store i64 0, ptr [[A]], align 8201; CHECK-NEXT:    [[TMP1:%.*]] = call i64 @may_inf_loop_ro()202; CHECK-NEXT:    [[V2:%.*]] = load i64, ptr [[A2]], align 8203; CHECK-NEXT:    [[TMP2:%.*]] = load <2 x i64>, ptr [[C:%.*]], align 8204; CHECK-NEXT:    [[TMP3:%.*]] = insertelement <2 x i64> poison, i64 [[V1]], i32 0205; CHECK-NEXT:    [[TMP4:%.*]] = insertelement <2 x i64> [[TMP3]], i64 [[V2]], i32 1206; CHECK-NEXT:    [[TMP5:%.*]] = add <2 x i64> [[TMP4]], [[TMP2]]207; CHECK-NEXT:    store <2 x i64> [[TMP5]], ptr [[B:%.*]], align 8208; CHECK-NEXT:    ret void209;210  %v1 = load i64, ptr %a211  store i64 0, ptr %a212  call i64 @may_inf_loop_ro()213  %a2 = getelementptr i64, ptr %a, i32 1214  %v2 = load i64, ptr %a2215 216  %c1 = load i64, ptr %c217  %ca2 = getelementptr i64, ptr %c, i32 1218  %c2 = load i64, ptr %ca2219  %add1 = add i64 %v1, %c1220  %add2 = add i64 %v2, %c2221 222  store i64 %add1, ptr %b223  %b2 = getelementptr i64, ptr %b, i32 1224  store i64 %add2, ptr %b2225  ret void226}227 228; Same as test7, but with a throwing call229define void @test8(ptr %a, ptr %b, ptr %c) {230; CHECK-LABEL: @test8(231; CHECK-NEXT:    [[A2:%.*]] = getelementptr i64, ptr [[A:%.*]], i32 1232; CHECK-NEXT:    [[V1:%.*]] = load i64, ptr [[A]], align 8233; CHECK-NEXT:    store i64 0, ptr [[A]], align 8234; CHECK-NEXT:    [[TMP1:%.*]] = call i64 @may_throw() #[[ATTR4:[0-9]+]]235; CHECK-NEXT:    [[V2:%.*]] = load i64, ptr [[A2]], align 8236; CHECK-NEXT:    [[TMP2:%.*]] = load <2 x i64>, ptr [[C:%.*]], align 8237; CHECK-NEXT:    [[TMP3:%.*]] = insertelement <2 x i64> poison, i64 [[V1]], i32 0238; CHECK-NEXT:    [[TMP4:%.*]] = insertelement <2 x i64> [[TMP3]], i64 [[V2]], i32 1239; CHECK-NEXT:    [[TMP5:%.*]] = add <2 x i64> [[TMP4]], [[TMP2]]240; CHECK-NEXT:    store <2 x i64> [[TMP5]], ptr [[B:%.*]], align 8241; CHECK-NEXT:    ret void242;243  %v1 = load i64, ptr %a244  store i64 0, ptr %a245  call i64 @may_throw() readonly246  %a2 = getelementptr i64, ptr %a, i32 1247  %v2 = load i64, ptr %a2248 249  %c1 = load i64, ptr %c250  %ca2 = getelementptr i64, ptr %c, i32 1251  %c2 = load i64, ptr %ca2252  %add1 = add i64 %v1, %c1253  %add2 = add i64 %v2, %c2254 255  store i64 %add1, ptr %b256  %b2 = getelementptr i64, ptr %b, i32 1257  store i64 %add2, ptr %b2258  ret void259}260 261; Same as test8, but with a readwrite maythrow call262define void @test9(ptr %a, ptr %b, ptr %c) {263; CHECK-LABEL: @test9(264; CHECK-NEXT:    [[A2:%.*]] = getelementptr i64, ptr [[A:%.*]], i32 1265; CHECK-NEXT:    [[V1:%.*]] = load i64, ptr [[A]], align 8266; CHECK-NEXT:    store i64 0, ptr [[A]], align 8267; CHECK-NEXT:    [[TMP1:%.*]] = call i64 @may_throw()268; CHECK-NEXT:    [[V2:%.*]] = load i64, ptr [[A2]], align 8269; CHECK-NEXT:    [[TMP2:%.*]] = load <2 x i64>, ptr [[C:%.*]], align 8270; CHECK-NEXT:    [[TMP3:%.*]] = insertelement <2 x i64> poison, i64 [[V1]], i32 0271; CHECK-NEXT:    [[TMP4:%.*]] = insertelement <2 x i64> [[TMP3]], i64 [[V2]], i32 1272; CHECK-NEXT:    [[TMP5:%.*]] = add <2 x i64> [[TMP4]], [[TMP2]]273; CHECK-NEXT:    store <2 x i64> [[TMP5]], ptr [[B:%.*]], align 8274; CHECK-NEXT:    ret void275;276  %v1 = load i64, ptr %a277  store i64 0, ptr %a278  call i64 @may_throw()279  %a2 = getelementptr i64, ptr %a, i32 1280  %v2 = load i64, ptr %a2281 282  %c1 = load i64, ptr %c283  %ca2 = getelementptr i64, ptr %c, i32 1284  %c2 = load i64, ptr %ca2285  %add1 = add i64 %v1, %c1286  %add2 = add i64 %v2, %c2287 288  store i64 %add1, ptr %b289  %b2 = getelementptr i64, ptr %b, i32 1290  store i64 %add2, ptr %b2291  ret void292}293 294; A variant of test7 which shows the same problem with a non-load instruction295define void @test10(ptr %a, ptr %b, ptr %c) {296; CHECK-LABEL: @test10(297; CHECK-NEXT:    [[V1:%.*]] = load i64, ptr [[A:%.*]], align 8298; CHECK-NEXT:    [[A2:%.*]] = getelementptr i64, ptr [[A]], i32 1299; CHECK-NEXT:    [[V2:%.*]] = load i64, ptr [[A2]], align 8300; CHECK-NEXT:    [[U1:%.*]] = udiv i64 200, [[V1]]301; CHECK-NEXT:    store i64 [[U1]], ptr [[A]], align 8302; CHECK-NEXT:    [[TMP1:%.*]] = call i64 @may_inf_loop_ro()303; CHECK-NEXT:    [[U2:%.*]] = udiv i64 200, [[V2]]304; CHECK-NEXT:    [[TMP2:%.*]] = load <2 x i64>, ptr [[C:%.*]], align 8305; CHECK-NEXT:    [[TMP3:%.*]] = insertelement <2 x i64> poison, i64 [[U1]], i32 0306; CHECK-NEXT:    [[TMP4:%.*]] = insertelement <2 x i64> [[TMP3]], i64 [[U2]], i32 1307; CHECK-NEXT:    [[TMP5:%.*]] = add <2 x i64> [[TMP4]], [[TMP2]]308; CHECK-NEXT:    store <2 x i64> [[TMP5]], ptr [[B:%.*]], align 8309; CHECK-NEXT:    ret void310;311  %v1 = load i64, ptr %a312  %a2 = getelementptr i64, ptr %a, i32 1313  %v2 = load i64, ptr %a2314 315  %u1 = udiv i64 200, %v1316  store i64 %u1, ptr %a317  call i64 @may_inf_loop_ro()318  %u2 = udiv i64 200, %v2319 320  %c1 = load i64, ptr %c321  %ca2 = getelementptr i64, ptr %c, i32 1322  %c2 = load i64, ptr %ca2323  %add1 = add i64 %u1, %c1324  %add2 = add i64 %u2, %c2325 326  store i64 %add1, ptr %b327  %b2 = getelementptr i64, ptr %b, i32 1328  store i64 %add2, ptr %b2329  ret void330}331 332; Variant of test10 block invariant operands to the udivs333; FIXME: This is wrong, we're hoisting a faulting udiv above an infinite loop.334define void @test11(i64 %x, i64 %y, ptr %b, ptr %c) {335; CHECK-LABEL: @test11(336; CHECK-NEXT:    [[U1:%.*]] = udiv i64 200, [[X:%.*]]337; CHECK-NEXT:    store i64 [[U1]], ptr [[B:%.*]], align 8338; CHECK-NEXT:    [[TMP1:%.*]] = call i64 @may_inf_loop_ro()339; CHECK-NEXT:    [[U2:%.*]] = udiv i64 200, [[Y:%.*]]340; CHECK-NEXT:    [[TMP2:%.*]] = load <2 x i64>, ptr [[C:%.*]], align 8341; CHECK-NEXT:    [[TMP3:%.*]] = insertelement <2 x i64> poison, i64 [[U1]], i32 0342; CHECK-NEXT:    [[TMP4:%.*]] = insertelement <2 x i64> [[TMP3]], i64 [[U2]], i32 1343; CHECK-NEXT:    [[TMP5:%.*]] = add <2 x i64> [[TMP4]], [[TMP2]]344; CHECK-NEXT:    store <2 x i64> [[TMP5]], ptr [[B]], align 8345; CHECK-NEXT:    ret void346;347  %u1 = udiv i64 200, %x348  store i64 %u1, ptr %b349  call i64 @may_inf_loop_ro()350  %u2 = udiv i64 200, %y351 352  %c1 = load i64, ptr %c353  %ca2 = getelementptr i64, ptr %c, i32 1354  %c2 = load i64, ptr %ca2355  %add1 = add i64 %u1, %c1356  %add2 = add i64 %u2, %c2357 358  store i64 %add1, ptr %b359  %b2 = getelementptr i64, ptr %b, i32 1360  store i64 %add2, ptr %b2361  ret void362}363