1149 lines · plain
1; NOTE: Assertions have been autogenerated by utils/update_test_checks.py2; RUN: opt < %s -passes=instcombine -S | FileCheck %s3; RUN: opt < %s -passes=instcombine -use-constant-fp-for-fixed-length-splat -S | FileCheck %s4 5declare void @use(float)6declare void @use_vec(<2 x float>)7declare float @llvm.vector.reduce.fadd.v4f32(float, <4 x float>)8 9; -x + y => y - x10 11define float @fneg_op0(float %x, float %y) {12; CHECK-LABEL: @fneg_op0(13; CHECK-NEXT: [[ADD:%.*]] = fsub float [[Y:%.*]], [[X:%.*]]14; CHECK-NEXT: ret float [[ADD]]15;16 %neg = fsub float -0.0, %x17 %add = fadd float %neg, %y18 ret float %add19}20 21; x + -y => x - y22 23define float @fneg_op1(float %x, float %y) {24; CHECK-LABEL: @fneg_op1(25; CHECK-NEXT: [[ADD:%.*]] = fsub float [[X:%.*]], [[Y:%.*]]26; CHECK-NEXT: ret float [[ADD]]27;28 %neg = fsub float -0.0, %y29 %add = fadd float %x, %neg30 ret float %add31}32 33; Z + (-X / Y) --> Z - (X / Y)34 35define double @fdiv_fneg1(double %x, double %y, double %pz) {36; CHECK-LABEL: @fdiv_fneg1(37; CHECK-NEXT: [[Z:%.*]] = frem double 4.200000e+01, [[PZ:%.*]]38; CHECK-NEXT: [[TMP1:%.*]] = fdiv double [[X:%.*]], [[Y:%.*]]39; CHECK-NEXT: [[R:%.*]] = fsub double [[Z]], [[TMP1]]40; CHECK-NEXT: ret double [[R]]41;42 %z = frem double 42.0, %pz ; thwart complexity-based canonicalization43 %neg = fsub double -0.000000e+00, %x44 %div = fdiv double %neg, %y45 %r = fadd double %z, %div46 ret double %r47}48 49; Z + (Y / -X) --> Z - (Y / X)50 51define <2 x double> @fdiv_fneg2(<2 x double> %x, <2 x double> %y, <2 x double> %pz) {52; CHECK-LABEL: @fdiv_fneg2(53; CHECK-NEXT: [[Z:%.*]] = frem <2 x double> <double 4.200000e+01, double 8.000000e+00>, [[PZ:%.*]]54; CHECK-NEXT: [[TMP1:%.*]] = fdiv <2 x double> [[Y:%.*]], [[X:%.*]]55; CHECK-NEXT: [[R:%.*]] = fsub <2 x double> [[Z]], [[TMP1]]56; CHECK-NEXT: ret <2 x double> [[R]]57;58 %z = frem <2 x double> <double 42.0, double 8.0>, %pz ; thwart complexity-based canonicalization59 %neg = fsub <2 x double> <double -0.0, double -0.0>, %x60 %div = fdiv <2 x double> %y, %neg61 %r = fadd <2 x double> %z, %div62 ret <2 x double> %r63}64 65; Z + (-X * Y) --> Z - (X * Y)66 67define double @fmul_fneg1(double %x, double %y, double %pz) {68; CHECK-LABEL: @fmul_fneg1(69; CHECK-NEXT: [[Z:%.*]] = frem double 4.200000e+01, [[PZ:%.*]]70; CHECK-NEXT: [[TMP1:%.*]] = fmul double [[X:%.*]], [[Y:%.*]]71; CHECK-NEXT: [[R:%.*]] = fsub double [[Z]], [[TMP1]]72; CHECK-NEXT: ret double [[R]]73;74 %z = frem double 42.0, %pz ; thwart complexity-based canonicalization75 %neg = fsub double -0.000000e+00, %x76 %mul = fmul double %neg, %y77 %r = fadd double %z, %mul78 ret double %r79}80 81; Z + (Y * -X) --> Z - (Y * X)82 83define double @fmul_fneg2(double %x, double %py, double %pz) {84; CHECK-LABEL: @fmul_fneg2(85; CHECK-NEXT: [[Y:%.*]] = frem double -4.200000e+01, [[PY:%.*]]86; CHECK-NEXT: [[Z:%.*]] = frem double 4.200000e+01, [[PZ:%.*]]87; CHECK-NEXT: [[TMP1:%.*]] = fmul double [[X:%.*]], [[Y]]88; CHECK-NEXT: [[R:%.*]] = fsub double [[Z]], [[TMP1]]89; CHECK-NEXT: ret double [[R]]90;91 %y = frem double -42.0, %py ; thwart complexity-based canonicalization92 %z = frem double 42.0, %pz ; thwart complexity-based canonicalization93 %neg = fsub double -0.000000e+00, %x94 %mul = fmul double %y, %neg95 %r = fadd double %z, %mul96 ret double %r97}98 99; (-X / Y) + Z --> Z - (X / Y)100 101define double @fdiv_fneg1_commute(double %x, double %y, double %pz) {102; CHECK-LABEL: @fdiv_fneg1_commute(103; CHECK-NEXT: [[Z:%.*]] = frem double 4.200000e+01, [[PZ:%.*]]104; CHECK-NEXT: [[TMP1:%.*]] = fdiv double [[X:%.*]], [[Y:%.*]]105; CHECK-NEXT: [[R:%.*]] = fsub double [[Z]], [[TMP1]]106; CHECK-NEXT: ret double [[R]]107;108 %z = frem double 42.0, %pz ; thwart complexity-based canonicalization109 %neg = fsub double -0.000000e+00, %x110 %div = fdiv double %neg, %y111 %r = fadd double %div, %z112 ret double %r113}114 115; (Y / -X) + Z --> Z - (Y / X)116 117define <2 x double> @fdiv_fneg2_commute(<2 x double> %x, <2 x double> %y, <2 x double> %pz) {118; CHECK-LABEL: @fdiv_fneg2_commute(119; CHECK-NEXT: [[Z:%.*]] = frem <2 x double> <double 4.200000e+01, double 8.000000e+00>, [[PZ:%.*]]120; CHECK-NEXT: [[TMP1:%.*]] = fdiv <2 x double> [[Y:%.*]], [[X:%.*]]121; CHECK-NEXT: [[R:%.*]] = fsub <2 x double> [[Z]], [[TMP1]]122; CHECK-NEXT: ret <2 x double> [[R]]123;124 %z = frem <2 x double> <double 42.0, double 8.0>, %pz ; thwart complexity-based canonicalization125 %neg = fsub <2 x double> <double -0.0, double -0.0>, %x126 %div = fdiv <2 x double> %y, %neg127 %r = fadd <2 x double> %div, %z128 ret <2 x double> %r129}130 131; (-X * Y) + Z --> Z - (X * Y)132 133define double @fmul_fneg1_commute(double %x, double %y, double %pz) {134; CHECK-LABEL: @fmul_fneg1_commute(135; CHECK-NEXT: [[Z:%.*]] = frem double 4.200000e+01, [[PZ:%.*]]136; CHECK-NEXT: [[TMP1:%.*]] = fmul double [[X:%.*]], [[Y:%.*]]137; CHECK-NEXT: [[R:%.*]] = fsub double [[Z]], [[TMP1]]138; CHECK-NEXT: ret double [[R]]139;140 %z = frem double 42.0, %pz ; thwart complexity-based canonicalization141 %neg = fsub double -0.000000e+00, %x142 %mul = fmul double %neg, %y143 %r = fadd double %mul, %z144 ret double %r145}146 147; (Y * -X) + Z --> Z - (Y * X)148 149define double @fmul_fneg2_commute(double %x, double %py, double %pz) {150; CHECK-LABEL: @fmul_fneg2_commute(151; CHECK-NEXT: [[Y:%.*]] = frem double 4.100000e+01, [[PY:%.*]]152; CHECK-NEXT: [[Z:%.*]] = frem double 4.200000e+01, [[PZ:%.*]]153; CHECK-NEXT: [[TMP1:%.*]] = fmul double [[X:%.*]], [[Y]]154; CHECK-NEXT: [[R:%.*]] = fsub double [[Z]], [[TMP1]]155; CHECK-NEXT: ret double [[R]]156;157 %y = frem double 41.0, %py ; thwart complexity-based canonicalization158 %z = frem double 42.0, %pz ; thwart complexity-based canonicalization159 %neg = fsub double -0.000000e+00, %x160 %mul = fmul double %y, %neg161 %r = fadd double %mul, %z162 ret double %r163}164 165; Z + (-X / Y) - extra use means we can't transform to fsub without an extra instruction166 167define float @fdiv_fneg1_extra_use(float %x, float %y, float %pz) {168; CHECK-LABEL: @fdiv_fneg1_extra_use(169; CHECK-NEXT: [[Z:%.*]] = frem float 4.200000e+01, [[PZ:%.*]]170; CHECK-NEXT: [[NEG:%.*]] = fneg float [[X:%.*]]171; CHECK-NEXT: [[DIV:%.*]] = fdiv float [[NEG]], [[Y:%.*]]172; CHECK-NEXT: call void @use(float [[DIV]])173; CHECK-NEXT: [[R:%.*]] = fadd float [[Z]], [[DIV]]174; CHECK-NEXT: ret float [[R]]175;176 %z = frem float 42.0, %pz ; thwart complexity-based canonicalization177 %neg = fsub float -0.000000e+00, %x178 %div = fdiv float %neg, %y179 call void @use(float %div)180 %r = fadd float %z, %div181 ret float %r182}183 184; Z + (Y / -X) - extra use means we can't transform to fsub without an extra instruction185 186define float @fdiv_fneg2_extra_use(float %x, float %py, float %pz) {187; CHECK-LABEL: @fdiv_fneg2_extra_use(188; CHECK-NEXT: [[Y:%.*]] = frem float -4.200000e+01, [[PY:%.*]]189; CHECK-NEXT: [[Z:%.*]] = frem float 4.200000e+01, [[PZ:%.*]]190; CHECK-NEXT: [[NEG:%.*]] = fneg float [[X:%.*]]191; CHECK-NEXT: [[DIV:%.*]] = fdiv float [[Y]], [[NEG]]192; CHECK-NEXT: call void @use(float [[DIV]])193; CHECK-NEXT: [[R:%.*]] = fadd float [[Z]], [[DIV]]194; CHECK-NEXT: ret float [[R]]195;196 %y = frem float -42.0, %py ; thwart complexity-based canonicalization197 %z = frem float 42.0, %pz ; thwart complexity-based canonicalization198 %neg = fsub float -0.000000e+00, %x199 %div = fdiv float %y, %neg200 call void @use(float %div)201 %r = fadd float %z, %div202 ret float %r203}204 205; Z + (-X * Y) - extra use means we can't transform to fsub without an extra instruction206 207define <2 x float> @fmul_fneg1_extra_use(<2 x float> %x, <2 x float> %y, <2 x float> %pz) {208; CHECK-LABEL: @fmul_fneg1_extra_use(209; CHECK-NEXT: [[Z:%.*]] = frem <2 x float> <float 4.200000e+01, float -1.000000e+00>, [[PZ:%.*]]210; CHECK-NEXT: [[NEG:%.*]] = fneg <2 x float> [[X:%.*]]211; CHECK-NEXT: [[MUL:%.*]] = fmul <2 x float> [[Y:%.*]], [[NEG]]212; CHECK-NEXT: call void @use_vec(<2 x float> [[MUL]])213; CHECK-NEXT: [[R:%.*]] = fadd <2 x float> [[Z]], [[MUL]]214; CHECK-NEXT: ret <2 x float> [[R]]215;216 %z = frem <2 x float> <float 42.0, float -1.0>, %pz ; thwart complexity-based canonicalization217 %neg = fsub <2 x float> <float -0.0, float -0.0>, %x218 %mul = fmul <2 x float> %neg, %y219 call void @use_vec(<2 x float> %mul)220 %r = fadd <2 x float> %z, %mul221 ret <2 x float> %r222}223 224; Z + (Y * -X) - extra use means we can't transform to fsub without an extra instruction225 226define float @fmul_fneg2_extra_use(float %x, float %py, float %pz) {227; CHECK-LABEL: @fmul_fneg2_extra_use(228; CHECK-NEXT: [[Y:%.*]] = frem float -4.200000e+01, [[PY:%.*]]229; CHECK-NEXT: [[Z:%.*]] = frem float 4.200000e+01, [[PZ:%.*]]230; CHECK-NEXT: [[NEG:%.*]] = fneg float [[X:%.*]]231; CHECK-NEXT: [[MUL:%.*]] = fmul float [[Y]], [[NEG]]232; CHECK-NEXT: call void @use(float [[MUL]])233; CHECK-NEXT: [[R:%.*]] = fadd float [[Z]], [[MUL]]234; CHECK-NEXT: ret float [[R]]235;236 %y = frem float -42.0, %py ; thwart complexity-based canonicalization237 %z = frem float 42.0, %pz ; thwart complexity-based canonicalization238 %neg = fsub float -0.000000e+00, %x239 %mul = fmul float %y, %neg240 call void @use(float %mul)241 %r = fadd float %z, %mul242 ret float %r243}244 245; (-X / Y) + Z --> Z - (X / Y)246 247define float @fdiv_fneg1_extra_use2(float %x, float %y, float %z) {248; CHECK-LABEL: @fdiv_fneg1_extra_use2(249; CHECK-NEXT: [[NEG:%.*]] = fneg float [[X:%.*]]250; CHECK-NEXT: call void @use(float [[NEG]])251; CHECK-NEXT: [[TMP1:%.*]] = fdiv float [[X]], [[Y:%.*]]252; CHECK-NEXT: [[R:%.*]] = fsub float [[Z:%.*]], [[TMP1]]253; CHECK-NEXT: ret float [[R]]254;255 %neg = fsub float -0.000000e+00, %x256 call void @use(float %neg)257 %div = fdiv float %neg, %y258 %r = fadd float %div, %z259 ret float %r260}261 262; (Y / -X) + Z --> Z - (Y / X)263 264define float @fdiv_fneg2_extra_use2(float %x, float %y, float %z) {265; CHECK-LABEL: @fdiv_fneg2_extra_use2(266; CHECK-NEXT: [[NEG:%.*]] = fneg float [[X:%.*]]267; CHECK-NEXT: call void @use(float [[NEG]])268; CHECK-NEXT: [[TMP1:%.*]] = fdiv float [[Y:%.*]], [[X]]269; CHECK-NEXT: [[R:%.*]] = fsub float [[Z:%.*]], [[TMP1]]270; CHECK-NEXT: ret float [[R]]271;272 %neg = fsub float -0.000000e+00, %x273 call void @use(float %neg)274 %div = fdiv float %y, %neg275 %r = fadd float %div, %z276 ret float %r277}278 279; (-X * Y) + Z --> Z - (X * Y)280 281define <2 x float> @fmul_fneg1_extra_use2(<2 x float> %x, <2 x float> %y, <2 x float> %z) {282; CHECK-LABEL: @fmul_fneg1_extra_use2(283; CHECK-NEXT: [[NEG:%.*]] = fneg <2 x float> [[X:%.*]]284; CHECK-NEXT: call void @use_vec(<2 x float> [[NEG]])285; CHECK-NEXT: [[TMP1:%.*]] = fmul <2 x float> [[X]], [[Y:%.*]]286; CHECK-NEXT: [[R:%.*]] = fsub <2 x float> [[Z:%.*]], [[TMP1]]287; CHECK-NEXT: ret <2 x float> [[R]]288;289 %neg = fsub <2 x float> <float -0.0, float -0.0>, %x290 call void @use_vec(<2 x float> %neg)291 %mul = fmul <2 x float> %neg, %y292 %r = fadd <2 x float> %mul, %z293 ret <2 x float> %r294}295 296; (Y * -X) + Z --> Z - (Y * X)297 298define float @fmul_fneg2_extra_use2(float %x, float %py, float %z) {299; CHECK-LABEL: @fmul_fneg2_extra_use2(300; CHECK-NEXT: [[Y:%.*]] = frem float -4.200000e+01, [[PY:%.*]]301; CHECK-NEXT: [[NEG:%.*]] = fneg float [[X:%.*]]302; CHECK-NEXT: call void @use(float [[NEG]])303; CHECK-NEXT: [[TMP1:%.*]] = fmul float [[X]], [[Y]]304; CHECK-NEXT: [[R:%.*]] = fsub float [[Z:%.*]], [[TMP1]]305; CHECK-NEXT: ret float [[R]]306;307 %y = frem float -42.0, %py ; thwart complexity-based canonicalization308 %neg = fsub float -0.000000e+00, %x309 call void @use(float %neg)310 %mul = fmul float %y, %neg311 %r = fadd float %mul, %z312 ret float %r313}314 315; (-X / Y) + Z --> Z - (X / Y)316 317define float @fdiv_fneg1_extra_use3(float %x, float %y, float %z) {318; CHECK-LABEL: @fdiv_fneg1_extra_use3(319; CHECK-NEXT: [[NEG:%.*]] = fneg float [[X:%.*]]320; CHECK-NEXT: call void @use(float [[NEG]])321; CHECK-NEXT: [[DIV:%.*]] = fdiv float [[NEG]], [[Y:%.*]]322; CHECK-NEXT: call void @use(float [[DIV]])323; CHECK-NEXT: [[R:%.*]] = fadd float [[DIV]], [[Z:%.*]]324; CHECK-NEXT: ret float [[R]]325;326 %neg = fsub float -0.000000e+00, %x327 call void @use(float %neg)328 %div = fdiv float %neg, %y329 call void @use(float %div)330 %r = fadd float %div, %z331 ret float %r332}333 334; (Y / -X) + Z --> Z - (Y / X)335 336define float @fdiv_fneg2_extra_use3(float %x, float %y, float %z) {337; CHECK-LABEL: @fdiv_fneg2_extra_use3(338; CHECK-NEXT: [[NEG:%.*]] = fneg float [[X:%.*]]339; CHECK-NEXT: call void @use(float [[NEG]])340; CHECK-NEXT: [[DIV:%.*]] = fdiv float [[Y:%.*]], [[NEG]]341; CHECK-NEXT: call void @use(float [[DIV]])342; CHECK-NEXT: [[R:%.*]] = fadd float [[DIV]], [[Z:%.*]]343; CHECK-NEXT: ret float [[R]]344;345 %neg = fsub float -0.000000e+00, %x346 call void @use(float %neg)347 %div = fdiv float %y, %neg348 call void @use(float %div)349 %r = fadd float %div, %z350 ret float %r351}352 353; (-X * Y) + Z --> Z - (X * Y)354 355define <2 x float> @fmul_fneg1_extra_use3(<2 x float> %x, <2 x float> %y, <2 x float> %z) {356; CHECK-LABEL: @fmul_fneg1_extra_use3(357; CHECK-NEXT: [[NEG:%.*]] = fneg <2 x float> [[X:%.*]]358; CHECK-NEXT: call void @use_vec(<2 x float> [[NEG]])359; CHECK-NEXT: [[MUL:%.*]] = fmul <2 x float> [[Y:%.*]], [[NEG]]360; CHECK-NEXT: call void @use_vec(<2 x float> [[MUL]])361; CHECK-NEXT: [[R:%.*]] = fadd <2 x float> [[MUL]], [[Z:%.*]]362; CHECK-NEXT: ret <2 x float> [[R]]363;364 %neg = fsub <2 x float> <float -0.0, float -0.0>, %x365 call void @use_vec(<2 x float> %neg)366 %mul = fmul <2 x float> %neg, %y367 call void @use_vec(<2 x float> %mul)368 %r = fadd <2 x float> %mul, %z369 ret <2 x float> %r370}371 372; (Y * -X) + Z --> Z - (Y * X)373 374define float @fmul_fneg2_extra_use3(float %x, float %py, float %z) {375; CHECK-LABEL: @fmul_fneg2_extra_use3(376; CHECK-NEXT: [[Y:%.*]] = frem float -4.200000e+01, [[PY:%.*]]377; CHECK-NEXT: [[NEG:%.*]] = fneg float [[X:%.*]]378; CHECK-NEXT: call void @use(float [[NEG]])379; CHECK-NEXT: [[MUL:%.*]] = fmul float [[Y]], [[NEG]]380; CHECK-NEXT: call void @use(float [[MUL]])381; CHECK-NEXT: [[R:%.*]] = fadd float [[MUL]], [[Z:%.*]]382; CHECK-NEXT: ret float [[R]]383;384 %y = frem float -42.0, %py ; thwart complexity-based canonicalization385 %neg = fsub float -0.000000e+00, %x386 call void @use(float %neg)387 %mul = fmul float %y, %neg388 call void @use(float %mul)389 %r = fadd float %mul, %z390 ret float %r391}392 393define float @fadd_rdx(float %x, <4 x float> %v) {394; CHECK-LABEL: @fadd_rdx(395; CHECK-NEXT: [[ADD:%.*]] = call fast float @llvm.vector.reduce.fadd.v4f32(float [[X:%.*]], <4 x float> [[V:%.*]])396; CHECK-NEXT: ret float [[ADD]]397;398 %rdx = call fast float @llvm.vector.reduce.fadd.v4f32(float 0.0, <4 x float> %v)399 %add = fadd fast float %rdx, %x400 ret float %add401}402 403define float @fadd_rdx_commute(float %x, <4 x float> %v) {404; CHECK-LABEL: @fadd_rdx_commute(405; CHECK-NEXT: [[D:%.*]] = fdiv float 4.200000e+01, [[X:%.*]]406; CHECK-NEXT: [[ADD:%.*]] = call reassoc nsz float @llvm.vector.reduce.fadd.v4f32(float [[D]], <4 x float> [[V:%.*]])407; CHECK-NEXT: ret float [[ADD]]408;409 %d = fdiv float 42.0, %x410 %rdx = call float @llvm.vector.reduce.fadd.v4f32(float -0.0, <4 x float> %v)411 %add = fadd reassoc nsz float %d, %rdx412 ret float %add413}414 415; Negative test - require nsz to be safer (and reassoc obviously).416 417define float @fadd_rdx_fmf(float %x, <4 x float> %v) {418; CHECK-LABEL: @fadd_rdx_fmf(419; CHECK-NEXT: [[RDX:%.*]] = call float @llvm.vector.reduce.fadd.v4f32(float 0.000000e+00, <4 x float> [[V:%.*]])420; CHECK-NEXT: [[ADD:%.*]] = fadd reassoc float [[RDX]], [[X:%.*]]421; CHECK-NEXT: ret float [[ADD]]422;423 %rdx = call float @llvm.vector.reduce.fadd.v4f32(float 0.0, <4 x float> %v)424 %add = fadd reassoc float %rdx, %x425 ret float %add426}427 428; Negative test - don't replace a single add with another reduction.429 430define float @fadd_rdx_extra_use(float %x, <4 x float> %v) {431; CHECK-LABEL: @fadd_rdx_extra_use(432; CHECK-NEXT: [[RDX:%.*]] = call float @llvm.vector.reduce.fadd.v4f32(float 0.000000e+00, <4 x float> [[V:%.*]])433; CHECK-NEXT: call void @use(float [[RDX]])434; CHECK-NEXT: [[ADD:%.*]] = fadd fast float [[RDX]], [[X:%.*]]435; CHECK-NEXT: ret float [[ADD]]436;437 %rdx = call float @llvm.vector.reduce.fadd.v4f32(float 0.0, <4 x float> %v)438 call void @use(float %rdx)439 %add = fadd fast float %rdx, %x440 ret float %add441}442 443define float @fadd_rdx_nonzero_start_const_op(<4 x float> %v) {444; CHECK-LABEL: @fadd_rdx_nonzero_start_const_op(445; CHECK-NEXT: [[ADD:%.*]] = call reassoc ninf nsz float @llvm.vector.reduce.fadd.v4f32(float 3.300000e+01, <4 x float> [[V:%.*]])446; CHECK-NEXT: ret float [[ADD]]447;448 %rdx = call float @llvm.vector.reduce.fadd.v4f32(float 42.0, <4 x float> %v)449 %add = fadd reassoc nsz ninf float %rdx, -9.0450 ret float %add451}452 453; Negative test - we don't change the order of ops unless it saves an instruction.454 455define float @fadd_rdx_nonzero_start_variable_op(float %x, <4 x float> %v) {456; CHECK-LABEL: @fadd_rdx_nonzero_start_variable_op(457; CHECK-NEXT: [[RDX:%.*]] = call float @llvm.vector.reduce.fadd.v4f32(float 4.200000e+01, <4 x float> [[V:%.*]])458; CHECK-NEXT: [[ADD:%.*]] = fadd fast float [[RDX]], [[X:%.*]]459; CHECK-NEXT: ret float [[ADD]]460;461 %rdx = call float @llvm.vector.reduce.fadd.v4f32(float 42.0, <4 x float> %v)462 %add = fadd fast float %rdx, %x463 ret float %add464}465 466; (X * C) + X --> X * (C + 1)467 468define float @fadd_fmul_common_op(float %x) {469; CHECK-LABEL: @fadd_fmul_common_op(470; CHECK-NEXT: [[A:%.*]] = fmul reassoc nsz float [[X:%.*]], 4.300000e+01471; CHECK-NEXT: ret float [[A]]472;473 %m = fmul reassoc nsz float %x, 42.0474 %a = fadd reassoc nsz float %m, %x475 ret float %a476}477 478; Splat constant is ok.479 480define <2 x float> @fadd_fmul_common_op_vec(<2 x float> %x) {481; CHECK-LABEL: @fadd_fmul_common_op_vec(482; CHECK-NEXT: [[A:%.*]] = fmul reassoc nsz <2 x float> [[X:%.*]], splat (float 4.300000e+01)483; CHECK-NEXT: ret <2 x float> [[A]]484;485 %m = fmul reassoc nsz <2 x float> %x, <float 42.0, float 42.0>486 %a = fadd reassoc nsz <2 x float> %m, %x487 ret <2 x float> %a488}489 490; Non-splat constant is ok.491 492define <2 x float> @fadd_fmul_common_op_commute_vec(<2 x float> %px) {493; CHECK-LABEL: @fadd_fmul_common_op_commute_vec(494; CHECK-NEXT: [[X:%.*]] = fmul <2 x float> [[PX:%.*]], [[PX]]495; CHECK-NEXT: [[A:%.*]] = fmul reassoc nsz <2 x float> [[X]], <float 4.300000e+01, float -4.200000e+01>496; CHECK-NEXT: ret <2 x float> [[A]]497;498 %x = fmul <2 x float> %px, %px ; thwart complexity-based canonicalization499 %m = fmul reassoc nsz <2 x float> %x, <float 42.0, float -43.0>500 %a = fadd reassoc nsz <2 x float> %x, %m501 ret <2 x float> %a502}503 504; Extra use is ok.505 506define float @fadd_fmul_common_op_use(float %x) {507; CHECK-LABEL: @fadd_fmul_common_op_use(508; CHECK-NEXT: [[M:%.*]] = fmul reassoc nsz float [[X:%.*]], 4.200000e+01509; CHECK-NEXT: call void @use(float [[M]])510; CHECK-NEXT: [[A:%.*]] = fmul reassoc nsz float [[X]], 4.300000e+01511; CHECK-NEXT: ret float [[A]]512;513 %m = fmul reassoc nsz float %x, 42.0514 call void @use(float %m)515 %a = fadd reassoc nsz float %m, %x516 ret float %a517}518 519; Negative test - must have 'reassoc' FMF520 521define float @fadd_fmul_common_op_wrong_fmf(float %x) {522; CHECK-LABEL: @fadd_fmul_common_op_wrong_fmf(523; CHECK-NEXT: [[M:%.*]] = fmul ninf nsz float [[X:%.*]], 4.200000e+01524; CHECK-NEXT: [[A:%.*]] = fadd ninf nsz float [[M]], [[X]]525; CHECK-NEXT: ret float [[A]]526;527 %m = fmul ninf nsz float %x, 42.0528 %a = fadd ninf nsz float %m, %x529 ret float %a530}531 532; (-x - y) + (x + z) --> z - y533 534define float @fadd_fneg_reass_commute0(float %x, float %y, float %z) {535; CHECK-LABEL: @fadd_fneg_reass_commute0(536; CHECK-NEXT: [[N:%.*]] = fneg reassoc nsz float [[X:%.*]]537; CHECK-NEXT: call void @use(float [[N]])538; CHECK-NEXT: [[R:%.*]] = fsub reassoc nsz float [[Z:%.*]], [[Y:%.*]]539; CHECK-NEXT: ret float [[R]]540;541 %n = fneg reassoc nsz float %x542 call void @use(float %n)543 %s = fsub reassoc nsz float %n, %y544 %a = fadd reassoc nsz float %x, %z545 %r = fadd reassoc nsz float %s, %a546 ret float %r547}548 549define float @fadd_fneg_reass_commute1(float %x, float %y, float %z) {550; CHECK-LABEL: @fadd_fneg_reass_commute1(551; CHECK-NEXT: [[N:%.*]] = fneg float [[X:%.*]]552; CHECK-NEXT: call void @use(float [[N]])553; CHECK-NEXT: [[S:%.*]] = fsub float [[N]], [[Y:%.*]]554; CHECK-NEXT: call void @use(float [[S]])555; CHECK-NEXT: [[R:%.*]] = fsub reassoc nsz float [[Z:%.*]], [[Y]]556; CHECK-NEXT: ret float [[R]]557;558 %n = fneg float %x559 call void @use(float %n)560 %s = fsub float %n, %y561 call void @use(float %s)562 %a = fadd float %x, %z563 %r = fadd reassoc nsz float %a, %s564 ret float %r565}566 567define float @fadd_fneg_reass_commute2(float %x, float %y, float %z) {568; CHECK-LABEL: @fadd_fneg_reass_commute2(569; CHECK-NEXT: [[N:%.*]] = fneg float [[X:%.*]]570; CHECK-NEXT: call void @use(float [[N]])571; CHECK-NEXT: [[S:%.*]] = fsub float [[N]], [[Y:%.*]]572; CHECK-NEXT: call void @use(float [[S]])573; CHECK-NEXT: [[A:%.*]] = fadd float [[Z:%.*]], [[X]]574; CHECK-NEXT: call void @use(float [[A]])575; CHECK-NEXT: [[R:%.*]] = fsub fast float [[Z]], [[Y]]576; CHECK-NEXT: ret float [[R]]577;578 %n = fneg float %x579 call void @use(float %n)580 %s = fsub float %n, %y581 call void @use(float %s)582 %a = fadd float %z, %x583 call void @use(float %a)584 %r = fadd fast float %s, %a585 ret float %r586}587 588define <2 x float> @fadd_fneg_reass_commute3(<2 x float> %x, <2 x float> %y, <2 x float> %z) {589; CHECK-LABEL: @fadd_fneg_reass_commute3(590; CHECK-NEXT: [[N:%.*]] = fneg reassoc nsz <2 x float> [[X:%.*]]591; CHECK-NEXT: call void @use_vec(<2 x float> [[N]])592; CHECK-NEXT: [[R:%.*]] = fsub reassoc nsz <2 x float> [[Z:%.*]], [[Y:%.*]]593; CHECK-NEXT: ret <2 x float> [[R]]594;595 %n = fneg reassoc nsz <2 x float> %x596 call void @use_vec(<2 x float> %n)597 %s = fsub reassoc nsz <2 x float> %n, %y598 %a = fadd reassoc nsz <2 x float> %z, %x599 %r = fadd reassoc nsz <2 x float> %a, %s600 ret <2 x float> %r601}602 603; negative test - need reassoc (+ nsz)604 605define float @fadd_fneg_commute0(float %x, float %y, float %z) {606; CHECK-LABEL: @fadd_fneg_commute0(607; CHECK-NEXT: [[N:%.*]] = fneg float [[X:%.*]]608; CHECK-NEXT: call void @use(float [[N]])609; CHECK-NEXT: [[S:%.*]] = fsub float [[N]], [[Y:%.*]]610; CHECK-NEXT: [[A:%.*]] = fadd float [[X]], [[Z:%.*]]611; CHECK-NEXT: [[R:%.*]] = fadd nsz float [[S]], [[A]]612; CHECK-NEXT: ret float [[R]]613;614 %n = fneg float %x615 call void @use(float %n)616 %s = fsub float %n, %y617 %a = fadd float %x, %z618 %r = fadd nsz float %s, %a619 ret float %r620}621 622define float @fadd_reduce_sqr_sum_varA(float %a, float %b) {623; CHECK-LABEL: @fadd_reduce_sqr_sum_varA(624; CHECK-NEXT: [[TMP1:%.*]] = fadd reassoc nsz float [[A:%.*]], [[B:%.*]]625; CHECK-NEXT: [[ADD:%.*]] = fmul reassoc nsz float [[TMP1]], [[TMP1]]626; CHECK-NEXT: ret float [[ADD]]627;628 %a_sq = fmul float %a, %a629 %two_a = fmul float %a, 2.0630 %two_a_plus_b = fadd float %two_a, %b631 %mul = fmul float %two_a_plus_b, %b632 %add = fadd reassoc nsz float %mul, %a_sq633 ret float %add634}635 636define float @fadd_reduce_sqr_sum_varA_order2(float %a, float %b) {637; CHECK-LABEL: @fadd_reduce_sqr_sum_varA_order2(638; CHECK-NEXT: [[TMP1:%.*]] = fadd reassoc nsz float [[A:%.*]], [[B:%.*]]639; CHECK-NEXT: [[ADD:%.*]] = fmul reassoc nsz float [[TMP1]], [[TMP1]]640; CHECK-NEXT: ret float [[ADD]]641;642 %a_sq = fmul float %a, %a643 %two_a = fmul float %a, 2.0644 %two_a_plus_b = fadd float %two_a, %b645 %mul = fmul float %two_a_plus_b, %b646 %add = fadd reassoc nsz float %a_sq, %mul647 ret float %add648}649 650define float @fadd_reduce_sqr_sum_varA_order3(float %a, float %b) {651; CHECK-LABEL: @fadd_reduce_sqr_sum_varA_order3(652; CHECK-NEXT: [[TMP1:%.*]] = fadd reassoc nsz float [[A:%.*]], [[B:%.*]]653; CHECK-NEXT: [[ADD:%.*]] = fmul reassoc nsz float [[TMP1]], [[TMP1]]654; CHECK-NEXT: ret float [[ADD]]655;656 %a_sq = fmul float %a, %a657 %two_a = fmul float %a, 2.0658 %two_a_plus_b = fadd float %two_a, %b659 %mul = fmul float %b, %two_a_plus_b660 %add = fadd reassoc nsz float %mul, %a_sq661 ret float %add662}663 664define float @fadd_reduce_sqr_sum_varA_order4(float %a, float %b) {665; CHECK-LABEL: @fadd_reduce_sqr_sum_varA_order4(666; CHECK-NEXT: [[TMP1:%.*]] = fadd reassoc nsz float [[A:%.*]], [[B:%.*]]667; CHECK-NEXT: [[ADD:%.*]] = fmul reassoc nsz float [[TMP1]], [[TMP1]]668; CHECK-NEXT: ret float [[ADD]]669;670 %a_sq = fmul float %a, %a671 %two_a = fmul float %a, 2.0672 %two_a_plus_b = fadd float %b, %two_a673 %mul = fmul float %two_a_plus_b, %b674 %add = fadd reassoc nsz float %mul, %a_sq675 ret float %add676}677 678define float @fadd_reduce_sqr_sum_varA_order5(float %a, float %b) {679; CHECK-LABEL: @fadd_reduce_sqr_sum_varA_order5(680; CHECK-NEXT: [[TMP1:%.*]] = fadd reassoc nsz float [[A:%.*]], [[B:%.*]]681; CHECK-NEXT: [[ADD:%.*]] = fmul reassoc nsz float [[TMP1]], [[TMP1]]682; CHECK-NEXT: ret float [[ADD]]683;684 %a_sq = fmul float %a, %a685 %two_a = fmul float 2.0, %a686 %two_a_plus_b = fadd float %two_a, %b687 %mul = fmul float %two_a_plus_b, %b688 %add = fadd reassoc nsz float %mul, %a_sq689 ret float %add690}691 692define float @fadd_reduce_sqr_sum_varB(float %a, float %b) {693; CHECK-LABEL: @fadd_reduce_sqr_sum_varB(694; CHECK-NEXT: [[TMP1:%.*]] = fadd reassoc nsz float [[A:%.*]], [[B:%.*]]695; CHECK-NEXT: [[ADD:%.*]] = fmul reassoc nsz float [[TMP1]], [[TMP1]]696; CHECK-NEXT: ret float [[ADD]]697;698 %a_b = fmul float %a, %b699 %a_b_2 = fmul float %a_b, 2.0700 %a_sq = fmul float %a, %a701 %b_sq = fmul float %b, %b702 %a_sq_b_sq = fadd float %a_sq, %b_sq703 %add = fadd reassoc nsz float %a_b_2, %a_sq_b_sq704 ret float %add705}706 707define float @fadd_reduce_sqr_sum_varB_order1(float %a, float %b) {708; CHECK-LABEL: @fadd_reduce_sqr_sum_varB_order1(709; CHECK-NEXT: [[TMP1:%.*]] = fadd reassoc nsz float [[A:%.*]], [[B:%.*]]710; CHECK-NEXT: [[ADD:%.*]] = fmul reassoc nsz float [[TMP1]], [[TMP1]]711; CHECK-NEXT: ret float [[ADD]]712;713 %a_b = fmul float %a, %b714 %a_b_2 = fmul float %a_b, 2.0715 %a_sq = fmul float %a, %a716 %b_sq = fmul float %b, %b717 %a_sq_b_sq = fadd float %a_sq, %b_sq718 %add = fadd reassoc nsz float %a_sq_b_sq, %a_b_2719 ret float %add720}721 722define float @fadd_reduce_sqr_sum_varB_order2(float %a, float %b) {723; CHECK-LABEL: @fadd_reduce_sqr_sum_varB_order2(724; CHECK-NEXT: [[TMP1:%.*]] = fadd reassoc nsz float [[A:%.*]], [[B:%.*]]725; CHECK-NEXT: [[ADD:%.*]] = fmul reassoc nsz float [[TMP1]], [[TMP1]]726; CHECK-NEXT: ret float [[ADD]]727;728 %a_b = fmul float %a, %b729 %a_b_2 = fmul float %a_b, 2.0730 %a_sq = fmul float %a, %a731 %b_sq = fmul float %b, %b732 %a_sq_b_sq = fadd float %b_sq, %a_sq733 %add = fadd reassoc nsz float %a_b_2, %a_sq_b_sq734 ret float %add735}736 737define float @fadd_reduce_sqr_sum_varB_order3(float %a, float %b) {738; CHECK-LABEL: @fadd_reduce_sqr_sum_varB_order3(739; CHECK-NEXT: [[TMP1:%.*]] = fadd reassoc nsz float [[B:%.*]], [[A:%.*]]740; CHECK-NEXT: [[ADD:%.*]] = fmul reassoc nsz float [[TMP1]], [[TMP1]]741; CHECK-NEXT: ret float [[ADD]]742;743 %a_b = fmul float %b, %a744 %a_b_2 = fmul float 2.0, %a_b745 %a_sq = fmul float %a, %a746 %b_sq = fmul float %b, %b747 %a_sq_b_sq = fadd float %a_sq, %b_sq748 %add = fadd reassoc nsz float %a_b_2, %a_sq_b_sq749 ret float %add750}751 752define float @fadd_reduce_sqr_sum_varB2(float %a, float %b) {753; CHECK-LABEL: @fadd_reduce_sqr_sum_varB2(754; CHECK-NEXT: [[TMP1:%.*]] = fadd reassoc nsz float [[A:%.*]], [[B:%.*]]755; CHECK-NEXT: [[ADD:%.*]] = fmul reassoc nsz float [[TMP1]], [[TMP1]]756; CHECK-NEXT: ret float [[ADD]]757;758 %a_2 = fmul float %a, 2.0759 %a_b_2 = fmul float %a_2, %b760 %a_sq = fmul float %a, %a761 %b_sq = fmul float %b, %b762 %a_sq_b_sq = fadd float %a_sq, %b_sq763 %add = fadd reassoc nsz float %a_b_2, %a_sq_b_sq764 ret float %add765}766 767define float @fadd_reduce_sqr_sum_varB2_order1(float %a, float %b) {768; CHECK-LABEL: @fadd_reduce_sqr_sum_varB2_order1(769; CHECK-NEXT: [[TMP1:%.*]] = fadd reassoc nsz float [[A:%.*]], [[B:%.*]]770; CHECK-NEXT: [[ADD:%.*]] = fmul reassoc nsz float [[TMP1]], [[TMP1]]771; CHECK-NEXT: ret float [[ADD]]772;773 %a_2 = fmul float %a, 2.0774 %a_b_2 = fmul float %a_2, %b775 %a_sq = fmul float %a, %a776 %b_sq = fmul float %b, %b777 %a_sq_b_sq = fadd float %a_sq, %b_sq778 %add = fadd reassoc nsz float %a_sq_b_sq, %a_b_2779 ret float %add780}781 782define float @fadd_reduce_sqr_sum_varB2_order2(float %a, float %b) {783; CHECK-LABEL: @fadd_reduce_sqr_sum_varB2_order2(784; CHECK-NEXT: [[TMP1:%.*]] = fadd reassoc nsz float [[A:%.*]], [[B:%.*]]785; CHECK-NEXT: [[ADD:%.*]] = fmul reassoc nsz float [[TMP1]], [[TMP1]]786; CHECK-NEXT: ret float [[ADD]]787;788 %a_2 = fmul float %a, 2.0789 %a_b_2 = fmul float %b, %a_2790 %a_sq = fmul float %a, %a791 %b_sq = fmul float %b, %b792 %a_sq_b_sq = fadd float %a_sq, %b_sq793 %add = fadd reassoc nsz float %a_b_2, %a_sq_b_sq794 ret float %add795}796 797define float @fadd_reduce_sqr_sum_varB2_order3(float %a, float %b) {798; CHECK-LABEL: @fadd_reduce_sqr_sum_varB2_order3(799; CHECK-NEXT: [[TMP1:%.*]] = fadd reassoc nsz float [[A:%.*]], [[B:%.*]]800; CHECK-NEXT: [[ADD:%.*]] = fmul reassoc nsz float [[TMP1]], [[TMP1]]801; CHECK-NEXT: ret float [[ADD]]802;803 %a_2 = fmul float 2.0, %a804 %a_b_2 = fmul float %a_2, %b805 %a_sq = fmul float %a, %a806 %b_sq = fmul float %b, %b807 %a_sq_b_sq = fadd float %a_sq, %b_sq808 %add = fadd reassoc nsz float %a_b_2, %a_sq_b_sq809 ret float %add810}811 812define float @fadd_reduce_sqr_sum_varA_not_one_use1(float %a, float %b) {813; CHECK-LABEL: @fadd_reduce_sqr_sum_varA_not_one_use1(814; CHECK-NEXT: [[A_SQ:%.*]] = fmul float [[A:%.*]], [[A]]815; CHECK-NEXT: [[TWO_A:%.*]] = fmul float [[A]], 2.000000e+00816; CHECK-NEXT: [[TWO_A_PLUS_B:%.*]] = fadd float [[TWO_A]], [[B:%.*]]817; CHECK-NEXT: [[MUL:%.*]] = fmul float [[TWO_A_PLUS_B]], [[B]]818; CHECK-NEXT: [[ADD:%.*]] = fadd reassoc nsz float [[MUL]], [[A_SQ]]819; CHECK-NEXT: tail call void @fake_func(float [[MUL]])820; CHECK-NEXT: ret float [[ADD]]821;822 %a_sq = fmul float %a, %a823 %two_a = fmul float %a, 2.0824 %two_a_plus_b = fadd float %two_a, %b825 %mul = fmul float %two_a_plus_b, %b826 %add = fadd reassoc nsz float %mul, %a_sq827 tail call void @fake_func (float %mul)828 ret float %add829}830 831define float @fadd_reduce_sqr_sum_varA_not_one_use2(float %a, float %b) {832; CHECK-LABEL: @fadd_reduce_sqr_sum_varA_not_one_use2(833; CHECK-NEXT: [[A_SQ:%.*]] = fmul float [[A:%.*]], [[A]]834; CHECK-NEXT: [[TWO_A:%.*]] = fmul float [[A]], 2.000000e+00835; CHECK-NEXT: [[TWO_A_PLUS_B:%.*]] = fadd float [[TWO_A]], [[B:%.*]]836; CHECK-NEXT: [[MUL:%.*]] = fmul float [[TWO_A_PLUS_B]], [[B]]837; CHECK-NEXT: [[ADD:%.*]] = fadd reassoc nsz float [[MUL]], [[A_SQ]]838; CHECK-NEXT: tail call void @fake_func(float [[A_SQ]])839; CHECK-NEXT: ret float [[ADD]]840;841 %a_sq = fmul float %a, %a842 %two_a = fmul float %a, 2.0843 %two_a_plus_b = fadd float %two_a, %b844 %mul = fmul float %two_a_plus_b, %b845 %add = fadd reassoc nsz float %mul, %a_sq846 tail call void @fake_func (float %a_sq)847 ret float %add848}849 850define float @fadd_reduce_sqr_sum_varB_not_one_use1(float %a, float %b) {851; CHECK-LABEL: @fadd_reduce_sqr_sum_varB_not_one_use1(852; CHECK-NEXT: [[A_B:%.*]] = fmul float [[A:%.*]], [[B:%.*]]853; CHECK-NEXT: [[A_B_2:%.*]] = fmul float [[A_B]], 2.000000e+00854; CHECK-NEXT: [[A_SQ:%.*]] = fmul float [[A]], [[A]]855; CHECK-NEXT: [[B_SQ:%.*]] = fmul float [[B]], [[B]]856; CHECK-NEXT: [[A_SQ_B_SQ:%.*]] = fadd float [[A_SQ]], [[B_SQ]]857; CHECK-NEXT: [[ADD:%.*]] = fadd reassoc nsz float [[A_B_2]], [[A_SQ_B_SQ]]858; CHECK-NEXT: tail call void @fake_func(float [[A_B_2]])859; CHECK-NEXT: ret float [[ADD]]860;861 %a_b = fmul float %a, %b862 %a_b_2 = fmul float %a_b, 2.0863 %a_sq = fmul float %a, %a864 %b_sq = fmul float %b, %b865 %a_sq_b_sq = fadd float %a_sq, %b_sq866 %add = fadd reassoc nsz float %a_b_2, %a_sq_b_sq867 tail call void @fake_func (float %a_b_2)868 ret float %add869}870 871define float @fadd_reduce_sqr_sum_varB_not_one_use2(float %a, float %b) {872; CHECK-LABEL: @fadd_reduce_sqr_sum_varB_not_one_use2(873; CHECK-NEXT: [[A_B:%.*]] = fmul float [[A:%.*]], [[B:%.*]]874; CHECK-NEXT: [[A_B_2:%.*]] = fmul float [[A_B]], 2.000000e+00875; CHECK-NEXT: [[A_SQ:%.*]] = fmul float [[A]], [[A]]876; CHECK-NEXT: [[B_SQ:%.*]] = fmul float [[B]], [[B]]877; CHECK-NEXT: [[A_SQ_B_SQ:%.*]] = fadd float [[A_SQ]], [[B_SQ]]878; CHECK-NEXT: [[ADD:%.*]] = fadd reassoc nsz float [[A_B_2]], [[A_SQ_B_SQ]]879; CHECK-NEXT: tail call void @fake_func(float [[A_SQ_B_SQ]])880; CHECK-NEXT: ret float [[ADD]]881;882 %a_b = fmul float %a, %b883 %a_b_2 = fmul float %a_b, 2.0884 %a_sq = fmul float %a, %a885 %b_sq = fmul float %b, %b886 %a_sq_b_sq = fadd float %a_sq, %b_sq887 %add = fadd reassoc nsz float %a_b_2, %a_sq_b_sq888 tail call void @fake_func (float %a_sq_b_sq)889 ret float %add890}891 892define float @fadd_reduce_sqr_sum_varB2_not_one_use(float %a, float %b) {893; CHECK-LABEL: @fadd_reduce_sqr_sum_varB2_not_one_use(894; CHECK-NEXT: [[A_2:%.*]] = fmul float [[A:%.*]], 2.000000e+00895; CHECK-NEXT: [[A_B_2:%.*]] = fmul float [[A_2]], [[B:%.*]]896; CHECK-NEXT: [[A_SQ:%.*]] = fmul float [[A]], [[A]]897; CHECK-NEXT: [[B_SQ:%.*]] = fmul float [[B]], [[B]]898; CHECK-NEXT: [[A_SQ_B_SQ:%.*]] = fadd float [[A_SQ]], [[B_SQ]]899; CHECK-NEXT: [[ADD:%.*]] = fadd reassoc nsz float [[A_B_2]], [[A_SQ_B_SQ]]900; CHECK-NEXT: tail call void @fake_func(float [[A_B_2]])901; CHECK-NEXT: ret float [[ADD]]902;903 %a_2 = fmul float %a, 2.0904 %a_b_2 = fmul float %a_2, %b905 %a_sq = fmul float %a, %a906 %b_sq = fmul float %b, %b907 %a_sq_b_sq = fadd float %a_sq, %b_sq908 %add = fadd reassoc nsz float %a_b_2, %a_sq_b_sq909 tail call void @fake_func (float %a_b_2)910 ret float %add911}912 913define float @fadd_reduce_sqr_sum_varA_invalid1(float %a, float %b) {914; CHECK-LABEL: @fadd_reduce_sqr_sum_varA_invalid1(915; CHECK-NEXT: [[TWO_A:%.*]] = fmul float [[A:%.*]], 2.000000e+00916; CHECK-NEXT: [[TWO_A_PLUS_B:%.*]] = fadd float [[TWO_A]], [[B:%.*]]917; CHECK-NEXT: [[TMP1:%.*]] = fadd reassoc nsz float [[TWO_A_PLUS_B]], [[A]]918; CHECK-NEXT: [[ADD:%.*]] = fmul reassoc nsz float [[TMP1]], [[A]]919; CHECK-NEXT: ret float [[ADD]]920;921 %a_sq = fmul float %a, %a922 %two_a = fmul float %a, 2.0923 %two_a_plus_b = fadd float %two_a, %b924 %mul = fmul float %two_a_plus_b, %a925 %add = fadd reassoc nsz float %mul, %a_sq926 ret float %add927}928 929define float @fadd_reduce_sqr_sum_varA_invalid2(float %a, float %b) {930; CHECK-LABEL: @fadd_reduce_sqr_sum_varA_invalid2(931; CHECK-NEXT: [[A_SQ:%.*]] = fmul float [[A:%.*]], [[A]]932; CHECK-NEXT: [[TWO_A:%.*]] = fmul float [[A]], 2.000000e+00933; CHECK-NEXT: [[NOT_TWO_A_PLUS_B:%.*]] = fadd float [[TWO_A]], [[A]]934; CHECK-NEXT: [[MUL:%.*]] = fmul float [[NOT_TWO_A_PLUS_B]], [[B:%.*]]935; CHECK-NEXT: [[ADD:%.*]] = fadd reassoc nsz float [[MUL]], [[A_SQ]]936; CHECK-NEXT: ret float [[ADD]]937;938 %a_sq = fmul float %a, %a939 %two_a = fmul float %a, 2.0940 %not_two_a_plus_b = fadd float %two_a, %a941 %mul = fmul float %not_two_a_plus_b, %b942 %add = fadd reassoc nsz float %mul, %a_sq943 ret float %add944}945 946define float @fadd_reduce_sqr_sum_varA_invalid3(float %a, float %b) {947; CHECK-LABEL: @fadd_reduce_sqr_sum_varA_invalid3(948; CHECK-NEXT: [[A_SQ:%.*]] = fmul float [[A:%.*]], [[A]]949; CHECK-NEXT: [[NOT_TWO_A:%.*]] = fmul float [[A]], 0x4000CCCCC0000000950; CHECK-NEXT: [[TWO_A_PLUS_B:%.*]] = fadd float [[NOT_TWO_A]], [[B:%.*]]951; CHECK-NEXT: [[MUL:%.*]] = fmul float [[TWO_A_PLUS_B]], [[B]]952; CHECK-NEXT: [[ADD:%.*]] = fadd reassoc nsz float [[MUL]], [[A_SQ]]953; CHECK-NEXT: ret float [[ADD]]954;955 %a_sq = fmul float %a, %a956 %not_two_a = fmul float %a, 0x4000CCCCC0000000 ; 2.1957 %two_a_plus_b = fadd float %not_two_a, %b958 %mul = fmul float %two_a_plus_b, %b959 %add = fadd reassoc nsz float %mul, %a_sq960 ret float %add961}962 963define float @fadd_reduce_sqr_sum_varA_invalid4(float %a, float %b) {964; CHECK-LABEL: @fadd_reduce_sqr_sum_varA_invalid4(965; CHECK-NEXT: [[A_SQ:%.*]] = fmul float [[A:%.*]], [[A]]966; CHECK-NEXT: [[NOT_TWO_A:%.*]] = fmul float [[B:%.*]], 2.000000e+00967; CHECK-NEXT: [[TWO_A_PLUS_B:%.*]] = fadd float [[NOT_TWO_A]], [[B]]968; CHECK-NEXT: [[MUL:%.*]] = fmul float [[TWO_A_PLUS_B]], [[B]]969; CHECK-NEXT: [[ADD:%.*]] = fadd reassoc nsz float [[MUL]], [[A_SQ]]970; CHECK-NEXT: ret float [[ADD]]971;972 %a_sq = fmul float %a, %a973 %not_two_a = fmul float %b, 2.0974 %two_a_plus_b = fadd float %not_two_a, %b975 %mul = fmul float %two_a_plus_b, %b976 %add = fadd reassoc nsz float %mul, %a_sq977 ret float %add978}979 980define float @fadd_reduce_sqr_sum_varA_invalid5(float %a, float %b) {981; CHECK-LABEL: @fadd_reduce_sqr_sum_varA_invalid5(982; CHECK-NEXT: [[TWO_A:%.*]] = fmul float [[A:%.*]], 2.000000e+00983; CHECK-NEXT: [[TWO_A_PLUS_B:%.*]] = fadd float [[TWO_A]], [[B:%.*]]984; CHECK-NEXT: [[TMP1:%.*]] = fadd reassoc nsz float [[TWO_A_PLUS_B]], [[A]]985; CHECK-NEXT: [[ADD:%.*]] = fmul reassoc nsz float [[TMP1]], [[B]]986; CHECK-NEXT: ret float [[ADD]]987;988 %not_a_sq = fmul float %a, %b989 %two_a = fmul float %a, 2.0990 %two_a_plus_b = fadd float %two_a, %b991 %mul = fmul float %two_a_plus_b, %b992 %add = fadd reassoc nsz float %mul, %not_a_sq993 ret float %add994}995 996define float @fadd_reduce_sqr_sum_varB_invalid1(float %a, float %b) {997; CHECK-LABEL: @fadd_reduce_sqr_sum_varB_invalid1(998; CHECK-NEXT: [[A_B:%.*]] = fmul float [[A:%.*]], [[B:%.*]]999; CHECK-NEXT: [[A_B_2:%.*]] = fmul float [[A_B]], 2.000000e+001000; CHECK-NEXT: [[A_SQ:%.*]] = fmul float [[A]], [[A]]1001; CHECK-NEXT: [[NOT_B_SQ:%.*]] = fmul float [[B]], [[A]]1002; CHECK-NEXT: [[A_SQ_B_SQ:%.*]] = fadd float [[A_SQ]], [[NOT_B_SQ]]1003; CHECK-NEXT: [[ADD:%.*]] = fadd reassoc nsz float [[A_B_2]], [[A_SQ_B_SQ]]1004; CHECK-NEXT: ret float [[ADD]]1005;1006 %a_b = fmul float %a, %b1007 %a_b_2 = fmul float %a_b, 2.01008 %a_sq = fmul float %a, %a1009 %not_b_sq = fmul float %b, %a1010 %a_sq_b_sq = fadd float %a_sq, %not_b_sq1011 %add = fadd reassoc nsz float %a_b_2, %a_sq_b_sq1012 ret float %add1013}1014 1015define float @fadd_reduce_sqr_sum_varB_invalid2(float %a, float %b) {1016; CHECK-LABEL: @fadd_reduce_sqr_sum_varB_invalid2(1017; CHECK-NEXT: [[A_B:%.*]] = fmul float [[A:%.*]], [[B:%.*]]1018; CHECK-NEXT: [[A_B_2:%.*]] = fmul float [[A_B]], 2.000000e+001019; CHECK-NEXT: [[NOT_A_SQ:%.*]] = fmul float [[A]], [[B]]1020; CHECK-NEXT: [[B_SQ:%.*]] = fmul float [[B]], [[B]]1021; CHECK-NEXT: [[A_SQ_B_SQ:%.*]] = fadd float [[NOT_A_SQ]], [[B_SQ]]1022; CHECK-NEXT: [[ADD:%.*]] = fadd reassoc nsz float [[A_B_2]], [[A_SQ_B_SQ]]1023; CHECK-NEXT: ret float [[ADD]]1024;1025 %a_b = fmul float %a, %b1026 %a_b_2 = fmul float %a_b, 2.01027 %not_a_sq = fmul float %a, %b1028 %b_sq = fmul float %b, %b1029 %a_sq_b_sq = fadd float %not_a_sq, %b_sq1030 %add = fadd reassoc nsz float %a_b_2, %a_sq_b_sq1031 ret float %add1032}1033 1034define float @fadd_reduce_sqr_sum_varB_invalid3(float %a, float %b) {1035; CHECK-LABEL: @fadd_reduce_sqr_sum_varB_invalid3(1036; CHECK-NEXT: [[A_B:%.*]] = fmul float [[A:%.*]], [[B:%.*]]1037; CHECK-NEXT: [[NOT_A_B_2:%.*]] = fmul float [[A_B]], 0x4000CCCCC00000001038; CHECK-NEXT: [[A_SQ:%.*]] = fmul float [[A]], [[A]]1039; CHECK-NEXT: [[B_SQ:%.*]] = fmul float [[B]], [[B]]1040; CHECK-NEXT: [[A_SQ_B_SQ:%.*]] = fadd float [[A_SQ]], [[B_SQ]]1041; CHECK-NEXT: [[ADD:%.*]] = fadd reassoc nsz float [[NOT_A_B_2]], [[A_SQ_B_SQ]]1042; CHECK-NEXT: ret float [[ADD]]1043;1044 %a_b = fmul float %a, %b1045 %not_a_b_2 = fmul float %a_b, 0x4000CCCCC0000000 ; 2.11046 %a_sq = fmul float %a, %a1047 %b_sq = fmul float %b, %b1048 %a_sq_b_sq = fadd float %a_sq, %b_sq1049 %add = fadd reassoc nsz float %not_a_b_2, %a_sq_b_sq1050 ret float %add1051}1052 1053define float @fadd_reduce_sqr_sum_varB_invalid4(float %a, float %b) {1054; CHECK-LABEL: @fadd_reduce_sqr_sum_varB_invalid4(1055; CHECK-NEXT: [[NOT_A_B:%.*]] = fmul float [[A:%.*]], [[A]]1056; CHECK-NEXT: [[A_B_2:%.*]] = fmul float [[NOT_A_B]], 2.000000e+001057; CHECK-NEXT: [[A_SQ:%.*]] = fmul float [[A]], [[A]]1058; CHECK-NEXT: [[B_SQ:%.*]] = fmul float [[B:%.*]], [[B]]1059; CHECK-NEXT: [[A_SQ_B_SQ:%.*]] = fadd float [[A_SQ]], [[B_SQ]]1060; CHECK-NEXT: [[ADD:%.*]] = fadd reassoc nsz float [[A_B_2]], [[A_SQ_B_SQ]]1061; CHECK-NEXT: ret float [[ADD]]1062;1063 %not_a_b = fmul float %a, %a1064 %a_b_2 = fmul float %not_a_b, 2.01065 %a_sq = fmul float %a, %a1066 %b_sq = fmul float %b, %b1067 %a_sq_b_sq = fadd float %a_sq, %b_sq1068 %add = fadd reassoc nsz float %a_b_2, %a_sq_b_sq1069 ret float %add1070}1071 1072define float @fadd_reduce_sqr_sum_varB_invalid5(float %a, float %b) {1073; CHECK-LABEL: @fadd_reduce_sqr_sum_varB_invalid5(1074; CHECK-NEXT: [[NOT_A_B:%.*]] = fmul float [[B:%.*]], [[B]]1075; CHECK-NEXT: [[A_B_2:%.*]] = fmul float [[NOT_A_B]], 2.000000e+001076; CHECK-NEXT: [[A_SQ:%.*]] = fmul float [[A:%.*]], [[A]]1077; CHECK-NEXT: [[B_SQ:%.*]] = fmul float [[B]], [[B]]1078; CHECK-NEXT: [[A_SQ_B_SQ:%.*]] = fadd float [[A_SQ]], [[B_SQ]]1079; CHECK-NEXT: [[ADD:%.*]] = fadd reassoc nsz float [[A_B_2]], [[A_SQ_B_SQ]]1080; CHECK-NEXT: ret float [[ADD]]1081;1082 %not_a_b = fmul float %b, %b1083 %a_b_2 = fmul float %not_a_b, 2.01084 %a_sq = fmul float %a, %a1085 %b_sq = fmul float %b, %b1086 %a_sq_b_sq = fadd float %a_sq, %b_sq1087 %add = fadd reassoc nsz float %a_b_2, %a_sq_b_sq1088 ret float %add1089}1090 1091define float @fadd_reduce_sqr_sum_varB2_invalid1(float %a, float %b) {1092; CHECK-LABEL: @fadd_reduce_sqr_sum_varB2_invalid1(1093; CHECK-NEXT: [[A_2:%.*]] = fmul float [[A:%.*]], 2.000000e+001094; CHECK-NEXT: [[NOT_A_B_2:%.*]] = fmul float [[A_2]], [[A]]1095; CHECK-NEXT: [[A_SQ:%.*]] = fmul float [[A]], [[A]]1096; CHECK-NEXT: [[B_SQ:%.*]] = fmul float [[B:%.*]], [[B]]1097; CHECK-NEXT: [[A_SQ_B_SQ:%.*]] = fadd float [[A_SQ]], [[B_SQ]]1098; CHECK-NEXT: [[ADD:%.*]] = fadd reassoc nsz float [[NOT_A_B_2]], [[A_SQ_B_SQ]]1099; CHECK-NEXT: ret float [[ADD]]1100;1101 %a_2 = fmul float %a, 2.01102 %not_a_b_2 = fmul float %a_2, %a1103 %a_sq = fmul float %a, %a1104 %b_sq = fmul float %b, %b1105 %a_sq_b_sq = fadd float %a_sq, %b_sq1106 %add = fadd reassoc nsz float %not_a_b_2, %a_sq_b_sq1107 ret float %add1108}1109 1110define float @fadd_reduce_sqr_sum_varB2_invalid2(float %a, float %b) {1111; CHECK-LABEL: @fadd_reduce_sqr_sum_varB2_invalid2(1112; CHECK-NEXT: [[NOT_A_2:%.*]] = fmul float [[A:%.*]], 0x4000CCCCC00000001113; CHECK-NEXT: [[A_B_2:%.*]] = fmul float [[NOT_A_2]], [[B:%.*]]1114; CHECK-NEXT: [[A_SQ:%.*]] = fmul float [[A]], [[A]]1115; CHECK-NEXT: [[B_SQ:%.*]] = fmul float [[B]], [[B]]1116; CHECK-NEXT: [[A_SQ_B_SQ:%.*]] = fadd float [[A_SQ]], [[B_SQ]]1117; CHECK-NEXT: [[ADD:%.*]] = fadd reassoc nsz float [[A_B_2]], [[A_SQ_B_SQ]]1118; CHECK-NEXT: ret float [[ADD]]1119;1120 %not_a_2 = fmul float %a, 0x4000CCCCC0000000 ; 2.11121 %a_b_2 = fmul float %not_a_2, %b1122 %a_sq = fmul float %a, %a1123 %b_sq = fmul float %b, %b1124 %a_sq_b_sq = fadd float %a_sq, %b_sq1125 %add = fadd reassoc nsz float %a_b_2, %a_sq_b_sq1126 ret float %add1127}1128 1129define float @fadd_reduce_sqr_sum_varB2_invalid3(float %a, float %b) {1130; CHECK-LABEL: @fadd_reduce_sqr_sum_varB2_invalid3(1131; CHECK-NEXT: [[NOT_A_2:%.*]] = fmul float [[B:%.*]], 2.000000e+001132; CHECK-NEXT: [[A_B_2:%.*]] = fmul float [[NOT_A_2]], [[B]]1133; CHECK-NEXT: [[A_SQ:%.*]] = fmul float [[A:%.*]], [[A]]1134; CHECK-NEXT: [[B_SQ:%.*]] = fmul float [[B]], [[B]]1135; CHECK-NEXT: [[A_SQ_B_SQ:%.*]] = fadd float [[A_SQ]], [[B_SQ]]1136; CHECK-NEXT: [[ADD:%.*]] = fadd reassoc nsz float [[A_B_2]], [[A_SQ_B_SQ]]1137; CHECK-NEXT: ret float [[ADD]]1138;1139 %not_a_2 = fmul float %b, 2.01140 %a_b_2 = fmul float %not_a_2, %b1141 %a_sq = fmul float %a, %a1142 %b_sq = fmul float %b, %b1143 %a_sq_b_sq = fadd float %a_sq, %b_sq1144 %add = fadd reassoc nsz float %a_b_2, %a_sq_b_sq1145 ret float %add1146}1147 1148declare void @fake_func(float)1149