brintos

brintos / llvm-project-archived public Read only

0
0
Text · 22.8 KiB · 422792a Raw
593 lines · plain
1; NOTE: Assertions have been autogenerated by utils/update_test_checks.py2; RUN: opt -passes=instcombine -S < %s | FileCheck %s3 4declare double @llvm.powi.f64.i32(double, i32)5declare float @llvm.powi.f32.i32(float, i32)6declare double @llvm.powi.f64.i64(double, i64)7declare double @llvm.fabs.f64(double)8declare double @llvm.copysign.f64(double, double)9declare void @use(double)10 11define double @powi_fneg_even_int(double %x) {12; CHECK-LABEL: @powi_fneg_even_int(13; CHECK-NEXT:  entry:14; CHECK-NEXT:    [[R:%.*]] = tail call double @llvm.powi.f64.i32(double [[X:%.*]], i32 4)15; CHECK-NEXT:    ret double [[R]]16;17entry:18  %fneg = fneg double %x19  %r = tail call double @llvm.powi.f64.i32(double %fneg, i32 4)20  ret double %r21}22 23define double @powi_fabs_even_int(double %x) {24; CHECK-LABEL: @powi_fabs_even_int(25; CHECK-NEXT:  entry:26; CHECK-NEXT:    [[R:%.*]] = tail call double @llvm.powi.f64.i32(double [[X:%.*]], i32 4)27; CHECK-NEXT:    ret double [[R]]28;29entry:30  %f = tail call double @llvm.fabs.f64(double %x)31  %r = tail call double @llvm.powi.f64.i32(double %f, i32 4)32  ret double %r33}34 35define double @powi_copysign_even_int(double %x, double %y) {36; CHECK-LABEL: @powi_copysign_even_int(37; CHECK-NEXT:  entry:38; CHECK-NEXT:    [[R:%.*]] = tail call double @llvm.powi.f64.i32(double [[X:%.*]], i32 4)39; CHECK-NEXT:    ret double [[R]]40;41entry:42  %cs = tail call double @llvm.copysign.f64(double %x, double %y)43  %r = tail call double @llvm.powi.f64.i32(double %cs, i32 4)44  ret double %r45}46 47define double @powi_fneg_odd_int(double %x) {48; CHECK-LABEL: @powi_fneg_odd_int(49; CHECK-NEXT:  entry:50; CHECK-NEXT:    [[FNEG:%.*]] = fneg double [[X:%.*]]51; CHECK-NEXT:    [[R:%.*]] = tail call double @llvm.powi.f64.i32(double [[FNEG]], i32 5)52; CHECK-NEXT:    ret double [[R]]53;54entry:55  %fneg = fneg double %x56  %r = tail call double @llvm.powi.f64.i32(double %fneg, i32 5)57  ret double %r58}59 60define double @powi_fabs_odd_int(double %x) {61; CHECK-LABEL: @powi_fabs_odd_int(62; CHECK-NEXT:  entry:63; CHECK-NEXT:    [[F:%.*]] = tail call double @llvm.fabs.f64(double [[X:%.*]])64; CHECK-NEXT:    [[R:%.*]] = tail call double @llvm.powi.f64.i32(double [[F]], i32 5)65; CHECK-NEXT:    ret double [[R]]66;67entry:68  %f = tail call double @llvm.fabs.f64(double %x)69  %r = tail call double @llvm.powi.f64.i32(double %f, i32 5)70  ret double %r71}72 73define double @powi_copysign_odd_int(double %x, double %y) {74; CHECK-LABEL: @powi_copysign_odd_int(75; CHECK-NEXT:  entry:76; CHECK-NEXT:    [[CS:%.*]] = tail call double @llvm.copysign.f64(double [[X:%.*]], double [[Y:%.*]])77; CHECK-NEXT:    [[R:%.*]] = tail call double @llvm.powi.f64.i32(double [[CS]], i32 5)78; CHECK-NEXT:    ret double [[R]]79;80entry:81  %cs = tail call double @llvm.copysign.f64(double %x, double %y)82  %r = tail call double @llvm.powi.f64.i32(double %cs, i32 5)83  ret double %r84}85 86define double @powi_fmul_arg0_no_reassoc(double %x, i32 %i) {87; CHECK-LABEL: @powi_fmul_arg0_no_reassoc(88; CHECK-NEXT:  entry:89; CHECK-NEXT:    [[POW:%.*]] = tail call double @llvm.powi.f64.i32(double [[X:%.*]], i32 [[I:%.*]])90; CHECK-NEXT:    [[MUL:%.*]] = fmul double [[POW]], [[X]]91; CHECK-NEXT:    ret double [[MUL]]92;93entry:94  %pow = tail call double @llvm.powi.f64.i32(double %x, i32 %i)95  %mul = fmul double %pow, %x96  ret double %mul97}98 99 100define double @powi_fmul_arg0(double %x, i32 %i) {101; CHECK-LABEL: @powi_fmul_arg0(102; CHECK-NEXT:  entry:103; CHECK-NEXT:    [[POW:%.*]] = tail call double @llvm.powi.f64.i32(double [[X:%.*]], i32 [[I:%.*]])104; CHECK-NEXT:    [[MUL:%.*]] = fmul reassoc double [[POW]], [[X]]105; CHECK-NEXT:    ret double [[MUL]]106;107entry:108  %pow = tail call double @llvm.powi.f64.i32(double %x, i32 %i)109  %mul = fmul reassoc double %pow, %x110  ret double %mul111}112 113define double @powi_fmul_arg0_use(double %x, i32 %i) {114; CHECK-LABEL: @powi_fmul_arg0_use(115; CHECK-NEXT:  entry:116; CHECK-NEXT:    [[POW:%.*]] = tail call double @llvm.powi.f64.i32(double [[X:%.*]], i32 [[I:%.*]])117; CHECK-NEXT:    tail call void @use(double [[POW]])118; CHECK-NEXT:    [[MUL:%.*]] = fmul reassoc double [[POW]], [[X]]119; CHECK-NEXT:    ret double [[MUL]]120;121entry:122  %pow = tail call double @llvm.powi.f64.i32(double %x, i32 %i)123  tail call void @use(double %pow)124  %mul = fmul reassoc double %pow, %x125  ret double %mul126}127 128; Negative test: Missing reassoc flag on fmul129define double @powi_fmul_powi_no_reassoc1(double %x, i32 %y, i32 %z) {130; CHECK-LABEL: @powi_fmul_powi_no_reassoc1(131; CHECK-NEXT:  entry:132; CHECK-NEXT:    [[P1:%.*]] = tail call reassoc double @llvm.powi.f64.i32(double [[X:%.*]], i32 [[Y:%.*]])133; CHECK-NEXT:    [[P2:%.*]] = tail call reassoc double @llvm.powi.f64.i32(double [[X]], i32 [[Z:%.*]])134; CHECK-NEXT:    [[MUL:%.*]] = fmul double [[P2]], [[P1]]135; CHECK-NEXT:    ret double [[MUL]]136;137entry:138  %p1 = tail call reassoc double @llvm.powi.f64.i32(double %x, i32 %y)139  %p2 = tail call reassoc double @llvm.powi.f64.i32(double %x, i32 %z)140  %mul = fmul double %p2, %p1141  ret double %mul142}143 144; Negative test: Missing reassoc flag on 2nd operand145define double @powi_fmul_powi_no_reassoc2(double %x, i32 %y, i32 %z) {146; CHECK-LABEL: @powi_fmul_powi_no_reassoc2(147; CHECK-NEXT:  entry:148; CHECK-NEXT:    [[P1:%.*]] = tail call reassoc double @llvm.powi.f64.i32(double [[X:%.*]], i32 [[Y:%.*]])149; CHECK-NEXT:    [[P2:%.*]] = tail call double @llvm.powi.f64.i32(double [[X]], i32 [[Z:%.*]])150; CHECK-NEXT:    [[MUL:%.*]] = fmul reassoc double [[P2]], [[P1]]151; CHECK-NEXT:    ret double [[MUL]]152;153entry:154  %p1 = tail call reassoc double @llvm.powi.f64.i32(double %x, i32 %y)155  %p2 = tail call double @llvm.powi.f64.i32(double %x, i32 %z)156  %mul = fmul reassoc double %p2, %p1157  ret double %mul158}159 160; Negative test: Missing reassoc flag on 1st operand161define double @powi_fmul_powi_no_reassoc3(double %x, i32 %y, i32 %z) {162; CHECK-LABEL: @powi_fmul_powi_no_reassoc3(163; CHECK-NEXT:  entry:164; CHECK-NEXT:    [[P1:%.*]] = tail call double @llvm.powi.f64.i32(double [[X:%.*]], i32 [[Y:%.*]])165; CHECK-NEXT:    [[P2:%.*]] = tail call reassoc double @llvm.powi.f64.i32(double [[X]], i32 [[Z:%.*]])166; CHECK-NEXT:    [[MUL:%.*]] = fmul reassoc double [[P2]], [[P1]]167; CHECK-NEXT:    ret double [[MUL]]168;169entry:170  %p1 = tail call double @llvm.powi.f64.i32(double %x, i32 %y)171  %p2 = tail call reassoc double @llvm.powi.f64.i32(double %x, i32 %z)172  %mul = fmul reassoc double %p2, %p1173  ret double %mul174}175 176; All of the fmul and its operands should have the reassoc flags177define double @powi_fmul_powi(double %x, i32 %y, i32 %z) {178; CHECK-LABEL: @powi_fmul_powi(179; CHECK-NEXT:  entry:180; CHECK-NEXT:    [[TMP0:%.*]] = add i32 [[Z:%.*]], [[Y:%.*]]181; CHECK-NEXT:    [[MUL:%.*]] = call reassoc double @llvm.powi.f64.i32(double [[X:%.*]], i32 [[TMP0]])182; CHECK-NEXT:    ret double [[MUL]]183;184entry:185  %p1 = tail call reassoc double @llvm.powi.f64.i32(double %x, i32 %y)186  %p2 = tail call reassoc double @llvm.powi.f64.i32(double %x, i32 %z)187  %mul = fmul reassoc double %p2, %p1188  ret double %mul189}190 191define double @powi_fmul_powi_fast_on_fmul(double %x, i32 %y, i32 %z) {192; CHECK-LABEL: @powi_fmul_powi_fast_on_fmul(193; CHECK-NEXT:  entry:194; CHECK-NEXT:    [[TMP0:%.*]] = add i32 [[Z:%.*]], [[Y:%.*]]195; CHECK-NEXT:    [[MUL:%.*]] = call fast double @llvm.powi.f64.i32(double [[X:%.*]], i32 [[TMP0]])196; CHECK-NEXT:    ret double [[MUL]]197;198entry:199  %p1 = tail call fast double @llvm.powi.f64.i32(double %x, i32 %y)200  %p2 = tail call fast double @llvm.powi.f64.i32(double %x, i32 %z)201  %mul = fmul fast double %p2, %p1202  ret double %mul203}204 205define double @powi_fmul_powi_fast_on_powi(double %x, i32 %y, i32 %z) {206; CHECK-LABEL: @powi_fmul_powi_fast_on_powi(207; CHECK-NEXT:  entry:208; CHECK-NEXT:    [[P1:%.*]] = tail call fast double @llvm.powi.f64.i32(double [[X:%.*]], i32 [[Y:%.*]])209; CHECK-NEXT:    [[P2:%.*]] = tail call fast double @llvm.powi.f64.i32(double [[X]], i32 [[Z:%.*]])210; CHECK-NEXT:    [[MUL:%.*]] = fmul double [[P2]], [[P1]]211; CHECK-NEXT:    ret double [[MUL]]212;213entry:214  %p1 = tail call fast double @llvm.powi.f64.i32(double %x, i32 %y)215  %p2 = tail call fast double @llvm.powi.f64.i32(double %x, i32 %z)216  %mul = fmul double %p2, %p1217  ret double %mul218}219 220define double @powi_fmul_powi_same_power(double %x, i32 %y, i32 %z) {221; CHECK-LABEL: @powi_fmul_powi_same_power(222; CHECK-NEXT:  entry:223; CHECK-NEXT:    [[TMP0:%.*]] = shl i32 [[Y:%.*]], 1224; CHECK-NEXT:    [[MUL:%.*]] = call reassoc double @llvm.powi.f64.i32(double [[X:%.*]], i32 [[TMP0]])225; CHECK-NEXT:    ret double [[MUL]]226;227entry:228  %p1 = tail call reassoc double @llvm.powi.f64.i32(double %x, i32 %y)229  %p2 = tail call reassoc double @llvm.powi.f64.i32(double %x, i32 %y)230  %mul = fmul reassoc double %p2, %p1231  ret double %mul232}233 234define double @powi_fmul_powi_different_integer_types(double %x, i32 %y, i16 %z) {235; CHECK-LABEL: @powi_fmul_powi_different_integer_types(236; CHECK-NEXT:  entry:237; CHECK-NEXT:    [[P1:%.*]] = tail call reassoc double @llvm.powi.f64.i32(double [[X:%.*]], i32 [[Y:%.*]])238; CHECK-NEXT:    [[P2:%.*]] = tail call reassoc double @llvm.powi.f64.i16(double [[X]], i16 [[Z:%.*]])239; CHECK-NEXT:    [[MUL:%.*]] = fmul reassoc double [[P2]], [[P1]]240; CHECK-NEXT:    ret double [[MUL]]241;242entry:243  %p1 = tail call reassoc double @llvm.powi.f64.i32(double %x, i32 %y)244  %p2 = tail call reassoc double @llvm.powi.f64.i16(double %x, i16 %z)245  %mul = fmul reassoc double %p2, %p1246  ret double %mul247}248 249define double @powi_fmul_powi_use_first(double %x, i32 %y, i32 %z) {250; CHECK-LABEL: @powi_fmul_powi_use_first(251; CHECK-NEXT:  entry:252; CHECK-NEXT:    [[P1:%.*]] = tail call reassoc double @llvm.powi.f64.i32(double [[X:%.*]], i32 [[Y:%.*]])253; CHECK-NEXT:    tail call void @use(double [[P1]])254; CHECK-NEXT:    [[TMP0:%.*]] = add i32 [[Y]], [[Z:%.*]]255; CHECK-NEXT:    [[MUL:%.*]] = call reassoc double @llvm.powi.f64.i32(double [[X]], i32 [[TMP0]])256; CHECK-NEXT:    ret double [[MUL]]257;258entry:259  %p1 = tail call reassoc double @llvm.powi.f64.i32(double %x, i32 %y)260  tail call void @use(double %p1)261  %p2 = tail call reassoc double @llvm.powi.f64.i32(double %x, i32 %z)262  %mul = fmul reassoc double %p1, %p2263  ret double %mul264}265 266define double @powi_fmul_powi_use_second(double %x, i32 %y, i32 %z) {267; CHECK-LABEL: @powi_fmul_powi_use_second(268; CHECK-NEXT:  entry:269; CHECK-NEXT:    [[P1:%.*]] = tail call reassoc double @llvm.powi.f64.i32(double [[X:%.*]], i32 [[Z:%.*]])270; CHECK-NEXT:    tail call void @use(double [[P1]])271; CHECK-NEXT:    [[TMP0:%.*]] = add i32 [[Y:%.*]], [[Z]]272; CHECK-NEXT:    [[MUL:%.*]] = call reassoc double @llvm.powi.f64.i32(double [[X]], i32 [[TMP0]])273; CHECK-NEXT:    ret double [[MUL]]274;275entry:276  %p1 = tail call reassoc double @llvm.powi.f64.i32(double %x, i32 %z)277  tail call void @use(double %p1)278  %p2 = tail call reassoc double @llvm.powi.f64.i32(double %x, i32 %y)279  %mul = fmul reassoc double %p2, %p1280  ret double %mul281}282 283define double @powi_fmul_different_base(double %x, double %m, i32 %y, i32 %z) {284; CHECK-LABEL: @powi_fmul_different_base(285; CHECK-NEXT:  entry:286; CHECK-NEXT:    [[P1:%.*]] = tail call double @llvm.powi.f64.i32(double [[X:%.*]], i32 [[Y:%.*]])287; CHECK-NEXT:    [[P2:%.*]] = tail call double @llvm.powi.f64.i32(double [[M:%.*]], i32 [[Z:%.*]])288; CHECK-NEXT:    [[MUL:%.*]] = fmul reassoc double [[P2]], [[P1]]289; CHECK-NEXT:    ret double [[MUL]]290;291entry:292  %p1 = tail call double @llvm.powi.f64.i32(double %x, i32 %y)293  %p2 = tail call double @llvm.powi.f64.i32(double %m, i32 %z)294  %mul = fmul reassoc double %p2, %p1295  ret double %mul296}297 298define double @different_types_powi(double %x, i32 %y, i64 %z) {299; CHECK-LABEL: @different_types_powi(300; CHECK-NEXT:    [[P1:%.*]] = tail call double @llvm.powi.f64.i32(double [[X:%.*]], i32 [[Y:%.*]])301; CHECK-NEXT:    [[P2:%.*]] = tail call double @llvm.powi.f64.i64(double [[X]], i64 [[Z:%.*]])302; CHECK-NEXT:    [[MUL:%.*]] = fmul reassoc double [[P2]], [[P1]]303; CHECK-NEXT:    ret double [[MUL]]304;305  %p1 = tail call double @llvm.powi.f64.i32(double %x, i32 %y)306  %p2 = tail call double @llvm.powi.f64.i64(double %x, i64 %z)307  %mul = fmul reassoc double %p2, %p1308  ret double %mul309}310 311define double @fdiv_pow_powi(double %x) {312; CHECK-LABEL: @fdiv_pow_powi(313; CHECK-NEXT:    [[DIV:%.*]] = fmul reassoc nnan double [[X:%.*]], [[X]]314; CHECK-NEXT:    ret double [[DIV]]315;316  %p1 = call reassoc double @llvm.powi.f64.i32(double %x, i32 3)317  %div = fdiv reassoc nnan double %p1, %x318  ret double %div319}320 321define float @fdiv_powf_powi(float %x) {322; CHECK-LABEL: @fdiv_powf_powi(323; CHECK-NEXT:    [[DIV:%.*]] = call reassoc nnan float @llvm.powi.f32.i32(float [[X:%.*]], i32 99)324; CHECK-NEXT:    ret float [[DIV]]325;326  %p1 = call reassoc float @llvm.powi.f32.i32(float %x, i32 100)327  %div = fdiv reassoc nnan float %p1, %x328  ret float %div329}330 331; TODO: Multi-use may be also better off creating Powi(x,y-1) then creating332; (mul, Powi(x,y-1),x) to replace the Powi(x,y).333define double @fdiv_pow_powi_multi_use(double %x) {334; CHECK-LABEL: @fdiv_pow_powi_multi_use(335; CHECK-NEXT:    [[P1:%.*]] = call double @llvm.powi.f64.i32(double [[X:%.*]], i32 3)336; CHECK-NEXT:    [[DIV:%.*]] = fdiv reassoc nnan double [[P1]], [[X]]337; CHECK-NEXT:    tail call void @use(double [[P1]])338; CHECK-NEXT:    ret double [[DIV]]339;340  %p1 = call double @llvm.powi.f64.i32(double %x, i32 3)341  %div = fdiv reassoc nnan double %p1, %x342  tail call void @use(double %p1)343  ret double %div344}345 346; Negative test: Miss part of the fmf flag for the fdiv instruction347define float @fdiv_powf_powi_missing_reassoc(float %x) {348; CHECK-LABEL: @fdiv_powf_powi_missing_reassoc(349; CHECK-NEXT:    [[P1:%.*]] = call float @llvm.powi.f32.i32(float [[X:%.*]], i32 100)350; CHECK-NEXT:    [[DIV:%.*]] = fdiv reassoc nnan float [[P1]], [[X]]351; CHECK-NEXT:    ret float [[DIV]]352;353  %p1 = call float @llvm.powi.f32.i32(float %x, i32 100)354  %div = fdiv reassoc nnan float %p1, %x355  ret float %div356}357 358define float @fdiv_powf_powi_missing_reassoc1(float %x) {359; CHECK-LABEL: @fdiv_powf_powi_missing_reassoc1(360; CHECK-NEXT:    [[P1:%.*]] = call reassoc float @llvm.powi.f32.i32(float [[X:%.*]], i32 100)361; CHECK-NEXT:    [[DIV:%.*]] = fdiv nnan float [[P1]], [[X]]362; CHECK-NEXT:    ret float [[DIV]]363;364  %p1 = call reassoc float @llvm.powi.f32.i32(float %x, i32 100)365  %div = fdiv nnan float %p1, %x366  ret float %div367}368 369define float @fdiv_powf_powi_missing_nnan(float %x) {370; CHECK-LABEL: @fdiv_powf_powi_missing_nnan(371; CHECK-NEXT:    [[P1:%.*]] = call float @llvm.powi.f32.i32(float [[X:%.*]], i32 100)372; CHECK-NEXT:    [[DIV:%.*]] = fdiv reassoc float [[P1]], [[X]]373; CHECK-NEXT:    ret float [[DIV]]374;375  %p1 = call float @llvm.powi.f32.i32(float %x, i32 100)376  %div = fdiv reassoc float %p1, %x377  ret float %div378}379 380; Negative test: Illegal because (Y - 1) wraparound381define double @fdiv_pow_powi_negative(double %x) {382; CHECK-LABEL: @fdiv_pow_powi_negative(383; CHECK-NEXT:    [[P1:%.*]] = call double @llvm.powi.f64.i32(double [[X:%.*]], i32 -2147483648)384; CHECK-NEXT:    [[DIV:%.*]] = fdiv reassoc nnan double [[P1]], [[X]]385; CHECK-NEXT:    ret double [[DIV]]386;387  %p1 = call double @llvm.powi.f64.i32(double %x, i32 -2147483648) ; INT_MIN388  %div = fdiv reassoc nnan double %p1, %x389  ret double %div390}391 392; Negative test: The 2nd powi argument is a variable393define double @fdiv_pow_powi_negative_variable(double %x, i32 %y) {394; CHECK-LABEL: @fdiv_pow_powi_negative_variable(395; CHECK-NEXT:    [[P1:%.*]] = call reassoc double @llvm.powi.f64.i32(double [[X:%.*]], i32 [[Y:%.*]])396; CHECK-NEXT:    [[DIV:%.*]] = fdiv reassoc nnan double [[P1]], [[X]]397; CHECK-NEXT:    ret double [[DIV]]398;399  %p1 = call reassoc double @llvm.powi.f64.i32(double %x, i32 %y)400  %div = fdiv reassoc nnan double %p1, %x401  ret double %div402}403 404; powi(X,C1)/ (X * Z) --> powi(X,C1 - 1)/ Z405define double @fdiv_fmul_powi(double %a, double %z) {406; CHECK-LABEL: @fdiv_fmul_powi(407; CHECK-NEXT:    [[TMP1:%.*]] = call reassoc nnan double @llvm.powi.f64.i32(double [[A:%.*]], i32 4)408; CHECK-NEXT:    [[DIV:%.*]] = fdiv reassoc nnan double [[TMP1]], [[Z:%.*]]409; CHECK-NEXT:    ret double [[DIV]]410;411  %pow = call reassoc double @llvm.powi.f64.i32(double %a, i32 5)412  %square = fmul reassoc double %z, %a413  %div = fdiv reassoc nnan double %pow, %square414  ret double %div415}416 417; powi(X, 5)/ (X * X) --> powi(X, 4)/ X -> powi(X, 3)418define double @fdiv_fmul_powi_2(double %a) {419; CHECK-LABEL: @fdiv_fmul_powi_2(420; CHECK-NEXT:    [[DIV:%.*]] = call reassoc nnan double @llvm.powi.f64.i32(double [[A:%.*]], i32 3)421; CHECK-NEXT:    ret double [[DIV]]422;423  %pow = call reassoc double @llvm.powi.f64.i32(double %a, i32 5)424  %square = fmul reassoc double %a, %a425  %div = fdiv reassoc nnan double %pow, %square426  ret double %div427}428 429define <2 x float> @fdiv_fmul_powi_vector(<2 x float> %a) {430; CHECK-LABEL: @fdiv_fmul_powi_vector(431; CHECK-NEXT:    [[DIV:%.*]] = call reassoc nnan <2 x float> @llvm.powi.v2f32.i32(<2 x float> [[A:%.*]], i32 3)432; CHECK-NEXT:    ret <2 x float> [[DIV]]433;434  %pow = call reassoc <2 x float> @llvm.powi.v2f32.i32(<2 x float> %a, i32 5)435  %square = fmul reassoc <2 x float> %a, %a436  %div = fdiv reassoc nnan <2 x float> %pow, %square437  ret <2 x float> %div438}439 440; Negative test441define double @fdiv_fmul_powi_missing_reassoc1(double %a) {442; CHECK-LABEL: @fdiv_fmul_powi_missing_reassoc1(443; CHECK-NEXT:    [[POW:%.*]] = call reassoc double @llvm.powi.f64.i32(double [[A:%.*]], i32 5)444; CHECK-NEXT:    [[SQUARE:%.*]] = fmul reassoc double [[A]], [[A]]445; CHECK-NEXT:    [[DIV:%.*]] = fdiv nnan double [[POW]], [[SQUARE]]446; CHECK-NEXT:    ret double [[DIV]]447;448  %pow = call reassoc double @llvm.powi.f64.i32(double %a, i32 5)449  %square = fmul reassoc double %a, %a450  %div = fdiv nnan double %pow, %square451  ret double %div452}453 454define double @fdiv_fmul_powi_missing_reassoc2(double %a) {455; CHECK-LABEL: @fdiv_fmul_powi_missing_reassoc2(456; CHECK-NEXT:    [[POW:%.*]] = call reassoc double @llvm.powi.f64.i32(double [[A:%.*]], i32 5)457; CHECK-NEXT:    [[SQUARE:%.*]] = fmul double [[A]], [[A]]458; CHECK-NEXT:    [[DIV:%.*]] = fdiv reassoc nnan double [[POW]], [[SQUARE]]459; CHECK-NEXT:    ret double [[DIV]]460;461  %pow = call reassoc double @llvm.powi.f64.i32(double %a, i32 5)462  %square = fmul double %a, %a463  %div = fdiv reassoc nnan double %pow, %square464  ret double %div465}466 467define double @fdiv_fmul_powi_missing_reassoc3(double %a) {468; CHECK-LABEL: @fdiv_fmul_powi_missing_reassoc3(469; CHECK-NEXT:    [[POW:%.*]] = call double @llvm.powi.f64.i32(double [[A:%.*]], i32 5)470; CHECK-NEXT:    [[SQUARE:%.*]] = fmul reassoc double [[A]], [[A]]471; CHECK-NEXT:    [[DIV:%.*]] = fdiv reassoc nnan double [[POW]], [[SQUARE]]472; CHECK-NEXT:    ret double [[DIV]]473;474  %pow = call double @llvm.powi.f64.i32(double %a, i32 5)475  %square = fmul reassoc double %a, %a476  %div = fdiv reassoc nnan double %pow, %square477  ret double %div478}479 480define double @fdiv_fmul_powi_missing_nnan(double %a) {481; CHECK-LABEL: @fdiv_fmul_powi_missing_nnan(482; CHECK-NEXT:    [[POW:%.*]] = call reassoc double @llvm.powi.f64.i32(double [[A:%.*]], i32 5)483; CHECK-NEXT:    [[SQUARE:%.*]] = fmul reassoc double [[A]], [[A]]484; CHECK-NEXT:    [[DIV:%.*]] = fdiv reassoc double [[POW]], [[SQUARE]]485; CHECK-NEXT:    ret double [[DIV]]486;487  %pow = call reassoc double @llvm.powi.f64.i32(double %a, i32 5)488  %square = fmul reassoc double %a, %a489  %div = fdiv reassoc double %pow, %square490  ret double %div491}492 493define double @fdiv_fmul_powi_negative_wrap(double noundef %x) {494; CHECK-LABEL: @fdiv_fmul_powi_negative_wrap(495; CHECK-NEXT:    [[P1:%.*]] = tail call double @llvm.powi.f64.i32(double [[X:%.*]], i32 -2147483648)496; CHECK-NEXT:    [[MUL:%.*]] = fmul reassoc double [[P1]], [[X]]497; CHECK-NEXT:    ret double [[MUL]]498;499  %p1 = tail call double @llvm.powi.f64.i32(double %x, i32 -2147483648) ; INT_MIN500  %mul = fmul reassoc double %p1, %x501  ret double %mul502}503 504define double @fdiv_fmul_powi_multi_use(double %a) {505; CHECK-LABEL: @fdiv_fmul_powi_multi_use(506; CHECK-NEXT:    [[POW:%.*]] = call reassoc double @llvm.powi.f64.i32(double [[A:%.*]], i32 5)507; CHECK-NEXT:    tail call void @use(double [[POW]])508; CHECK-NEXT:    [[SQUARE:%.*]] = fmul reassoc double [[A]], [[A]]509; CHECK-NEXT:    [[DIV:%.*]] = fdiv reassoc nnan double [[POW]], [[SQUARE]]510; CHECK-NEXT:    ret double [[DIV]]511;512  %pow = call reassoc double @llvm.powi.f64.i32(double %a, i32 5)513  tail call void @use(double %pow)514  %square = fmul reassoc double %a, %a515  %div = fdiv reassoc nnan double %pow, %square516  ret double %div517}518 519; powi(X, Y) * X --> powi(X, Y+1)520define double @powi_fmul_powi_x(double noundef %x) {521; CHECK-LABEL: @powi_fmul_powi_x(522; CHECK-NEXT:    [[MUL:%.*]] = call reassoc double @llvm.powi.f64.i32(double [[X:%.*]], i32 4)523; CHECK-NEXT:    ret double [[MUL]]524;525  %p1 = tail call reassoc double @llvm.powi.f64.i32(double %x, i32 3)526  %mul = fmul reassoc double %p1, %x527  ret double %mul528}529 530; Negative test: Multi-use531define double @powi_fmul_powi_x_multi_use(double noundef %x) {532; CHECK-LABEL: @powi_fmul_powi_x_multi_use(533; CHECK-NEXT:    [[P1:%.*]] = tail call double @llvm.powi.f64.i32(double [[X:%.*]], i32 3)534; CHECK-NEXT:    tail call void @use(double [[P1]])535; CHECK-NEXT:    [[MUL:%.*]] = fmul reassoc double [[P1]], [[X]]536; CHECK-NEXT:    ret double [[MUL]]537;538  %p1 = tail call double @llvm.powi.f64.i32(double %x, i32 3)539  tail call void @use(double %p1)540  %mul = fmul reassoc double %p1, %x541  ret double %mul542}543 544; Negative test: Miss fmf flag545define double @powi_fmul_powi_x_missing_reassoc(double noundef %x) {546; CHECK-LABEL: @powi_fmul_powi_x_missing_reassoc(547; CHECK-NEXT:    [[P1:%.*]] = tail call double @llvm.powi.f64.i32(double [[X:%.*]], i32 3)548; CHECK-NEXT:    [[MUL:%.*]] = fmul double [[P1]], [[X]]549; CHECK-NEXT:    ret double [[MUL]]550;551  %p1 = tail call double @llvm.powi.f64.i32(double %x, i32 3)552  %mul = fmul double %p1, %x553  ret double %mul554}555 556; Negative test: overflow557define double @powi_fmul_powi_x_overflow(double noundef %x) {558; CHECK-LABEL: @powi_fmul_powi_x_overflow(559; CHECK-NEXT:    [[P1:%.*]] = tail call double @llvm.powi.f64.i32(double [[X:%.*]], i32 2147483647)560; CHECK-NEXT:    [[MUL:%.*]] = fmul reassoc double [[P1]], [[X]]561; CHECK-NEXT:    ret double [[MUL]]562;563  %p1 = tail call double @llvm.powi.f64.i32(double %x, i32 2147483647) ; INT_MAX564  %mul = fmul reassoc double %p1, %x565  ret double %mul566}567 568define <3 x float> @powi_unary_shuffle_ops(<3 x float> %x, i32 %power) {569; CHECK-LABEL: @powi_unary_shuffle_ops(570; CHECK-NEXT:    [[TMP1:%.*]] = call <3 x float> @llvm.powi.v3f32.i32(<3 x float> [[X:%.*]], i32 [[POWER:%.*]])571; CHECK-NEXT:    [[R:%.*]] = shufflevector <3 x float> [[TMP1]], <3 x float> poison, <3 x i32> <i32 1, i32 0, i32 2>572; CHECK-NEXT:    ret <3 x float> [[R]]573;574  %sx = shufflevector <3 x float> %x, <3 x float> poison, <3 x i32> <i32 1, i32 0, i32 2>575  %r = call <3 x float> @llvm.powi(<3 x float> %sx, i32 %power)576  ret <3 x float> %r577}578 579; Negative test - multiple uses580 581define <3 x float> @powi_unary_shuffle_ops_use(<3 x float> %x, i32 %power, ptr %p) {582; CHECK-LABEL: @powi_unary_shuffle_ops_use(583; CHECK-NEXT:    [[SX:%.*]] = shufflevector <3 x float> [[X:%.*]], <3 x float> poison, <3 x i32> <i32 1, i32 0, i32 2>584; CHECK-NEXT:    store <3 x float> [[SX]], ptr [[P:%.*]], align 16585; CHECK-NEXT:    [[R:%.*]] = call <3 x float> @llvm.powi.v3f32.i32(<3 x float> [[SX]], i32 [[POWER:%.*]])586; CHECK-NEXT:    ret <3 x float> [[R]]587;588  %sx = shufflevector <3 x float> %x, <3 x float> poison, <3 x i32> <i32 1, i32 0, i32 2>589  store <3 x float> %sx, ptr %p590  %r = call <3 x float> @llvm.powi(<3 x float> %sx, i32 %power)591  ret <3 x float> %r592}593