brintos

brintos / llvm-project-archived public Read only

0
0
Text · 21.4 KiB · 0be7f50 Raw
636 lines · plain
1; NOTE: Assertions have been autogenerated by utils/update_test_checks.py2; RUN: opt < %s -passes=instcombine -S | FileCheck %s3 4; =========================================================================5;6;   Test FP factorization with patterns:7;   X * Z + Y * Z --> (X + Y) * Z (including all 4 commuted variants)8;   X * Z - Y * Z --> (X - Y) * Z (including all 4 commuted variants)9;   X / Z + Y / Z --> (X + Y) / Z10;   X / Z - Y / Z --> (X - Y) / Z11;12; =========================================================================13 14; Minimum FMF - the final result requires/propagates FMF.15 16define float @fmul_fadd(float %x, float %y, float %z) {17; CHECK-LABEL: @fmul_fadd(18; CHECK-NEXT:    [[TMP1:%.*]] = fadd reassoc nsz float [[X:%.*]], [[Y:%.*]]19; CHECK-NEXT:    [[R:%.*]] = fmul reassoc nsz float [[TMP1]], [[Z:%.*]]20; CHECK-NEXT:    ret float [[R]]21;22  %t1 = fmul float %x, %z23  %t2 = fmul float %y, %z24  %r = fadd reassoc nsz float %t1, %t225  ret float %r26}27 28; Verify vector types and commuted operands.29 30define <2 x float> @fmul_fadd_commute1_vec(<2 x float> %x, <2 x float> %y, <2 x float> %z) {31; CHECK-LABEL: @fmul_fadd_commute1_vec(32; CHECK-NEXT:    [[TMP1:%.*]] = fadd reassoc nsz <2 x float> [[X:%.*]], [[Y:%.*]]33; CHECK-NEXT:    [[R:%.*]] = fmul reassoc nsz <2 x float> [[TMP1]], [[Z:%.*]]34; CHECK-NEXT:    ret <2 x float> [[R]]35;36  %t1 = fmul <2 x float> %z, %x37  %t2 = fmul <2 x float> %z, %y38  %r = fadd reassoc nsz <2 x float> %t1, %t239  ret <2 x float> %r40}41 42; Verify vector types, commuted operands, FMF propagation.43 44define <2 x float> @fmul_fadd_commute2_vec(<2 x float> %x, <2 x float> %y, <2 x float> %z) {45; CHECK-LABEL: @fmul_fadd_commute2_vec(46; CHECK-NEXT:    [[TMP1:%.*]] = fadd reassoc ninf nsz <2 x float> [[X:%.*]], [[Y:%.*]]47; CHECK-NEXT:    [[R:%.*]] = fmul reassoc ninf nsz <2 x float> [[TMP1]], [[Z:%.*]]48; CHECK-NEXT:    ret <2 x float> [[R]]49;50  %t1 = fmul fast <2 x float> %x, %z51  %t2 = fmul nnan <2 x float> %z, %y52  %r = fadd reassoc nsz ninf <2 x float> %t1, %t253  ret <2 x float> %r54}55 56; Verify different scalar type, commuted operands, FMF propagation.57 58define double @fmul_fadd_commute3(double %x, double %y, double %z) {59; CHECK-LABEL: @fmul_fadd_commute3(60; CHECK-NEXT:    [[TMP1:%.*]] = fadd reassoc nnan nsz double [[X:%.*]], [[Y:%.*]]61; CHECK-NEXT:    [[R:%.*]] = fmul reassoc nnan nsz double [[TMP1]], [[Z:%.*]]62; CHECK-NEXT:    ret double [[R]]63;64  %t1 = fmul double %z, %x65  %t2 = fmul fast double %y, %z66  %r = fadd reassoc nsz nnan double %t1, %t267  ret double %r68}69 70; Negative test - verify the fold is not done with only 'reassoc' ('nsz' is required).71 72define float @fmul_fadd_not_enough_FMF(float %x, float %y, float %z) {73; CHECK-LABEL: @fmul_fadd_not_enough_FMF(74; CHECK-NEXT:    [[T1:%.*]] = fmul fast float [[X:%.*]], [[Z:%.*]]75; CHECK-NEXT:    [[T2:%.*]] = fmul fast float [[Y:%.*]], [[Z]]76; CHECK-NEXT:    [[R:%.*]] = fadd reassoc float [[T1]], [[T2]]77; CHECK-NEXT:    ret float [[R]]78;79  %t1 = fmul fast float %x, %z80  %t2 = fmul fast float %y, %z81  %r = fadd reassoc float %t1, %t282  ret float %r83}84 85declare void @use(float)86 87; Negative test - extra uses should disable the fold.88 89define float @fmul_fadd_uses1(float %x, float %y, float %z) {90; CHECK-LABEL: @fmul_fadd_uses1(91; CHECK-NEXT:    [[T1:%.*]] = fmul float [[Z:%.*]], [[X:%.*]]92; CHECK-NEXT:    [[T2:%.*]] = fmul float [[Y:%.*]], [[Z]]93; CHECK-NEXT:    [[R:%.*]] = fadd reassoc nsz float [[T1]], [[T2]]94; CHECK-NEXT:    call void @use(float [[T1]])95; CHECK-NEXT:    ret float [[R]]96;97  %t1 = fmul float %z, %x98  %t2 = fmul float %y, %z99  %r = fadd reassoc nsz float %t1, %t2100  call void @use(float %t1)101  ret float %r102}103 104; Negative test - extra uses should disable the fold.105 106define float @fmul_fadd_uses2(float %x, float %y, float %z) {107; CHECK-LABEL: @fmul_fadd_uses2(108; CHECK-NEXT:    [[T1:%.*]] = fmul float [[Z:%.*]], [[X:%.*]]109; CHECK-NEXT:    [[T2:%.*]] = fmul float [[Z]], [[Y:%.*]]110; CHECK-NEXT:    [[R:%.*]] = fadd reassoc nsz float [[T1]], [[T2]]111; CHECK-NEXT:    call void @use(float [[T2]])112; CHECK-NEXT:    ret float [[R]]113;114  %t1 = fmul float %z, %x115  %t2 = fmul float %z, %y116  %r = fadd reassoc nsz float %t1, %t2117  call void @use(float %t2)118  ret float %r119}120 121; Negative test - extra uses should disable the fold.122 123define float @fmul_fadd_uses3(float %x, float %y, float %z) {124; CHECK-LABEL: @fmul_fadd_uses3(125; CHECK-NEXT:    [[T1:%.*]] = fmul float [[X:%.*]], [[Z:%.*]]126; CHECK-NEXT:    [[T2:%.*]] = fmul float [[Z]], [[Y:%.*]]127; CHECK-NEXT:    [[R:%.*]] = fadd reassoc nsz float [[T1]], [[T2]]128; CHECK-NEXT:    call void @use(float [[T1]])129; CHECK-NEXT:    call void @use(float [[T2]])130; CHECK-NEXT:    ret float [[R]]131;132  %t1 = fmul float %x, %z133  %t2 = fmul float %z, %y134  %r = fadd reassoc nsz float %t1, %t2135  call void @use(float %t1)136  call void @use(float %t2)137  ret float %r138}139 140; Minimum FMF - the final result requires/propagates FMF.141 142define half @fmul_fsub(half %x, half %y, half %z) {143; CHECK-LABEL: @fmul_fsub(144; CHECK-NEXT:    [[TMP1:%.*]] = fsub reassoc nsz half [[X:%.*]], [[Y:%.*]]145; CHECK-NEXT:    [[R:%.*]] = fmul reassoc nsz half [[TMP1]], [[Z:%.*]]146; CHECK-NEXT:    ret half [[R]]147;148  %t1 = fmul half %x, %z149  %t2 = fmul half %y, %z150  %r = fsub reassoc nsz half %t1, %t2151  ret half %r152}153 154; Verify vector types and commuted operands.155 156define <2 x float> @fmul_fsub_commute1_vec(<2 x float> %x, <2 x float> %y, <2 x float> %z) {157; CHECK-LABEL: @fmul_fsub_commute1_vec(158; CHECK-NEXT:    [[TMP1:%.*]] = fsub reassoc nsz <2 x float> [[X:%.*]], [[Y:%.*]]159; CHECK-NEXT:    [[R:%.*]] = fmul reassoc nsz <2 x float> [[TMP1]], [[Z:%.*]]160; CHECK-NEXT:    ret <2 x float> [[R]]161;162  %t1 = fmul <2 x float> %z, %x163  %t2 = fmul <2 x float> %y, %z164  %r = fsub reassoc nsz <2 x float> %t1, %t2165  ret <2 x float> %r166}167 168; Verify vector types, commuted operands, FMF propagation.169 170define <2 x float> @fmul_fsub_commute2_vec(<2 x float> %x, <2 x float> %y, <2 x float> %z) {171; CHECK-LABEL: @fmul_fsub_commute2_vec(172; CHECK-NEXT:    [[TMP1:%.*]] = fsub reassoc ninf nsz <2 x float> [[X:%.*]], [[Y:%.*]]173; CHECK-NEXT:    [[R:%.*]] = fmul reassoc ninf nsz <2 x float> [[TMP1]], [[Z:%.*]]174; CHECK-NEXT:    ret <2 x float> [[R]]175;176  %t1 = fmul fast <2 x float> %x, %z177  %t2 = fmul nnan <2 x float> %z, %y178  %r = fsub reassoc nsz ninf <2 x float> %t1, %t2179  ret <2 x float> %r180}181 182; Verify different scalar type, commuted operands, FMF propagation.183 184define double @fmul_fsub_commute3(double %x, double %y, double %z) {185; CHECK-LABEL: @fmul_fsub_commute3(186; CHECK-NEXT:    [[TMP1:%.*]] = fsub reassoc nnan nsz double [[X:%.*]], [[Y:%.*]]187; CHECK-NEXT:    [[R:%.*]] = fmul reassoc nnan nsz double [[TMP1]], [[Z:%.*]]188; CHECK-NEXT:    ret double [[R]]189;190  %t1 = fmul double %z, %x191  %t2 = fmul fast double %z, %y192  %r = fsub reassoc nsz nnan double %t1, %t2193  ret double %r194}195 196; Negative test - verify the fold is not done with only 'nsz' ('reassoc' is required).197 198define float @fmul_fsub_not_enough_FMF(float %x, float %y, float %z) {199; CHECK-LABEL: @fmul_fsub_not_enough_FMF(200; CHECK-NEXT:    [[T1:%.*]] = fmul fast float [[Z:%.*]], [[X:%.*]]201; CHECK-NEXT:    [[T2:%.*]] = fmul fast float [[Y:%.*]], [[Z]]202; CHECK-NEXT:    [[R:%.*]] = fsub nsz float [[T1]], [[T2]]203; CHECK-NEXT:    ret float [[R]]204;205  %t1 = fmul fast float %z, %x206  %t2 = fmul fast float %y, %z207  %r = fsub nsz float %t1, %t2208  ret float %r209}210 211; Negative test - extra uses should disable the fold.212 213define float @fmul_fsub_uses1(float %x, float %y, float %z) {214; CHECK-LABEL: @fmul_fsub_uses1(215; CHECK-NEXT:    [[T1:%.*]] = fmul float [[X:%.*]], [[Z:%.*]]216; CHECK-NEXT:    [[T2:%.*]] = fmul float [[Y:%.*]], [[Z]]217; CHECK-NEXT:    [[R:%.*]] = fsub reassoc nsz float [[T1]], [[T2]]218; CHECK-NEXT:    call void @use(float [[T1]])219; CHECK-NEXT:    ret float [[R]]220;221  %t1 = fmul float %x, %z222  %t2 = fmul float %y, %z223  %r = fsub reassoc nsz float %t1, %t2224  call void @use(float %t1)225  ret float %r226}227 228; Negative test - extra uses should disable the fold.229 230define float @fmul_fsub_uses2(float %x, float %y, float %z) {231; CHECK-LABEL: @fmul_fsub_uses2(232; CHECK-NEXT:    [[T1:%.*]] = fmul float [[Z:%.*]], [[X:%.*]]233; CHECK-NEXT:    [[T2:%.*]] = fmul float [[Z]], [[Y:%.*]]234; CHECK-NEXT:    [[R:%.*]] = fsub reassoc nsz float [[T1]], [[T2]]235; CHECK-NEXT:    call void @use(float [[T2]])236; CHECK-NEXT:    ret float [[R]]237;238  %t1 = fmul float %z, %x239  %t2 = fmul float %z, %y240  %r = fsub reassoc nsz float %t1, %t2241  call void @use(float %t2)242  ret float %r243}244 245; Negative test - extra uses should disable the fold.246 247define float @fmul_fsub_uses3(float %x, float %y, float %z) {248; CHECK-LABEL: @fmul_fsub_uses3(249; CHECK-NEXT:    [[T1:%.*]] = fmul float [[X:%.*]], [[Z:%.*]]250; CHECK-NEXT:    [[T2:%.*]] = fmul float [[Y:%.*]], [[Z]]251; CHECK-NEXT:    [[R:%.*]] = fsub reassoc nsz float [[T1]], [[T2]]252; CHECK-NEXT:    call void @use(float [[T1]])253; CHECK-NEXT:    call void @use(float [[T2]])254; CHECK-NEXT:    ret float [[R]]255;256  %t1 = fmul float %x, %z257  %t2 = fmul float %y, %z258  %r = fsub reassoc nsz float %t1, %t2259  call void @use(float %t1)260  call void @use(float %t2)261  ret float %r262}263 264; Common divisor265 266define double @fdiv_fadd(double %x, double %y, double %z) {267; CHECK-LABEL: @fdiv_fadd(268; CHECK-NEXT:    [[TMP1:%.*]] = fadd reassoc nsz double [[X:%.*]], [[Y:%.*]]269; CHECK-NEXT:    [[R:%.*]] = fdiv reassoc nsz double [[TMP1]], [[Z:%.*]]270; CHECK-NEXT:    ret double [[R]]271;272  %t1 = fdiv double %x, %z273  %t2 = fdiv double %y, %z274  %r = fadd reassoc nsz double %t1, %t2275  ret double %r276}277 278define float @fdiv_fsub(float %x, float %y, float %z) {279; CHECK-LABEL: @fdiv_fsub(280; CHECK-NEXT:    [[TMP1:%.*]] = fsub reassoc nsz float [[X:%.*]], [[Y:%.*]]281; CHECK-NEXT:    [[R:%.*]] = fdiv reassoc nsz float [[TMP1]], [[Z:%.*]]282; CHECK-NEXT:    ret float [[R]]283;284  %t1 = fdiv fast float %x, %z285  %t2 = fdiv nnan float %y, %z286  %r = fsub reassoc nsz float %t1, %t2287  ret float %r288}289 290; Verify vector types.291 292define <2 x double> @fdiv_fadd_vec(<2 x double> %x, <2 x double> %y, <2 x double> %z) {293; CHECK-LABEL: @fdiv_fadd_vec(294; CHECK-NEXT:    [[TMP1:%.*]] = fadd reassoc nsz <2 x double> [[X:%.*]], [[Y:%.*]]295; CHECK-NEXT:    [[R:%.*]] = fdiv reassoc nsz <2 x double> [[TMP1]], [[Z:%.*]]296; CHECK-NEXT:    ret <2 x double> [[R]]297;298  %t1 = fdiv fast <2 x double> %x, %z299  %t2 = fdiv <2 x double> %y, %z300  %r = fadd reassoc nsz <2 x double> %t1, %t2301  ret <2 x double> %r302}303 304; Verify vector types.305 306define <2 x float> @fdiv_fsub_vec(<2 x float> %x, <2 x float> %y, <2 x float> %z) {307; CHECK-LABEL: @fdiv_fsub_vec(308; CHECK-NEXT:    [[TMP1:%.*]] = fsub reassoc nsz <2 x float> [[X:%.*]], [[Y:%.*]]309; CHECK-NEXT:    [[R:%.*]] = fdiv reassoc nsz <2 x float> [[TMP1]], [[Z:%.*]]310; CHECK-NEXT:    ret <2 x float> [[R]]311;312  %t1 = fdiv <2 x float> %x, %z313  %t2 = fdiv nnan <2 x float> %y, %z314  %r = fsub reassoc nsz <2 x float> %t1, %t2315  ret <2 x float> %r316}317 318; Negative test - common operand is not divisor.319 320define float @fdiv_fadd_commute1(float %x, float %y, float %z) {321; CHECK-LABEL: @fdiv_fadd_commute1(322; CHECK-NEXT:    [[T1:%.*]] = fdiv fast float [[Z:%.*]], [[Y:%.*]]323; CHECK-NEXT:    [[T2:%.*]] = fdiv fast float [[Z]], [[X:%.*]]324; CHECK-NEXT:    [[R:%.*]] = fadd fast float [[T1]], [[T2]]325; CHECK-NEXT:    ret float [[R]]326;327  %t1 = fdiv fast float %z, %y328  %t2 = fdiv fast float %z, %x329  %r = fadd fast float %t1, %t2330  ret float %r331}332 333; Negative test - common operand is not divisor.334 335define float @fdiv_fsub_commute2(float %x, float %y, float %z) {336; CHECK-LABEL: @fdiv_fsub_commute2(337; CHECK-NEXT:    [[T1:%.*]] = fdiv fast float [[Z:%.*]], [[Y:%.*]]338; CHECK-NEXT:    [[T2:%.*]] = fdiv fast float [[X:%.*]], [[Z]]339; CHECK-NEXT:    [[R:%.*]] = fsub fast float [[T1]], [[T2]]340; CHECK-NEXT:    ret float [[R]]341;342  %t1 = fdiv fast float %z, %y343  %t2 = fdiv fast float %x, %z344  %r = fsub fast float %t1, %t2345  ret float %r346}347 348; Negative test - verify the fold is not done with only 'nsz' ('reassoc' is required).349 350define float @fdiv_fadd_not_enough_FMF(float %x, float %y, float %z) {351; CHECK-LABEL: @fdiv_fadd_not_enough_FMF(352; CHECK-NEXT:    [[T1:%.*]] = fdiv fast float [[Y:%.*]], [[X:%.*]]353; CHECK-NEXT:    [[T2:%.*]] = fdiv fast float [[Z:%.*]], [[X]]354; CHECK-NEXT:    [[T3:%.*]] = fadd nsz float [[T1]], [[T2]]355; CHECK-NEXT:    ret float [[T3]]356;357  %t1 = fdiv fast float %y, %x358  %t2 = fdiv fast float %z, %x359  %t3 = fadd nsz float %t1, %t2360  ret float %t3361}362 363; Negative test - verify the fold is not done with only 'reassoc' ('nsz' is required).364 365define float @fdiv_fsub_not_enough_FMF(float %x, float %y, float %z) {366; CHECK-LABEL: @fdiv_fsub_not_enough_FMF(367; CHECK-NEXT:    [[T1:%.*]] = fdiv fast float [[Y:%.*]], [[X:%.*]]368; CHECK-NEXT:    [[T2:%.*]] = fdiv fast float [[Z:%.*]], [[X]]369; CHECK-NEXT:    [[T3:%.*]] = fsub reassoc float [[T1]], [[T2]]370; CHECK-NEXT:    ret float [[T3]]371;372  %t1 = fdiv fast float %y, %x373  %t2 = fdiv fast float %z, %x374  %t3 = fsub reassoc float %t1, %t2375  ret float %t3376}377 378; Negative test - extra uses should disable the fold.379 380define float @fdiv_fadd_uses1(float %x, float %y, float %z) {381; CHECK-LABEL: @fdiv_fadd_uses1(382; CHECK-NEXT:    [[T1:%.*]] = fdiv fast float [[X:%.*]], [[Z:%.*]]383; CHECK-NEXT:    [[T2:%.*]] = fdiv fast float [[Y:%.*]], [[Z]]384; CHECK-NEXT:    [[R:%.*]] = fadd fast float [[T1]], [[T2]]385; CHECK-NEXT:    call void @use(float [[T1]])386; CHECK-NEXT:    ret float [[R]]387;388  %t1 = fdiv fast float %x, %z389  %t2 = fdiv fast float %y, %z390  %r = fadd fast float %t1, %t2391  call void @use(float %t1)392  ret float %r393}394 395; Negative test - extra uses should disable the fold.396 397define float @fdiv_fsub_uses2(float %x, float %y, float %z) {398; CHECK-LABEL: @fdiv_fsub_uses2(399; CHECK-NEXT:    [[T1:%.*]] = fdiv fast float [[X:%.*]], [[Z:%.*]]400; CHECK-NEXT:    [[T2:%.*]] = fdiv fast float [[Y:%.*]], [[Z]]401; CHECK-NEXT:    [[R:%.*]] = fsub fast float [[T1]], [[T2]]402; CHECK-NEXT:    call void @use(float [[T2]])403; CHECK-NEXT:    ret float [[R]]404;405  %t1 = fdiv fast float %x, %z406  %t2 = fdiv fast float %y, %z407  %r = fsub fast float %t1, %t2408  call void @use(float %t2)409  ret float %r410}411 412; Negative test - extra uses should disable the fold.413 414define float @fdiv_fsub_uses3(float %x, float %y, float %z) {415; CHECK-LABEL: @fdiv_fsub_uses3(416; CHECK-NEXT:    [[T1:%.*]] = fdiv fast float [[X:%.*]], [[Z:%.*]]417; CHECK-NEXT:    [[T2:%.*]] = fdiv fast float [[Y:%.*]], [[Z]]418; CHECK-NEXT:    [[R:%.*]] = fsub fast float [[T1]], [[T2]]419; CHECK-NEXT:    call void @use(float [[T1]])420; CHECK-NEXT:    call void @use(float [[T2]])421; CHECK-NEXT:    ret float [[R]]422;423  %t1 = fdiv fast float %x, %z424  %t2 = fdiv fast float %y, %z425  %r = fsub fast float %t1, %t2426  call void @use(float %t1)427  call void @use(float %t2)428  ret float %r429}430 431; Constants are fine to combine if they are not denorms.432 433define float @fdiv_fadd_not_denorm(float %x) {434; CHECK-LABEL: @fdiv_fadd_not_denorm(435; CHECK-NEXT:    [[R:%.*]] = fdiv fast float 0x3818000000000000, [[X:%.*]]436; CHECK-NEXT:    ret float [[R]]437;438  %t1 = fdiv fast float 0x3810000000000000, %x439  %t2 = fdiv fast float 0x3800000000000000, %x440  %r = fadd fast float %t1, %t2441  ret float %r442}443 444; Negative test - disabled if x+y is denormal.445 446define float @fdiv_fadd_denorm(float %x) {447; CHECK-LABEL: @fdiv_fadd_denorm(448; CHECK-NEXT:    [[T1:%.*]] = fdiv fast float 0xB810000000000000, [[X:%.*]]449; CHECK-NEXT:    [[T2:%.*]] = fdiv fast float 0x3800000000000000, [[X]]450; CHECK-NEXT:    [[R:%.*]] = fadd fast float [[T1]], [[T2]]451; CHECK-NEXT:    ret float [[R]]452;453  %t1 = fdiv fast float 0xB810000000000000, %x454  %t2 = fdiv fast float 0x3800000000000000, %x455  %r = fadd fast float %t1, %t2456  ret float %r457}458 459; Negative test - disabled if x-y is denormal.460 461define float @fdiv_fsub_denorm(float %x) {462; CHECK-LABEL: @fdiv_fsub_denorm(463; CHECK-NEXT:    [[T1:%.*]] = fdiv fast float 0x3810000000000000, [[X:%.*]]464; CHECK-NEXT:    [[T2:%.*]] = fdiv fast float 0x3800000000000000, [[X]]465; CHECK-NEXT:    [[R:%.*]] = fsub fast float [[T1]], [[T2]]466; CHECK-NEXT:    ret float [[R]]467;468  %t1 = fdiv fast float 0x3810000000000000, %x469  %t2 = fdiv fast float 0x3800000000000000, %x470  %r = fsub fast float %t1, %t2471  ret float %r472}473 474define float @lerp_commute0(float %a, float %b, float %c) {475; CHECK-LABEL: @lerp_commute0(476; CHECK-NEXT:    [[TMP1:%.*]] = fsub fast float [[B:%.*]], [[A:%.*]]477; CHECK-NEXT:    [[TMP2:%.*]] = fmul fast float [[C:%.*]], [[TMP1]]478; CHECK-NEXT:    [[ADD:%.*]] = fadd fast float [[A]], [[TMP2]]479; CHECK-NEXT:    ret float [[ADD]]480;481  %sub = fsub fast float 1.0, %c482  %mul = fmul fast float %sub, %a483  %bc = fmul fast float %c, %b484  %add = fadd fast float %mul, %bc485  ret float %add486}487 488define <2 x float> @lerp_commute1(<2 x float> %a, <2 x float> %b, <2 x float> %c) {489; CHECK-LABEL: @lerp_commute1(490; CHECK-NEXT:    [[TMP1:%.*]] = fsub fast <2 x float> [[B:%.*]], [[A:%.*]]491; CHECK-NEXT:    [[TMP2:%.*]] = fmul fast <2 x float> [[C:%.*]], [[TMP1]]492; CHECK-NEXT:    [[ADD:%.*]] = fadd fast <2 x float> [[A]], [[TMP2]]493; CHECK-NEXT:    ret <2 x float> [[ADD]]494;495  %sub = fsub <2 x float> <float 1.0, float 1.0>, %c496  %mul = fmul <2 x float> %sub, %a497  %bc = fmul <2 x float> %c, %b498  %add = fadd fast <2 x float> %bc, %mul499  ret <2 x float> %add500}501 502define float @lerp_commute2(float %a, float %b, float %c) {503; CHECK-LABEL: @lerp_commute2(504; CHECK-NEXT:    [[TMP1:%.*]] = fsub reassoc nsz float [[B:%.*]], [[A:%.*]]505; CHECK-NEXT:    [[TMP2:%.*]] = fmul reassoc nsz float [[C:%.*]], [[TMP1]]506; CHECK-NEXT:    [[ADD:%.*]] = fadd reassoc nsz float [[A]], [[TMP2]]507; CHECK-NEXT:    ret float [[ADD]]508;509  %sub = fsub float 1.0, %c510  %mul = fmul float %sub, %a511  %bc = fmul float %b, %c512  %add = fadd reassoc nsz float %mul, %bc513  ret float %add514}515 516define float @lerp_commute3(float %a, float %b, float %c) {517; CHECK-LABEL: @lerp_commute3(518; CHECK-NEXT:    [[TMP1:%.*]] = fsub reassoc ninf nsz float [[B:%.*]], [[A:%.*]]519; CHECK-NEXT:    [[TMP2:%.*]] = fmul reassoc ninf nsz float [[C:%.*]], [[TMP1]]520; CHECK-NEXT:    [[ADD:%.*]] = fadd reassoc ninf nsz float [[A]], [[TMP2]]521; CHECK-NEXT:    ret float [[ADD]]522;523  %sub = fsub fast float 1.0, %c524  %mul = fmul float %sub, %a525  %bc = fmul float %b, %c526  %add = fadd reassoc nsz ninf float %bc, %mul527  ret float %add528}529 530define double @lerp_commute4(double %a, double %b, double %c) {531; CHECK-LABEL: @lerp_commute4(532; CHECK-NEXT:    [[TMP1:%.*]] = fsub fast double [[B:%.*]], [[A:%.*]]533; CHECK-NEXT:    [[TMP2:%.*]] = fmul fast double [[C:%.*]], [[TMP1]]534; CHECK-NEXT:    [[ADD:%.*]] = fadd fast double [[A]], [[TMP2]]535; CHECK-NEXT:    ret double [[ADD]]536;537  %sub = fsub fast double 1.0, %c538  %mul = fmul fast double %a, %sub539  %bc = fmul fast double %c, %b540  %add = fadd fast double %mul, %bc541  ret double %add542}543 544define double @lerp_commute5(double %a, double %b, double %c) {545; CHECK-LABEL: @lerp_commute5(546; CHECK-NEXT:    [[TMP1:%.*]] = fsub fast double [[B:%.*]], [[A:%.*]]547; CHECK-NEXT:    [[TMP2:%.*]] = fmul fast double [[C:%.*]], [[TMP1]]548; CHECK-NEXT:    [[ADD:%.*]] = fadd fast double [[A]], [[TMP2]]549; CHECK-NEXT:    ret double [[ADD]]550;551  %sub = fsub fast double 1.0, %c552  %mul = fmul fast double %a, %sub553  %bc = fmul fast double %c, %b554  %add = fadd fast double %bc, %mul555  ret double %add556}557 558define half @lerp_commute6(half %a, half %b, half %c) {559; CHECK-LABEL: @lerp_commute6(560; CHECK-NEXT:    [[TMP1:%.*]] = fsub fast half [[B:%.*]], [[A:%.*]]561; CHECK-NEXT:    [[TMP2:%.*]] = fmul fast half [[C:%.*]], [[TMP1]]562; CHECK-NEXT:    [[ADD:%.*]] = fadd fast half [[A]], [[TMP2]]563; CHECK-NEXT:    ret half [[ADD]]564;565  %sub = fsub fast half 1.0, %c566  %mul = fmul fast half %a, %sub567  %bc = fmul fast half %b, %c568  %add = fadd fast half %mul, %bc569  ret half %add570}571 572define half @lerp_commute7(half %a, half %b, half %c) {573; CHECK-LABEL: @lerp_commute7(574; CHECK-NEXT:    [[TMP1:%.*]] = fsub fast half [[B:%.*]], [[A:%.*]]575; CHECK-NEXT:    [[TMP2:%.*]] = fmul fast half [[C:%.*]], [[TMP1]]576; CHECK-NEXT:    [[ADD:%.*]] = fadd fast half [[A]], [[TMP2]]577; CHECK-NEXT:    ret half [[ADD]]578;579  %sub = fsub fast half 1.0, %c580  %mul = fmul fast half %a, %sub581  %bc = fmul fast half %b, %c582  %add = fadd fast half %bc, %mul583  ret half %add584}585 586define float @lerp_extra_use1(float %a, float %b, float %c) {587; CHECK-LABEL: @lerp_extra_use1(588; CHECK-NEXT:    [[SUB:%.*]] = fsub fast float 1.000000e+00, [[C:%.*]]589; CHECK-NEXT:    [[MUL:%.*]] = fmul fast float [[A:%.*]], [[SUB]]590; CHECK-NEXT:    [[BC:%.*]] = fmul fast float [[B:%.*]], [[C]]591; CHECK-NEXT:    call void @use(float [[BC]])592; CHECK-NEXT:    [[ADD:%.*]] = fadd fast float [[BC]], [[MUL]]593; CHECK-NEXT:    ret float [[ADD]]594;595  %sub = fsub fast float 1.0, %c596  %mul = fmul fast float %a, %sub597  %bc = fmul fast float %b, %c598  call void @use(float %bc)599  %add = fadd fast float %bc, %mul600  ret float %add601}602 603define float @lerp_extra_use2(float %a, float %b, float %c) {604; CHECK-LABEL: @lerp_extra_use2(605; CHECK-NEXT:    [[SUB:%.*]] = fsub fast float 1.000000e+00, [[C:%.*]]606; CHECK-NEXT:    [[MUL:%.*]] = fmul fast float [[A:%.*]], [[SUB]]607; CHECK-NEXT:    call void @use(float [[MUL]])608; CHECK-NEXT:    [[BC:%.*]] = fmul fast float [[B:%.*]], [[C]]609; CHECK-NEXT:    [[ADD:%.*]] = fadd fast float [[BC]], [[MUL]]610; CHECK-NEXT:    ret float [[ADD]]611;612  %sub = fsub fast float 1.0, %c613  %mul = fmul fast float %a, %sub614  call void @use(float %mul)615  %bc = fmul fast float %b, %c616  %add = fadd fast float %bc, %mul617  ret float %add618}619 620define float @lerp_extra_use3(float %a, float %b, float %c) {621; CHECK-LABEL: @lerp_extra_use3(622; CHECK-NEXT:    [[SUB:%.*]] = fsub fast float 1.000000e+00, [[C:%.*]]623; CHECK-NEXT:    call void @use(float [[SUB]])624; CHECK-NEXT:    [[MUL:%.*]] = fmul fast float [[A:%.*]], [[SUB]]625; CHECK-NEXT:    [[BC:%.*]] = fmul fast float [[B:%.*]], [[C]]626; CHECK-NEXT:    [[ADD:%.*]] = fadd fast float [[BC]], [[MUL]]627; CHECK-NEXT:    ret float [[ADD]]628;629  %sub = fsub fast float 1.0, %c630  call void @use(float %sub)631  %mul = fmul fast float %a, %sub632  %bc = fmul fast float %b, %c633  %add = fadd fast float %bc, %mul634  ret float %add635}636