545 lines · plain
1; NOTE: Assertions have been autogenerated by utils/update_test_checks.py UTC_ARGS: --version 32; RUN: opt -mtriple unknown -passes=instcombine -S < %s | FileCheck %s3target datalayout = "e"4 5; PR421906; Can't generate test checks due to PR42740.7 8define double @pow_sitofp_const_base_fast(i32 %x) {9; CHECK-LABEL: define double @pow_sitofp_const_base_fast(10; CHECK-SAME: i32 [[X:%.*]]) {11; CHECK-NEXT: [[POW:%.*]] = tail call afn float @llvm.powi.f32.i32(float 7.000000e+00, i32 [[X]])12; CHECK-NEXT: [[RES:%.*]] = fpext float [[POW]] to double13; CHECK-NEXT: ret double [[RES]]14;15 %subfp = sitofp i32 %x to float16 %pow = tail call afn float @llvm.pow.f32(float 7.000000e+00, float %subfp)17 %res = fpext float %pow to double18 ret double %res19}20 21define double @pow_uitofp_const_base_fast(i31 %x) {22; CHECK-LABEL: define double @pow_uitofp_const_base_fast(23; CHECK-SAME: i31 [[X:%.*]]) {24; CHECK-NEXT: [[TMP1:%.*]] = zext i31 [[X]] to i3225; CHECK-NEXT: [[POW:%.*]] = tail call afn float @llvm.powi.f32.i32(float 7.000000e+00, i32 [[TMP1]])26; CHECK-NEXT: [[RES:%.*]] = fpext float [[POW]] to double27; CHECK-NEXT: ret double [[RES]]28;29 %subfp = uitofp i31 %x to float30 %pow = tail call afn float @llvm.pow.f32(float 7.000000e+00, float %subfp)31 %res = fpext float %pow to double32 ret double %res33}34 35define double @pow_sitofp_double_const_base_fast(i32 %x) {36; CHECK-LABEL: define double @pow_sitofp_double_const_base_fast(37; CHECK-SAME: i32 [[X:%.*]]) {38; CHECK-NEXT: [[POW:%.*]] = tail call afn double @llvm.powi.f64.i32(double 7.000000e+00, i32 [[X]])39; CHECK-NEXT: ret double [[POW]]40;41 %subfp = sitofp i32 %x to double42 %pow = tail call afn double @llvm.pow.f64(double 7.000000e+00, double %subfp)43 ret double %pow44}45 46define double @pow_uitofp_double_const_base_fast(i31 %x) {47; CHECK-LABEL: define double @pow_uitofp_double_const_base_fast(48; CHECK-SAME: i31 [[X:%.*]]) {49; CHECK-NEXT: [[TMP1:%.*]] = zext i31 [[X]] to i3250; CHECK-NEXT: [[POW:%.*]] = tail call afn double @llvm.powi.f64.i32(double 7.000000e+00, i32 [[TMP1]])51; CHECK-NEXT: ret double [[POW]]52;53 %subfp = uitofp i31 %x to double54 %pow = tail call afn double @llvm.pow.f64(double 7.000000e+00, double %subfp)55 ret double %pow56}57 58define double @pow_sitofp_double_const_base_2_fast(i32 %x) {59; CHECK-LABEL: define double @pow_sitofp_double_const_base_2_fast(60; CHECK-SAME: i32 [[X:%.*]]) {61; CHECK-NEXT: [[LDEXPF:%.*]] = tail call afn float @llvm.ldexp.f32.i32(float 1.000000e+00, i32 [[X]])62; CHECK-NEXT: [[RES:%.*]] = fpext float [[LDEXPF]] to double63; CHECK-NEXT: ret double [[RES]]64;65 %subfp = sitofp i32 %x to float66 %pow = tail call afn float @llvm.pow.f32(float 2.000000e+00, float %subfp)67 %res = fpext float %pow to double68 ret double %res69}70 71define double @pow_sitofp_double_const_base_power_of_2_fast(i32 %x) {72; CHECK-LABEL: define double @pow_sitofp_double_const_base_power_of_2_fast(73; CHECK-SAME: i32 [[X:%.*]]) {74; CHECK-NEXT: [[SUBFP:%.*]] = sitofp i32 [[X]] to float75; CHECK-NEXT: [[MUL:%.*]] = fmul afn float [[SUBFP]], 4.000000e+0076; CHECK-NEXT: [[EXP2:%.*]] = tail call afn float @llvm.exp2.f32(float [[MUL]])77; CHECK-NEXT: [[RES:%.*]] = fpext float [[EXP2]] to double78; CHECK-NEXT: ret double [[RES]]79;80 %subfp = sitofp i32 %x to float81 %pow = tail call afn float @llvm.pow.f32(float 16.000000e+00, float %subfp)82 %res = fpext float %pow to double83 ret double %res84}85 86define double @pow_uitofp_const_base_2_fast(i31 %x) {87; CHECK-LABEL: define double @pow_uitofp_const_base_2_fast(88; CHECK-SAME: i31 [[X:%.*]]) {89; CHECK-NEXT: [[TMP1:%.*]] = zext i31 [[X]] to i3290; CHECK-NEXT: [[LDEXPF:%.*]] = tail call afn float @llvm.ldexp.f32.i32(float 1.000000e+00, i32 [[TMP1]])91; CHECK-NEXT: [[RES:%.*]] = fpext float [[LDEXPF]] to double92; CHECK-NEXT: ret double [[RES]]93;94 %subfp = uitofp i31 %x to float95 %pow = tail call afn float @llvm.pow.f32(float 2.000000e+00, float %subfp)96 %res = fpext float %pow to double97 ret double %res98}99 100define double @pow_uitofp_const_base_power_of_2_fast(i31 %x) {101; CHECK-LABEL: define double @pow_uitofp_const_base_power_of_2_fast(102; CHECK-SAME: i31 [[X:%.*]]) {103; CHECK-NEXT: [[SUBFP:%.*]] = uitofp i31 [[X]] to float104; CHECK-NEXT: [[MUL:%.*]] = fmul afn float [[SUBFP]], 4.000000e+00105; CHECK-NEXT: [[EXP2:%.*]] = tail call afn float @llvm.exp2.f32(float [[MUL]])106; CHECK-NEXT: [[RES:%.*]] = fpext float [[EXP2]] to double107; CHECK-NEXT: ret double [[RES]]108;109 %subfp = uitofp i31 %x to float110 %pow = tail call afn float @llvm.pow.f32(float 16.000000e+00, float %subfp)111 %res = fpext float %pow to double112 ret double %res113}114 115define double @pow_sitofp_float_base_fast(float %base, i32 %x) {116; CHECK-LABEL: define double @pow_sitofp_float_base_fast(117; CHECK-SAME: float [[BASE:%.*]], i32 [[X:%.*]]) {118; CHECK-NEXT: [[POW:%.*]] = tail call afn float @llvm.powi.f32.i32(float [[BASE]], i32 [[X]])119; CHECK-NEXT: [[RES:%.*]] = fpext float [[POW]] to double120; CHECK-NEXT: ret double [[RES]]121;122 %subfp = sitofp i32 %x to float123 %pow = tail call afn float @llvm.pow.f32(float %base, float %subfp)124 %res = fpext float %pow to double125 ret double %res126}127 128define double @pow_uitofp_float_base_fast(float %base, i31 %x) {129; CHECK-LABEL: define double @pow_uitofp_float_base_fast(130; CHECK-SAME: float [[BASE:%.*]], i31 [[X:%.*]]) {131; CHECK-NEXT: [[TMP1:%.*]] = zext i31 [[X]] to i32132; CHECK-NEXT: [[POW:%.*]] = tail call afn float @llvm.powi.f32.i32(float [[BASE]], i32 [[TMP1]])133; CHECK-NEXT: [[RES:%.*]] = fpext float [[POW]] to double134; CHECK-NEXT: ret double [[RES]]135;136 %subfp = uitofp i31 %x to float137 %pow = tail call afn float @llvm.pow.f32(float %base, float %subfp)138 %res = fpext float %pow to double139 ret double %res140}141 142define double @pow_sitofp_double_base_fast(double %base, i32 %x) {143; CHECK-LABEL: define double @pow_sitofp_double_base_fast(144; CHECK-SAME: double [[BASE:%.*]], i32 [[X:%.*]]) {145; CHECK-NEXT: [[RES:%.*]] = tail call afn double @llvm.powi.f64.i32(double [[BASE]], i32 [[X]])146; CHECK-NEXT: ret double [[RES]]147;148 %subfp = sitofp i32 %x to double149 %res = tail call afn double @llvm.pow.f64(double %base, double %subfp)150 ret double %res151}152 153define double @pow_uitofp_double_base_fast(double %base, i31 %x) {154; CHECK-LABEL: define double @pow_uitofp_double_base_fast(155; CHECK-SAME: double [[BASE:%.*]], i31 [[X:%.*]]) {156; CHECK-NEXT: [[TMP1:%.*]] = zext i31 [[X]] to i32157; CHECK-NEXT: [[RES:%.*]] = tail call afn double @llvm.powi.f64.i32(double [[BASE]], i32 [[TMP1]])158; CHECK-NEXT: ret double [[RES]]159;160 %subfp = uitofp i31 %x to double161 %res = tail call afn double @llvm.pow.f64(double %base, double %subfp)162 ret double %res163}164 165define double @pow_sitofp_const_base_fast_i8(i8 %x) {166; CHECK-LABEL: define double @pow_sitofp_const_base_fast_i8(167; CHECK-SAME: i8 [[X:%.*]]) {168; CHECK-NEXT: [[TMP1:%.*]] = sext i8 [[X]] to i32169; CHECK-NEXT: [[POW:%.*]] = tail call afn float @llvm.powi.f32.i32(float 7.000000e+00, i32 [[TMP1]])170; CHECK-NEXT: [[RES:%.*]] = fpext float [[POW]] to double171; CHECK-NEXT: ret double [[RES]]172;173 %subfp = sitofp i8 %x to float174 %pow = tail call afn float @llvm.pow.f32(float 7.000000e+00, float %subfp)175 %res = fpext float %pow to double176 ret double %res177}178 179define double @pow_sitofp_const_base_fast_i16(i16 %x) {180; CHECK-LABEL: define double @pow_sitofp_const_base_fast_i16(181; CHECK-SAME: i16 [[X:%.*]]) {182; CHECK-NEXT: [[TMP1:%.*]] = sext i16 [[X]] to i32183; CHECK-NEXT: [[POW:%.*]] = tail call afn float @llvm.powi.f32.i32(float 7.000000e+00, i32 [[TMP1]])184; CHECK-NEXT: [[RES:%.*]] = fpext float [[POW]] to double185; CHECK-NEXT: ret double [[RES]]186;187 %subfp = sitofp i16 %x to float188 %pow = tail call afn float @llvm.pow.f32(float 7.000000e+00, float %subfp)189 %res = fpext float %pow to double190 ret double %res191}192 193 194define double @pow_uitofp_const_base_fast_i8(i8 %x) {195; CHECK-LABEL: define double @pow_uitofp_const_base_fast_i8(196; CHECK-SAME: i8 [[X:%.*]]) {197; CHECK-NEXT: [[TMP1:%.*]] = zext i8 [[X]] to i32198; CHECK-NEXT: [[POW:%.*]] = tail call afn float @llvm.powi.f32.i32(float 7.000000e+00, i32 [[TMP1]])199; CHECK-NEXT: [[RES:%.*]] = fpext float [[POW]] to double200; CHECK-NEXT: ret double [[RES]]201;202 %subfp = uitofp i8 %x to float203 %pow = tail call afn float @llvm.pow.f32(float 7.000000e+00, float %subfp)204 %res = fpext float %pow to double205 ret double %res206}207 208define double @pow_uitofp_const_base_fast_i16(i16 %x) {209; CHECK-LABEL: define double @pow_uitofp_const_base_fast_i16(210; CHECK-SAME: i16 [[X:%.*]]) {211; CHECK-NEXT: [[TMP1:%.*]] = zext i16 [[X]] to i32212; CHECK-NEXT: [[POW:%.*]] = tail call afn float @llvm.powi.f32.i32(float 7.000000e+00, i32 [[TMP1]])213; CHECK-NEXT: [[RES:%.*]] = fpext float [[POW]] to double214; CHECK-NEXT: ret double [[RES]]215;216 %subfp = uitofp i16 %x to float217 %pow = tail call afn float @llvm.pow.f32(float 7.000000e+00, float %subfp)218 %res = fpext float %pow to double219 ret double %res220}221 222define double @powf_exp_const_int_fast(double %base) {223; CHECK-LABEL: define double @powf_exp_const_int_fast(224; CHECK-SAME: double [[BASE:%.*]]) {225; CHECK-NEXT: [[RES:%.*]] = tail call fast double @llvm.powi.f64.i32(double [[BASE]], i32 40)226; CHECK-NEXT: ret double [[RES]]227;228 %res = tail call fast double @llvm.pow.f64(double %base, double 4.000000e+01)229 ret double %res230}231 232define double @powf_exp_const2_int_fast(double %base) {233; CHECK-LABEL: define double @powf_exp_const2_int_fast(234; CHECK-SAME: double [[BASE:%.*]]) {235; CHECK-NEXT: [[RES:%.*]] = tail call fast double @llvm.powi.f64.i32(double [[BASE]], i32 -40)236; CHECK-NEXT: ret double [[RES]]237;238 %res = tail call fast double @llvm.pow.f64(double %base, double -4.000000e+01)239 ret double %res240}241 242; Negative tests243 244define double @pow_uitofp_const_base_fast_i32(i32 %x) {245; CHECK-LABEL: define double @pow_uitofp_const_base_fast_i32(246; CHECK-SAME: i32 [[X:%.*]]) {247; CHECK-NEXT: [[SUBFP:%.*]] = uitofp i32 [[X]] to float248; CHECK-NEXT: [[MUL:%.*]] = fmul fast float [[SUBFP]], 0x4006757680000000249; CHECK-NEXT: [[EXP2:%.*]] = tail call fast float @llvm.exp2.f32(float [[MUL]])250; CHECK-NEXT: [[RES:%.*]] = fpext float [[EXP2]] to double251; CHECK-NEXT: ret double [[RES]]252;253 %subfp = uitofp i32 %x to float254 %pow = tail call fast float @llvm.pow.f32(float 7.000000e+00, float %subfp)255 %res = fpext float %pow to double256 ret double %res257}258 259define double @pow_uitofp_const_base_2_fast_i32(i32 %x) {260; CHECK-LABEL: define double @pow_uitofp_const_base_2_fast_i32(261; CHECK-SAME: i32 [[X:%.*]]) {262; CHECK-NEXT: [[SUBFP:%.*]] = uitofp i32 [[X]] to float263; CHECK-NEXT: [[EXP2:%.*]] = tail call fast float @llvm.exp2.f32(float [[SUBFP]])264; CHECK-NEXT: [[RES:%.*]] = fpext float [[EXP2]] to double265; CHECK-NEXT: ret double [[RES]]266;267 %subfp = uitofp i32 %x to float268 %pow = tail call fast float @llvm.pow.f32(float 2.000000e+00, float %subfp)269 %res = fpext float %pow to double270 ret double %res271}272 273define double @pow_uitofp_const_base_power_of_2_fast_i32(i32 %x) {274; CHECK-LABEL: define double @pow_uitofp_const_base_power_of_2_fast_i32(275; CHECK-SAME: i32 [[X:%.*]]) {276; CHECK-NEXT: [[SUBFP:%.*]] = uitofp i32 [[X]] to float277; CHECK-NEXT: [[MUL:%.*]] = fmul fast float [[SUBFP]], 4.000000e+00278; CHECK-NEXT: [[EXP2:%.*]] = tail call fast float @llvm.exp2.f32(float [[MUL]])279; CHECK-NEXT: [[RES:%.*]] = fpext float [[EXP2]] to double280; CHECK-NEXT: ret double [[RES]]281;282 %subfp = uitofp i32 %x to float283 %pow = tail call fast float @llvm.pow.f32(float 16.000000e+00, float %subfp)284 %res = fpext float %pow to double285 ret double %res286}287 288define double @pow_uitofp_float_base_fast_i32(float %base, i32 %x) {289; CHECK-LABEL: define double @pow_uitofp_float_base_fast_i32(290; CHECK-SAME: float [[BASE:%.*]], i32 [[X:%.*]]) {291; CHECK-NEXT: [[SUBFP:%.*]] = uitofp i32 [[X]] to float292; CHECK-NEXT: [[POW:%.*]] = tail call fast float @llvm.pow.f32(float [[BASE]], float [[SUBFP]])293; CHECK-NEXT: [[RES:%.*]] = fpext float [[POW]] to double294; CHECK-NEXT: ret double [[RES]]295;296 %subfp = uitofp i32 %x to float297 %pow = tail call fast float @llvm.pow.f32(float %base, float %subfp)298 %res = fpext float %pow to double299 ret double %res300}301 302define double @pow_uitofp_double_base_fast_i32(double %base, i32 %x) {303; CHECK-LABEL: define double @pow_uitofp_double_base_fast_i32(304; CHECK-SAME: double [[BASE:%.*]], i32 [[X:%.*]]) {305; CHECK-NEXT: [[SUBFP:%.*]] = uitofp i32 [[X]] to double306; CHECK-NEXT: [[RES:%.*]] = tail call fast double @llvm.pow.f64(double [[BASE]], double [[SUBFP]])307; CHECK-NEXT: ret double [[RES]]308;309 %subfp = uitofp i32 %x to double310 %res = tail call fast double @llvm.pow.f64(double %base, double %subfp)311 ret double %res312}313 314define double @pow_sitofp_const_base_fast_i64(i64 %x) {315; CHECK-LABEL: define double @pow_sitofp_const_base_fast_i64(316; CHECK-SAME: i64 [[X:%.*]]) {317; CHECK-NEXT: [[SUBFP:%.*]] = sitofp i64 [[X]] to float318; CHECK-NEXT: [[MUL:%.*]] = fmul fast float [[SUBFP]], 0x4006757680000000319; CHECK-NEXT: [[EXP2:%.*]] = tail call fast float @llvm.exp2.f32(float [[MUL]])320; CHECK-NEXT: [[RES:%.*]] = fpext float [[EXP2]] to double321; CHECK-NEXT: ret double [[RES]]322;323; Do not change 0x400675{{.*}} to the exact constant, see PR42740324 %subfp = sitofp i64 %x to float325 %pow = tail call fast float @llvm.pow.f32(float 7.000000e+00, float %subfp)326 %res = fpext float %pow to double327 ret double %res328}329 330define double @pow_uitofp_const_base_fast_i64(i64 %x) {331; CHECK-LABEL: define double @pow_uitofp_const_base_fast_i64(332; CHECK-SAME: i64 [[X:%.*]]) {333; CHECK-NEXT: [[SUBFP:%.*]] = uitofp i64 [[X]] to float334; CHECK-NEXT: [[MUL:%.*]] = fmul fast float [[SUBFP]], 0x4006757680000000335; CHECK-NEXT: [[EXP2:%.*]] = tail call fast float @llvm.exp2.f32(float [[MUL]])336; CHECK-NEXT: [[RES:%.*]] = fpext float [[EXP2]] to double337; CHECK-NEXT: ret double [[RES]]338;339 %subfp = uitofp i64 %x to float340 %pow = tail call fast float @llvm.pow.f32(float 7.000000e+00, float %subfp)341 %res = fpext float %pow to double342 ret double %res343}344 345define double @pow_sitofp_const_base_no_fast(i32 %x) {346; CHECK-LABEL: define double @pow_sitofp_const_base_no_fast(347; CHECK-SAME: i32 [[X:%.*]]) {348; CHECK-NEXT: [[SUBFP:%.*]] = sitofp i32 [[X]] to float349; CHECK-NEXT: [[POW:%.*]] = tail call float @llvm.pow.f32(float 7.000000e+00, float [[SUBFP]])350; CHECK-NEXT: [[RES:%.*]] = fpext float [[POW]] to double351; CHECK-NEXT: ret double [[RES]]352;353 %subfp = sitofp i32 %x to float354 %pow = tail call float @llvm.pow.f32(float 7.000000e+00, float %subfp)355 %res = fpext float %pow to double356 ret double %res357}358 359define double @pow_uitofp_const_base_no_fast(i32 %x) {360; CHECK-LABEL: define double @pow_uitofp_const_base_no_fast(361; CHECK-SAME: i32 [[X:%.*]]) {362; CHECK-NEXT: [[SUBFP:%.*]] = uitofp i32 [[X]] to float363; CHECK-NEXT: [[POW:%.*]] = tail call float @llvm.pow.f32(float 7.000000e+00, float [[SUBFP]])364; CHECK-NEXT: [[RES:%.*]] = fpext float [[POW]] to double365; CHECK-NEXT: ret double [[RES]]366;367 %subfp = uitofp i32 %x to float368 %pow = tail call float @llvm.pow.f32(float 7.000000e+00, float %subfp)369 %res = fpext float %pow to double370 ret double %res371}372 373define double @pow_sitofp_const_base_2_no_fast(i32 %x) {374; CHECK-LABEL: define double @pow_sitofp_const_base_2_no_fast(375; CHECK-SAME: i32 [[X:%.*]]) {376; CHECK-NEXT: [[LDEXPF:%.*]] = tail call float @llvm.ldexp.f32.i32(float 1.000000e+00, i32 [[X]])377; CHECK-NEXT: [[RES:%.*]] = fpext float [[LDEXPF]] to double378; CHECK-NEXT: ret double [[RES]]379;380 %subfp = sitofp i32 %x to float381 %pow = tail call float @llvm.pow.f32(float 2.000000e+00, float %subfp)382 %res = fpext float %pow to double383 ret double %res384}385 386define double @pow_sitofp_const_base_power_of_2_no_fast(i32 %x) {387; CHECK-LABEL: define double @pow_sitofp_const_base_power_of_2_no_fast(388; CHECK-SAME: i32 [[X:%.*]]) {389; CHECK-NEXT: [[SUBFP:%.*]] = sitofp i32 [[X]] to float390; CHECK-NEXT: [[MUL:%.*]] = fmul float [[SUBFP]], 4.000000e+00391; CHECK-NEXT: [[EXP2:%.*]] = tail call float @llvm.exp2.f32(float [[MUL]])392; CHECK-NEXT: [[RES:%.*]] = fpext float [[EXP2]] to double393; CHECK-NEXT: ret double [[RES]]394;395 %subfp = sitofp i32 %x to float396 %pow = tail call float @llvm.pow.f32(float 16.000000e+00, float %subfp)397 %res = fpext float %pow to double398 ret double %res399}400 401define double @pow_uitofp_const_base_2_no_fast(i32 %x) {402; CHECK-LABEL: define double @pow_uitofp_const_base_2_no_fast(403; CHECK-SAME: i32 [[X:%.*]]) {404; CHECK-NEXT: [[SUBFP:%.*]] = uitofp i32 [[X]] to float405; CHECK-NEXT: [[EXP2:%.*]] = tail call float @llvm.exp2.f32(float [[SUBFP]])406; CHECK-NEXT: [[RES:%.*]] = fpext float [[EXP2]] to double407; CHECK-NEXT: ret double [[RES]]408;409 %subfp = uitofp i32 %x to float410 %pow = tail call float @llvm.pow.f32(float 2.000000e+00, float %subfp)411 %res = fpext float %pow to double412 ret double %res413}414 415define double @pow_uitofp_const_base_power_of_2_no_fast(i32 %x) {416; CHECK-LABEL: define double @pow_uitofp_const_base_power_of_2_no_fast(417; CHECK-SAME: i32 [[X:%.*]]) {418; CHECK-NEXT: [[SUBFP:%.*]] = uitofp i32 [[X]] to float419; CHECK-NEXT: [[MUL:%.*]] = fmul float [[SUBFP]], 4.000000e+00420; CHECK-NEXT: [[EXP2:%.*]] = tail call float @llvm.exp2.f32(float [[MUL]])421; CHECK-NEXT: [[RES:%.*]] = fpext float [[EXP2]] to double422; CHECK-NEXT: ret double [[RES]]423;424 %subfp = uitofp i32 %x to float425 %pow = tail call float @llvm.pow.f32(float 16.000000e+00, float %subfp)426 %res = fpext float %pow to double427 ret double %res428}429 430define double @pow_sitofp_float_base_no_fast(float %base, i32 %x) {431; CHECK-LABEL: define double @pow_sitofp_float_base_no_fast(432; CHECK-SAME: float [[BASE:%.*]], i32 [[X:%.*]]) {433; CHECK-NEXT: [[SUBFP:%.*]] = sitofp i32 [[X]] to float434; CHECK-NEXT: [[POW:%.*]] = tail call float @llvm.pow.f32(float [[BASE]], float [[SUBFP]])435; CHECK-NEXT: [[RES:%.*]] = fpext float [[POW]] to double436; CHECK-NEXT: ret double [[RES]]437;438 %subfp = sitofp i32 %x to float439 %pow = tail call float @llvm.pow.f32(float %base, float %subfp)440 %res = fpext float %pow to double441 ret double %res442}443 444define double @pow_uitofp_float_base_no_fast(float %base, i32 %x) {445; CHECK-LABEL: define double @pow_uitofp_float_base_no_fast(446; CHECK-SAME: float [[BASE:%.*]], i32 [[X:%.*]]) {447; CHECK-NEXT: [[SUBFP:%.*]] = uitofp i32 [[X]] to float448; CHECK-NEXT: [[POW:%.*]] = tail call float @llvm.pow.f32(float [[BASE]], float [[SUBFP]])449; CHECK-NEXT: [[RES:%.*]] = fpext float [[POW]] to double450; CHECK-NEXT: ret double [[RES]]451;452 %subfp = uitofp i32 %x to float453 %pow = tail call float @llvm.pow.f32(float %base, float %subfp)454 %res = fpext float %pow to double455 ret double %res456}457 458define double @pow_sitofp_double_base_no_fast(double %base, i32 %x) {459; CHECK-LABEL: define double @pow_sitofp_double_base_no_fast(460; CHECK-SAME: double [[BASE:%.*]], i32 [[X:%.*]]) {461; CHECK-NEXT: [[SUBFP:%.*]] = sitofp i32 [[X]] to double462; CHECK-NEXT: [[POW:%.*]] = tail call double @llvm.pow.f64(double [[BASE]], double [[SUBFP]])463; CHECK-NEXT: ret double [[POW]]464;465 %subfp = sitofp i32 %x to double466 %pow = tail call double @llvm.pow.f64(double %base, double %subfp)467 ret double %pow468}469 470define double @pow_uitofp_double_base_no_fast(double %base, i32 %x) {471; CHECK-LABEL: define double @pow_uitofp_double_base_no_fast(472; CHECK-SAME: double [[BASE:%.*]], i32 [[X:%.*]]) {473; CHECK-NEXT: [[SUBFP:%.*]] = uitofp i32 [[X]] to double474; CHECK-NEXT: [[POW:%.*]] = tail call double @llvm.pow.f64(double [[BASE]], double [[SUBFP]])475; CHECK-NEXT: ret double [[POW]]476;477 %subfp = uitofp i32 %x to double478 %pow = tail call double @llvm.pow.f64(double %base, double %subfp)479 ret double %pow480}481 482; negative test - pow with no FMF is not the same as the loosely-specified powi483 484define double @powf_exp_const_int_no_fast(double %base) {485; CHECK-LABEL: define double @powf_exp_const_int_no_fast(486; CHECK-SAME: double [[BASE:%.*]]) {487; CHECK-NEXT: [[RES:%.*]] = tail call double @llvm.pow.f64(double [[BASE]], double 4.000000e+01)488; CHECK-NEXT: ret double [[RES]]489;490 %res = tail call double @llvm.pow.f64(double %base, double 4.000000e+01)491 ret double %res492}493 494define double @powf_exp_const_not_int_fast(double %base) {495; CHECK-LABEL: define double @powf_exp_const_not_int_fast(496; CHECK-SAME: double [[BASE:%.*]]) {497; CHECK-NEXT: [[SQRT:%.*]] = call fast double @llvm.sqrt.f64(double [[BASE]])498; CHECK-NEXT: [[TMP1:%.*]] = tail call fast double @llvm.powi.f64.i32(double [[BASE]], i32 37)499; CHECK-NEXT: [[RES:%.*]] = fmul fast double [[TMP1]], [[SQRT]]500; CHECK-NEXT: ret double [[RES]]501;502 %res = tail call fast double @llvm.pow.f64(double %base, double 3.750000e+01)503 ret double %res504}505 506define double @powf_exp_const_not_int_no_fast(double %base) {507; CHECK-LABEL: define double @powf_exp_const_not_int_no_fast(508; CHECK-SAME: double [[BASE:%.*]]) {509; CHECK-NEXT: [[RES:%.*]] = tail call double @llvm.pow.f64(double [[BASE]], double 3.750000e+01)510; CHECK-NEXT: ret double [[RES]]511;512 %res = tail call double @llvm.pow.f64(double %base, double 3.750000e+01)513 ret double %res514}515 516; negative test - pow with no FMF is not the same as the loosely-specified powi517 518define double @powf_exp_const2_int_no_fast(double %base) {519; CHECK-LABEL: define double @powf_exp_const2_int_no_fast(520; CHECK-SAME: double [[BASE:%.*]]) {521; CHECK-NEXT: [[RES:%.*]] = tail call double @llvm.pow.f64(double [[BASE]], double -4.000000e+01)522; CHECK-NEXT: ret double [[RES]]523;524 %res = tail call double @llvm.pow.f64(double %base, double -4.000000e+01)525 ret double %res526}527 528; TODO: This could be transformed the same as scalar if there is an ldexp intrinsic.529 530define <2 x float> @pow_sitofp_const_base_2_no_fast_vector(<2 x i8> %x) {531; CHECK-LABEL: define <2 x float> @pow_sitofp_const_base_2_no_fast_vector(532; CHECK-SAME: <2 x i8> [[X:%.*]]) {533; CHECK-NEXT: [[TMP1:%.*]] = sext <2 x i8> [[X]] to <2 x i32>534; CHECK-NEXT: [[EXP2:%.*]] = call <2 x float> @llvm.ldexp.v2f32.v2i32(<2 x float> splat (float 1.000000e+00), <2 x i32> [[TMP1]])535; CHECK-NEXT: ret <2 x float> [[EXP2]]536;537 %s = sitofp <2 x i8> %x to <2 x float>538 %r = call <2 x float> @llvm.pow.v2f32(<2 x float><float 2.0, float 2.0>, <2 x float> %s)539 ret <2 x float> %r540}541 542declare float @llvm.pow.f32(float, float)543declare double @llvm.pow.f64(double, double)544declare <2 x float> @llvm.pow.v2f32(<2 x float>, <2 x float>)545