578 lines · plain
1; NOTE: Assertions have been autogenerated by utils/update_test_checks.py2; RUN: opt < %s -passes=slp-vectorizer -S | FileCheck %s3 4; Check propagation of optional IR flags (PR20802). For a flag to5; propagate from scalar instructions to their vector replacement,6; *all* scalar instructions must have the flag.7 8target datalayout = "e-m:o-i64:64-f80:128-n8:16:32:64-S128"9target triple = "x86_64-unknown-unknown"10 11define void @exact(ptr %x) {12; CHECK-LABEL: @exact(13; CHECK-NEXT: [[TMP2:%.*]] = load <4 x i32>, ptr [[X:%.*]], align 414; CHECK-NEXT: [[TMP3:%.*]] = lshr exact <4 x i32> [[TMP2]], splat (i32 1)15; CHECK-NEXT: store <4 x i32> [[TMP3]], ptr [[X]], align 416; CHECK-NEXT: ret void17;18 %idx2 = getelementptr inbounds i32, ptr %x, i64 119 %idx3 = getelementptr inbounds i32, ptr %x, i64 220 %idx4 = getelementptr inbounds i32, ptr %x, i64 321 22 %load1 = load i32, ptr %x, align 423 %load2 = load i32, ptr %idx2, align 424 %load3 = load i32, ptr %idx3, align 425 %load4 = load i32, ptr %idx4, align 426 27 %op1 = lshr exact i32 %load1, 128 %op2 = lshr exact i32 %load2, 129 %op3 = lshr exact i32 %load3, 130 %op4 = lshr exact i32 %load4, 131 32 store i32 %op1, ptr %x, align 433 store i32 %op2, ptr %idx2, align 434 store i32 %op3, ptr %idx3, align 435 store i32 %op4, ptr %idx4, align 436 37 ret void38}39 40define void @not_exact(ptr %x) {41; CHECK-LABEL: @not_exact(42; CHECK-NEXT: [[TMP2:%.*]] = load <4 x i32>, ptr [[X:%.*]], align 443; CHECK-NEXT: [[TMP3:%.*]] = lshr <4 x i32> [[TMP2]], splat (i32 1)44; CHECK-NEXT: store <4 x i32> [[TMP3]], ptr [[X]], align 445; CHECK-NEXT: ret void46;47 %idx2 = getelementptr inbounds i32, ptr %x, i64 148 %idx3 = getelementptr inbounds i32, ptr %x, i64 249 %idx4 = getelementptr inbounds i32, ptr %x, i64 350 51 %load1 = load i32, ptr %x, align 452 %load2 = load i32, ptr %idx2, align 453 %load3 = load i32, ptr %idx3, align 454 %load4 = load i32, ptr %idx4, align 455 56 %op1 = lshr exact i32 %load1, 157 %op2 = lshr i32 %load2, 158 %op3 = lshr exact i32 %load3, 159 %op4 = lshr exact i32 %load4, 160 61 store i32 %op1, ptr %x, align 462 store i32 %op2, ptr %idx2, align 463 store i32 %op3, ptr %idx3, align 464 store i32 %op4, ptr %idx4, align 465 66 ret void67}68 69define void @nsw(ptr %x) {70; CHECK-LABEL: @nsw(71; CHECK-NEXT: [[TMP2:%.*]] = load <4 x i32>, ptr [[X:%.*]], align 472; CHECK-NEXT: [[TMP3:%.*]] = add nsw <4 x i32> [[TMP2]], splat (i32 1)73; CHECK-NEXT: store <4 x i32> [[TMP3]], ptr [[X]], align 474; CHECK-NEXT: ret void75;76 %idx2 = getelementptr inbounds i32, ptr %x, i64 177 %idx3 = getelementptr inbounds i32, ptr %x, i64 278 %idx4 = getelementptr inbounds i32, ptr %x, i64 379 80 %load1 = load i32, ptr %x, align 481 %load2 = load i32, ptr %idx2, align 482 %load3 = load i32, ptr %idx3, align 483 %load4 = load i32, ptr %idx4, align 484 85 %op1 = add nsw i32 %load1, 186 %op2 = add nsw i32 %load2, 187 %op3 = add nsw i32 %load3, 188 %op4 = add nsw i32 %load4, 189 90 store i32 %op1, ptr %x, align 491 store i32 %op2, ptr %idx2, align 492 store i32 %op3, ptr %idx3, align 493 store i32 %op4, ptr %idx4, align 494 95 ret void96}97 98define void @not_nsw(ptr %x) {99; CHECK-LABEL: @not_nsw(100; CHECK-NEXT: [[TMP2:%.*]] = load <4 x i32>, ptr [[X:%.*]], align 4101; CHECK-NEXT: [[TMP3:%.*]] = add <4 x i32> [[TMP2]], splat (i32 1)102; CHECK-NEXT: store <4 x i32> [[TMP3]], ptr [[X]], align 4103; CHECK-NEXT: ret void104;105 %idx2 = getelementptr inbounds i32, ptr %x, i64 1106 %idx3 = getelementptr inbounds i32, ptr %x, i64 2107 %idx4 = getelementptr inbounds i32, ptr %x, i64 3108 109 %load1 = load i32, ptr %x, align 4110 %load2 = load i32, ptr %idx2, align 4111 %load3 = load i32, ptr %idx3, align 4112 %load4 = load i32, ptr %idx4, align 4113 114 %op1 = add nsw i32 %load1, 1115 %op2 = add nsw i32 %load2, 1116 %op3 = add nsw i32 %load3, 1117 %op4 = add i32 %load4, 1118 119 store i32 %op1, ptr %x, align 4120 store i32 %op2, ptr %idx2, align 4121 store i32 %op3, ptr %idx3, align 4122 store i32 %op4, ptr %idx4, align 4123 124 ret void125}126 127define void @nuw(ptr %x) {128; CHECK-LABEL: @nuw(129; CHECK-NEXT: [[TMP2:%.*]] = load <4 x i32>, ptr [[X:%.*]], align 4130; CHECK-NEXT: [[TMP3:%.*]] = add nuw <4 x i32> [[TMP2]], splat (i32 1)131; CHECK-NEXT: store <4 x i32> [[TMP3]], ptr [[X]], align 4132; CHECK-NEXT: ret void133;134 %idx2 = getelementptr inbounds i32, ptr %x, i64 1135 %idx3 = getelementptr inbounds i32, ptr %x, i64 2136 %idx4 = getelementptr inbounds i32, ptr %x, i64 3137 138 %load1 = load i32, ptr %x, align 4139 %load2 = load i32, ptr %idx2, align 4140 %load3 = load i32, ptr %idx3, align 4141 %load4 = load i32, ptr %idx4, align 4142 143 %op1 = add nuw i32 %load1, 1144 %op2 = add nuw i32 %load2, 1145 %op3 = add nuw i32 %load3, 1146 %op4 = add nuw i32 %load4, 1147 148 store i32 %op1, ptr %x, align 4149 store i32 %op2, ptr %idx2, align 4150 store i32 %op3, ptr %idx3, align 4151 store i32 %op4, ptr %idx4, align 4152 153 ret void154}155 156define void @not_nuw(ptr %x) {157; CHECK-LABEL: @not_nuw(158; CHECK-NEXT: [[TMP2:%.*]] = load <4 x i32>, ptr [[X:%.*]], align 4159; CHECK-NEXT: [[TMP3:%.*]] = add <4 x i32> [[TMP2]], splat (i32 1)160; CHECK-NEXT: store <4 x i32> [[TMP3]], ptr [[X]], align 4161; CHECK-NEXT: ret void162;163 %idx2 = getelementptr inbounds i32, ptr %x, i64 1164 %idx3 = getelementptr inbounds i32, ptr %x, i64 2165 %idx4 = getelementptr inbounds i32, ptr %x, i64 3166 167 %load1 = load i32, ptr %x, align 4168 %load2 = load i32, ptr %idx2, align 4169 %load3 = load i32, ptr %idx3, align 4170 %load4 = load i32, ptr %idx4, align 4171 172 %op1 = add nuw i32 %load1, 1173 %op2 = add i32 %load2, 1174 %op3 = add i32 %load3, 1175 %op4 = add nuw i32 %load4, 1176 177 store i32 %op1, ptr %x, align 4178 store i32 %op2, ptr %idx2, align 4179 store i32 %op3, ptr %idx3, align 4180 store i32 %op4, ptr %idx4, align 4181 182 ret void183}184 185define void @not_nsw_but_nuw(ptr %x) {186; CHECK-LABEL: @not_nsw_but_nuw(187; CHECK-NEXT: [[TMP2:%.*]] = load <4 x i32>, ptr [[X:%.*]], align 4188; CHECK-NEXT: [[TMP3:%.*]] = add nuw <4 x i32> [[TMP2]], splat (i32 1)189; CHECK-NEXT: store <4 x i32> [[TMP3]], ptr [[X]], align 4190; CHECK-NEXT: ret void191;192 %idx2 = getelementptr inbounds i32, ptr %x, i64 1193 %idx3 = getelementptr inbounds i32, ptr %x, i64 2194 %idx4 = getelementptr inbounds i32, ptr %x, i64 3195 196 %load1 = load i32, ptr %x, align 4197 %load2 = load i32, ptr %idx2, align 4198 %load3 = load i32, ptr %idx3, align 4199 %load4 = load i32, ptr %idx4, align 4200 201 %op1 = add nuw i32 %load1, 1202 %op2 = add nuw nsw i32 %load2, 1203 %op3 = add nuw nsw i32 %load3, 1204 %op4 = add nuw i32 %load4, 1205 206 store i32 %op1, ptr %x, align 4207 store i32 %op2, ptr %idx2, align 4208 store i32 %op3, ptr %idx3, align 4209 store i32 %op4, ptr %idx4, align 4210 211 ret void212}213 214define void @nnan(ptr %x) {215; CHECK-LABEL: @nnan(216; CHECK-NEXT: [[TMP2:%.*]] = load <4 x float>, ptr [[X:%.*]], align 4217; CHECK-NEXT: [[TMP3:%.*]] = fadd nnan <4 x float> [[TMP2]], splat (float 1.000000e+00)218; CHECK-NEXT: store <4 x float> [[TMP3]], ptr [[X]], align 4219; CHECK-NEXT: ret void220;221 %idx2 = getelementptr inbounds float, ptr %x, i64 1222 %idx3 = getelementptr inbounds float, ptr %x, i64 2223 %idx4 = getelementptr inbounds float, ptr %x, i64 3224 225 %load1 = load float, ptr %x, align 4226 %load2 = load float, ptr %idx2, align 4227 %load3 = load float, ptr %idx3, align 4228 %load4 = load float, ptr %idx4, align 4229 230 %op1 = fadd fast nnan float %load1, 1.0231 %op2 = fadd nnan ninf float %load2, 1.0232 %op3 = fadd nsz nnan float %load3, 1.0233 %op4 = fadd arcp nnan float %load4, 1.0234 235 store float %op1, ptr %x, align 4236 store float %op2, ptr %idx2, align 4237 store float %op3, ptr %idx3, align 4238 store float %op4, ptr %idx4, align 4239 240 ret void241}242 243define void @not_nnan(ptr %x) {244; CHECK-LABEL: @not_nnan(245; CHECK-NEXT: [[TMP2:%.*]] = load <4 x float>, ptr [[X:%.*]], align 4246; CHECK-NEXT: [[TMP3:%.*]] = fadd <4 x float> [[TMP2]], splat (float 1.000000e+00)247; CHECK-NEXT: store <4 x float> [[TMP3]], ptr [[X]], align 4248; CHECK-NEXT: ret void249;250 %idx2 = getelementptr inbounds float, ptr %x, i64 1251 %idx3 = getelementptr inbounds float, ptr %x, i64 2252 %idx4 = getelementptr inbounds float, ptr %x, i64 3253 254 %load1 = load float, ptr %x, align 4255 %load2 = load float, ptr %idx2, align 4256 %load3 = load float, ptr %idx3, align 4257 %load4 = load float, ptr %idx4, align 4258 259 %op1 = fadd nnan float %load1, 1.0260 %op2 = fadd ninf float %load2, 1.0261 %op3 = fadd nsz float %load3, 1.0262 %op4 = fadd arcp float %load4, 1.0263 264 store float %op1, ptr %x, align 4265 store float %op2, ptr %idx2, align 4266 store float %op3, ptr %idx3, align 4267 store float %op4, ptr %idx4, align 4268 269 ret void270}271 272define void @only_fast(ptr %x) {273; CHECK-LABEL: @only_fast(274; CHECK-NEXT: [[TMP2:%.*]] = load <4 x float>, ptr [[X:%.*]], align 4275; CHECK-NEXT: [[TMP3:%.*]] = fadd fast <4 x float> [[TMP2]], splat (float 1.000000e+00)276; CHECK-NEXT: store <4 x float> [[TMP3]], ptr [[X]], align 4277; CHECK-NEXT: ret void278;279 %idx2 = getelementptr inbounds float, ptr %x, i64 1280 %idx3 = getelementptr inbounds float, ptr %x, i64 2281 %idx4 = getelementptr inbounds float, ptr %x, i64 3282 283 %load1 = load float, ptr %x, align 4284 %load2 = load float, ptr %idx2, align 4285 %load3 = load float, ptr %idx3, align 4286 %load4 = load float, ptr %idx4, align 4287 288 %op1 = fadd fast nnan float %load1, 1.0289 %op2 = fadd fast nnan ninf float %load2, 1.0290 %op3 = fadd fast nsz nnan float %load3, 1.0291 %op4 = fadd arcp nnan fast float %load4, 1.0292 293 store float %op1, ptr %x, align 4294 store float %op2, ptr %idx2, align 4295 store float %op3, ptr %idx3, align 4296 store float %op4, ptr %idx4, align 4297 298 ret void299}300 301define void @only_arcp(ptr %x) {302; CHECK-LABEL: @only_arcp(303; CHECK-NEXT: [[TMP2:%.*]] = load <4 x float>, ptr [[X:%.*]], align 4304; CHECK-NEXT: [[TMP3:%.*]] = fadd arcp <4 x float> [[TMP2]], splat (float 1.000000e+00)305; CHECK-NEXT: store <4 x float> [[TMP3]], ptr [[X]], align 4306; CHECK-NEXT: ret void307;308 %idx2 = getelementptr inbounds float, ptr %x, i64 1309 %idx3 = getelementptr inbounds float, ptr %x, i64 2310 %idx4 = getelementptr inbounds float, ptr %x, i64 3311 312 %load1 = load float, ptr %x, align 4313 %load2 = load float, ptr %idx2, align 4314 %load3 = load float, ptr %idx3, align 4315 %load4 = load float, ptr %idx4, align 4316 317 %op1 = fadd fast float %load1, 1.0318 %op2 = fadd fast float %load2, 1.0319 %op3 = fadd fast float %load3, 1.0320 %op4 = fadd arcp float %load4, 1.0321 322 store float %op1, ptr %x, align 4323 store float %op2, ptr %idx2, align 4324 store float %op3, ptr %idx3, align 4325 store float %op4, ptr %idx4, align 4326 327 ret void328}329 330define void @addsub_all_nsw(ptr %x) {331; CHECK-LABEL: @addsub_all_nsw(332; CHECK-NEXT: [[TMP2:%.*]] = load <4 x i32>, ptr [[X:%.*]], align 4333; CHECK-NEXT: [[TMP5:%.*]] = add nsw <4 x i32> [[TMP2]], <i32 1, i32 -1, i32 1, i32 -1>334; CHECK-NEXT: store <4 x i32> [[TMP5]], ptr [[X]], align 4335; CHECK-NEXT: ret void336;337 %idx2 = getelementptr inbounds i32, ptr %x, i64 1338 %idx3 = getelementptr inbounds i32, ptr %x, i64 2339 %idx4 = getelementptr inbounds i32, ptr %x, i64 3340 341 %load1 = load i32, ptr %x, align 4342 %load2 = load i32, ptr %idx2, align 4343 %load3 = load i32, ptr %idx3, align 4344 %load4 = load i32, ptr %idx4, align 4345 346 %op1 = add nsw i32 %load1, 1347 %op2 = sub nsw i32 %load2, 1348 %op3 = add nsw i32 %load3, 1349 %op4 = sub nsw i32 %load4, 1350 351 store i32 %op1, ptr %x, align 4352 store i32 %op2, ptr %idx2, align 4353 store i32 %op3, ptr %idx3, align 4354 store i32 %op4, ptr %idx4, align 4355 356 ret void357}358 359define void @addsub_some_nsw(ptr %x) {360; CHECK-LABEL: @addsub_some_nsw(361; CHECK-NEXT: [[TMP2:%.*]] = load <4 x i32>, ptr [[X:%.*]], align 4362; CHECK-NEXT: [[TMP5:%.*]] = add <4 x i32> [[TMP2]], <i32 1, i32 -1, i32 1, i32 -1>363; CHECK-NEXT: store <4 x i32> [[TMP5]], ptr [[X]], align 4364; CHECK-NEXT: ret void365;366 %idx2 = getelementptr inbounds i32, ptr %x, i64 1367 %idx3 = getelementptr inbounds i32, ptr %x, i64 2368 %idx4 = getelementptr inbounds i32, ptr %x, i64 3369 370 %load1 = load i32, ptr %x, align 4371 %load2 = load i32, ptr %idx2, align 4372 %load3 = load i32, ptr %idx3, align 4373 %load4 = load i32, ptr %idx4, align 4374 375 %op1 = add nsw i32 %load1, 1376 %op2 = sub nsw i32 %load2, 1377 %op3 = add nsw i32 %load3, 1378 %op4 = sub i32 %load4, 1379 380 store i32 %op1, ptr %x, align 4381 store i32 %op2, ptr %idx2, align 4382 store i32 %op3, ptr %idx3, align 4383 store i32 %op4, ptr %idx4, align 4384 385 ret void386}387 388define void @addsub_no_nsw(ptr %x) {389; CHECK-LABEL: @addsub_no_nsw(390; CHECK-NEXT: [[TMP2:%.*]] = load <4 x i32>, ptr [[X:%.*]], align 4391; CHECK-NEXT: [[TMP5:%.*]] = add <4 x i32> [[TMP2]], <i32 1, i32 -1, i32 1, i32 -1>392; CHECK-NEXT: store <4 x i32> [[TMP5]], ptr [[X]], align 4393; CHECK-NEXT: ret void394;395 %idx2 = getelementptr inbounds i32, ptr %x, i64 1396 %idx3 = getelementptr inbounds i32, ptr %x, i64 2397 %idx4 = getelementptr inbounds i32, ptr %x, i64 3398 399 %load1 = load i32, ptr %x, align 4400 %load2 = load i32, ptr %idx2, align 4401 %load3 = load i32, ptr %idx3, align 4402 %load4 = load i32, ptr %idx4, align 4403 404 %op1 = add i32 %load1, 1405 %op2 = sub nsw i32 %load2, 1406 %op3 = add nsw i32 %load3, 1407 %op4 = sub i32 %load4, 1408 409 store i32 %op1, ptr %x, align 4410 store i32 %op2, ptr %idx2, align 4411 store i32 %op3, ptr %idx3, align 4412 store i32 %op4, ptr %idx4, align 4413 414 ret void415}416 417define void @fcmp_fast(ptr %x) #1 {418; CHECK-LABEL: @fcmp_fast(419; CHECK-NEXT: [[TMP2:%.*]] = load <2 x double>, ptr [[X:%.*]], align 8420; CHECK-NEXT: [[TMP3:%.*]] = fcmp fast oge <2 x double> [[TMP2]], zeroinitializer421; CHECK-NEXT: [[TMP4:%.*]] = fsub fast <2 x double> splat (double -0.000000e+00), [[TMP2]]422; CHECK-NEXT: [[TMP5:%.*]] = select <2 x i1> [[TMP3]], <2 x double> [[TMP2]], <2 x double> [[TMP4]]423; CHECK-NEXT: store <2 x double> [[TMP5]], ptr [[X]], align 8424; CHECK-NEXT: ret void425;426 %idx2 = getelementptr inbounds double, ptr %x, i64 1427 428 %load1 = load double, ptr %x, align 8429 %load2 = load double, ptr %idx2, align 8430 431 %cmp1 = fcmp fast oge double %load1, 0.000000e+00432 %cmp2 = fcmp fast oge double %load2, 0.000000e+00433 434 %sub1 = fsub fast double -0.000000e+00, %load1435 %sub2 = fsub fast double -0.000000e+00, %load2436 437 %sel1 = select i1 %cmp1, double %load1, double %sub1438 %sel2 = select i1 %cmp2, double %load2, double %sub2439 440 store double %sel1, ptr %x, align 8441 store double %sel2, ptr %idx2, align 8442 443 ret void444}445 446define void @fcmp_fast_unary_fneg(ptr %x) #1 {447; CHECK-LABEL: @fcmp_fast_unary_fneg(448; CHECK-NEXT: [[TMP2:%.*]] = load <2 x double>, ptr [[X:%.*]], align 8449; CHECK-NEXT: [[TMP3:%.*]] = fcmp fast oge <2 x double> [[TMP2]], zeroinitializer450; CHECK-NEXT: [[TMP4:%.*]] = fneg fast <2 x double> [[TMP2]]451; CHECK-NEXT: [[TMP5:%.*]] = select <2 x i1> [[TMP3]], <2 x double> [[TMP2]], <2 x double> [[TMP4]]452; CHECK-NEXT: store <2 x double> [[TMP5]], ptr [[X]], align 8453; CHECK-NEXT: ret void454;455 %idx2 = getelementptr inbounds double, ptr %x, i64 1456 457 %load1 = load double, ptr %x, align 8458 %load2 = load double, ptr %idx2, align 8459 460 %cmp1 = fcmp fast oge double %load1, 0.000000e+00461 %cmp2 = fcmp fast oge double %load2, 0.000000e+00462 463 %sub1 = fneg fast double %load1464 %sub2 = fneg fast double %load2465 466 %sel1 = select i1 %cmp1, double %load1, double %sub1467 %sel2 = select i1 %cmp2, double %load2, double %sub2468 469 store double %sel1, ptr %x, align 8470 store double %sel2, ptr %idx2, align 8471 472 ret void473}474 475define void @fcmp_no_fast(ptr %x) #1 {476; CHECK-LABEL: @fcmp_no_fast(477; CHECK-NEXT: [[TMP2:%.*]] = load <2 x double>, ptr [[X:%.*]], align 8478; CHECK-NEXT: [[TMP3:%.*]] = fcmp oge <2 x double> [[TMP2]], zeroinitializer479; CHECK-NEXT: [[TMP4:%.*]] = fsub <2 x double> splat (double -0.000000e+00), [[TMP2]]480; CHECK-NEXT: [[TMP5:%.*]] = select <2 x i1> [[TMP3]], <2 x double> [[TMP2]], <2 x double> [[TMP4]]481; CHECK-NEXT: store <2 x double> [[TMP5]], ptr [[X]], align 8482; CHECK-NEXT: ret void483;484 %idx2 = getelementptr inbounds double, ptr %x, i64 1485 486 %load1 = load double, ptr %x, align 8487 %load2 = load double, ptr %idx2, align 8488 489 %cmp1 = fcmp fast oge double %load1, 0.000000e+00490 %cmp2 = fcmp oge double %load2, 0.000000e+00491 492 %sub1 = fsub fast double -0.000000e+00, %load1493 %sub2 = fsub double -0.000000e+00, %load2494 495 %sel1 = select i1 %cmp1, double %load1, double %sub1496 %sel2 = select i1 %cmp2, double %load2, double %sub2497 498 store double %sel1, ptr %x, align 8499 store double %sel2, ptr %idx2, align 8500 501 ret void502}503 504define void @fcmp_no_fast_unary_fneg(ptr %x) #1 {505; CHECK-LABEL: @fcmp_no_fast_unary_fneg(506; CHECK-NEXT: [[TMP2:%.*]] = load <2 x double>, ptr [[X:%.*]], align 8507; CHECK-NEXT: [[TMP3:%.*]] = fcmp oge <2 x double> [[TMP2]], zeroinitializer508; CHECK-NEXT: [[TMP4:%.*]] = fneg <2 x double> [[TMP2]]509; CHECK-NEXT: [[TMP5:%.*]] = select <2 x i1> [[TMP3]], <2 x double> [[TMP2]], <2 x double> [[TMP4]]510; CHECK-NEXT: store <2 x double> [[TMP5]], ptr [[X]], align 8511; CHECK-NEXT: ret void512;513 %idx2 = getelementptr inbounds double, ptr %x, i64 1514 515 %load1 = load double, ptr %x, align 8516 %load2 = load double, ptr %idx2, align 8517 518 %cmp1 = fcmp fast oge double %load1, 0.000000e+00519 %cmp2 = fcmp oge double %load2, 0.000000e+00520 521 %sub1 = fneg double %load1522 %sub2 = fneg double %load2523 524 %sel1 = select i1 %cmp1, double %load1, double %sub1525 %sel2 = select i1 %cmp2, double %load2, double %sub2526 527 store double %sel1, ptr %x, align 8528 store double %sel2, ptr %idx2, align 8529 530 ret void531}532 533declare double @llvm.fabs.f64(double) nounwind readnone534 535define void @call_fast(ptr %x) {536; CHECK-LABEL: @call_fast(537; CHECK-NEXT: [[TMP2:%.*]] = load <2 x double>, ptr [[X:%.*]], align 8538; CHECK-NEXT: [[TMP3:%.*]] = call fast <2 x double> @llvm.fabs.v2f64(<2 x double> [[TMP2]])539; CHECK-NEXT: store <2 x double> [[TMP3]], ptr [[X]], align 8540; CHECK-NEXT: ret void541;542 %idx2 = getelementptr inbounds double, ptr %x, i64 1543 544 %load1 = load double, ptr %x, align 8545 %load2 = load double, ptr %idx2, align 8546 547 %call1 = tail call fast double @llvm.fabs.f64(double %load1) nounwind readnone548 %call2 = tail call fast double @llvm.fabs.f64(double %load2) nounwind readnone549 550 store double %call1, ptr %x, align 8551 store double %call2, ptr %idx2, align 8552 553 ret void554}555 556define void @call_no_fast(ptr %x) {557; CHECK-LABEL: @call_no_fast(558; CHECK-NEXT: [[TMP2:%.*]] = load <2 x double>, ptr [[X:%.*]], align 8559; CHECK-NEXT: [[TMP3:%.*]] = call <2 x double> @llvm.fabs.v2f64(<2 x double> [[TMP2]])560; CHECK-NEXT: store <2 x double> [[TMP3]], ptr [[X]], align 8561; CHECK-NEXT: ret void562;563 %idx2 = getelementptr inbounds double, ptr %x, i64 1564 565 %load1 = load double, ptr %x, align 8566 %load2 = load double, ptr %idx2, align 8567 568 %call1 = tail call fast double @llvm.fabs.f64(double %load1) nounwind readnone569 %call2 = tail call double @llvm.fabs.f64(double %load2) nounwind readnone570 571 store double %call1, ptr %x, align 8572 store double %call2, ptr %idx2, align 8573 574 ret void575}576 577attributes #1 = { "target-features"="+avx" }578