1; NOTE: Assertions have been autogenerated by utils/update_test_checks.py UTC_ARGS: --version 3 2; RUN: opt -mtriple unknown -passes=instcombine -S < %s | FileCheck %s 3target datalayout = "e" 4 5; PR42190 6; 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 double 13; CHECK-NEXT: ret double [[RES]] 14; 15 %subfp = sitofp i32 %x to float 16 %pow = tail call afn float @llvm.pow.f32(float 7.000000e+00, float %subfp) 17 %res = fpext float %pow to double 18 ret double %res 19} 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 i32 25; 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 double 27; CHECK-NEXT: ret double [[RES]] 28; 29 %subfp = uitofp i31 %x to float 30 %pow = tail call afn float @llvm.pow.f32(float 7.000000e+00, float %subfp) 31 %res = fpext float %pow to double 32 ret double %res 33} 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 double 42 %pow = tail call afn double @llvm.pow.f64(double 7.000000e+00, double %subfp) 43 ret double %pow 44} 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 i32 50; 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 double 54 %pow = tail call afn double @llvm.pow.f64(double 7.000000e+00, double %subfp) 55 ret double %pow 56} 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 double 63; CHECK-NEXT: ret double [[RES]] 64; 65 %subfp = sitofp i32 %x to float 66 %pow = tail call afn float @llvm.pow.f32(float 2.000000e+00, float %subfp) 67 %res = fpext float %pow to double 68 ret double %res 69} 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 float 75; CHECK-NEXT: [[MUL:%.*]] = fmul afn float [[SUBFP]], 4.000000e+00 76; CHECK-NEXT: [[EXP2:%.*]] = tail call afn float @llvm.exp2.f32(float [[MUL]]) 77; CHECK-NEXT: [[RES:%.*]] = fpext float [[EXP2]] to double 78; CHECK-NEXT: ret double [[RES]] 79; 80 %subfp = sitofp i32 %x to float 81 %pow = tail call afn float @llvm.pow.f32(float 16.000000e+00, float %subfp) 82 %res = fpext float %pow to double 83 ret double %res 84} 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 i32 90; 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 double 92; CHECK-NEXT: ret double [[RES]] 93; 94 %subfp = uitofp i31 %x to float 95 %pow = tail call afn float @llvm.pow.f32(float 2.000000e+00, float %subfp) 96 %res = fpext float %pow to double 97 ret double %res 98} 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 float 104; CHECK-NEXT: [[MUL:%.*]] = fmul afn float [[SUBFP]], 4.000000e+00 105; CHECK-NEXT: [[EXP2:%.*]] = tail call afn float @llvm.exp2.f32(float [[MUL]]) 106; CHECK-NEXT: [[RES:%.*]] = fpext float [[EXP2]] to double 107; CHECK-NEXT: ret double [[RES]] 108; 109 %subfp = uitofp i31 %x to float 110 %pow = tail call afn float @llvm.pow.f32(float 16.000000e+00, float %subfp) 111 %res = fpext float %pow to double 112 ret double %res 113} 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 double 120; CHECK-NEXT: ret double [[RES]] 121; 122 %subfp = sitofp i32 %x to float 123 %pow = tail call afn float @llvm.pow.f32(float %base, float %subfp) 124 %res = fpext float %pow to double 125 ret double %res 126} 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 i32 132; CHECK-NEXT: [[POW:%.*]] = tail call afn float @llvm.powi.f32.i32(float [[BASE]], i32 [[TMP1]]) 133; CHECK-NEXT: [[RES:%.*]] = fpext float [[POW]] to double 134; CHECK-NEXT: ret double [[RES]] 135; 136 %subfp = uitofp i31 %x to float 137 %pow = tail call afn float @llvm.pow.f32(float %base, float %subfp) 138 %res = fpext float %pow to double 139 ret double %res 140} 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 double 149 %res = tail call afn double @llvm.pow.f64(double %base, double %subfp) 150 ret double %res 151} 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 i32 157; 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 double 161 %res = tail call afn double @llvm.pow.f64(double %base, double %subfp) 162 ret double %res 163} 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 i32 169; 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 double 171; CHECK-NEXT: ret double [[RES]] 172; 173 %subfp = sitofp i8 %x to float 174 %pow = tail call afn float @llvm.pow.f32(float 7.000000e+00, float %subfp) 175 %res = fpext float %pow to double 176 ret double %res 177} 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 i32 183; 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 double 185; CHECK-NEXT: ret double [[RES]] 186; 187 %subfp = sitofp i16 %x to float 188 %pow = tail call afn float @llvm.pow.f32(float 7.000000e+00, float %subfp) 189 %res = fpext float %pow to double 190 ret double %res 191} 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 i32 198; 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 double 200; CHECK-NEXT: ret double [[RES]] 201; 202 %subfp = uitofp i8 %x to float 203 %pow = tail call afn float @llvm.pow.f32(float 7.000000e+00, float %subfp) 204 %res = fpext float %pow to double 205 ret double %res 206} 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 i32 212; 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 double 214; CHECK-NEXT: ret double [[RES]] 215; 216 %subfp = uitofp i16 %x to float 217 %pow = tail call afn float @llvm.pow.f32(float 7.000000e+00, float %subfp) 218 %res = fpext float %pow to double 219 ret double %res 220} 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 %res 230} 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 %res 240} 241 242; Negative tests 243 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 float 248; CHECK-NEXT: [[MUL:%.*]] = fmul fast float [[SUBFP]], 0x4006757680000000 249; CHECK-NEXT: [[EXP2:%.*]] = tail call fast float @llvm.exp2.f32(float [[MUL]]) 250; CHECK-NEXT: [[RES:%.*]] = fpext float [[EXP2]] to double 251; CHECK-NEXT: ret double [[RES]] 252; 253 %subfp = uitofp i32 %x to float 254 %pow = tail call fast float @llvm.pow.f32(float 7.000000e+00, float %subfp) 255 %res = fpext float %pow to double 256 ret double %res 257} 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 float 263; CHECK-NEXT: [[EXP2:%.*]] = tail call fast float @llvm.exp2.f32(float [[SUBFP]]) 264; CHECK-NEXT: [[RES:%.*]] = fpext float [[EXP2]] to double 265; CHECK-NEXT: ret double [[RES]] 266; 267 %subfp = uitofp i32 %x to float 268 %pow = tail call fast float @llvm.pow.f32(float 2.000000e+00, float %subfp) 269 %res = fpext float %pow to double 270 ret double %res 271} 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 float 277; CHECK-NEXT: [[MUL:%.*]] = fmul fast float [[SUBFP]], 4.000000e+00 278; CHECK-NEXT: [[EXP2:%.*]] = tail call fast float @llvm.exp2.f32(float [[MUL]]) 279; CHECK-NEXT: [[RES:%.*]] = fpext float [[EXP2]] to double 280; CHECK-NEXT: ret double [[RES]] 281; 282 %subfp = uitofp i32 %x to float 283 %pow = tail call fast float @llvm.pow.f32(float 16.000000e+00, float %subfp) 284 %res = fpext float %pow to double 285 ret double %res 286} 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 float 292; CHECK-NEXT: [[POW:%.*]] = tail call fast float @llvm.pow.f32(float [[BASE]], float [[SUBFP]]) 293; CHECK-NEXT: [[RES:%.*]] = fpext float [[POW]] to double 294; CHECK-NEXT: ret double [[RES]] 295; 296 %subfp = uitofp i32 %x to float 297 %pow = tail call fast float @llvm.pow.f32(float %base, float %subfp) 298 %res = fpext float %pow to double 299 ret double %res 300} 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 double 306; 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 double 310 %res = tail call fast double @llvm.pow.f64(double %base, double %subfp) 311 ret double %res 312} 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 float 318; CHECK-NEXT: [[MUL:%.*]] = fmul fast float [[SUBFP]], 0x4006757680000000 319; CHECK-NEXT: [[EXP2:%.*]] = tail call fast float @llvm.exp2.f32(float [[MUL]]) 320; CHECK-NEXT: [[RES:%.*]] = fpext float [[EXP2]] to double 321; CHECK-NEXT: ret double [[RES]] 322; 323; Do not change 0x400675{{.*}} to the exact constant, see PR42740 324 %subfp = sitofp i64 %x to float 325 %pow = tail call fast float @llvm.pow.f32(float 7.000000e+00, float %subfp) 326 %res = fpext float %pow to double 327 ret double %res 328} 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 float 334; CHECK-NEXT: [[MUL:%.*]] = fmul fast float [[SUBFP]], 0x4006757680000000 335; CHECK-NEXT: [[EXP2:%.*]] = tail call fast float @llvm.exp2.f32(float [[MUL]]) 336; CHECK-NEXT: [[RES:%.*]] = fpext float [[EXP2]] to double 337; CHECK-NEXT: ret double [[RES]] 338; 339 %subfp = uitofp i64 %x to float 340 %pow = tail call fast float @llvm.pow.f32(float 7.000000e+00, float %subfp) 341 %res = fpext float %pow to double 342 ret double %res 343} 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 float 349; CHECK-NEXT: [[POW:%.*]] = tail call float @llvm.pow.f32(float 7.000000e+00, float [[SUBFP]]) 350; CHECK-NEXT: [[RES:%.*]] = fpext float [[POW]] to double 351; CHECK-NEXT: ret double [[RES]] 352; 353 %subfp = sitofp i32 %x to float 354 %pow = tail call float @llvm.pow.f32(float 7.000000e+00, float %subfp) 355 %res = fpext float %pow to double 356 ret double %res 357} 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 float 363; CHECK-NEXT: [[POW:%.*]] = tail call float @llvm.pow.f32(float 7.000000e+00, float [[SUBFP]]) 364; CHECK-NEXT: [[RES:%.*]] = fpext float [[POW]] to double 365; CHECK-NEXT: ret double [[RES]] 366; 367 %subfp = uitofp i32 %x to float 368 %pow = tail call float @llvm.pow.f32(float 7.000000e+00, float %subfp) 369 %res = fpext float %pow to double 370 ret double %res 371} 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 double 378; CHECK-NEXT: ret double [[RES]] 379; 380 %subfp = sitofp i32 %x to float 381 %pow = tail call float @llvm.pow.f32(float 2.000000e+00, float %subfp) 382 %res = fpext float %pow to double 383 ret double %res 384} 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 float 390; CHECK-NEXT: [[MUL:%.*]] = fmul float [[SUBFP]], 4.000000e+00 391; CHECK-NEXT: [[EXP2:%.*]] = tail call float @llvm.exp2.f32(float [[MUL]]) 392; CHECK-NEXT: [[RES:%.*]] = fpext float [[EXP2]] to double 393; CHECK-NEXT: ret double [[RES]] 394; 395 %subfp = sitofp i32 %x to float 396 %pow = tail call float @llvm.pow.f32(float 16.000000e+00, float %subfp) 397 %res = fpext float %pow to double 398 ret double %res 399} 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 float 405; CHECK-NEXT: [[EXP2:%.*]] = tail call float @llvm.exp2.f32(float [[SUBFP]]) 406; CHECK-NEXT: [[RES:%.*]] = fpext float [[EXP2]] to double 407; CHECK-NEXT: ret double [[RES]] 408; 409 %subfp = uitofp i32 %x to float 410 %pow = tail call float @llvm.pow.f32(float 2.000000e+00, float %subfp) 411 %res = fpext float %pow to double 412 ret double %res 413} 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 float 419; CHECK-NEXT: [[MUL:%.*]] = fmul float [[SUBFP]], 4.000000e+00 420; CHECK-NEXT: [[EXP2:%.*]] = tail call float @llvm.exp2.f32(float [[MUL]]) 421; CHECK-NEXT: [[RES:%.*]] = fpext float [[EXP2]] to double 422; CHECK-NEXT: ret double [[RES]] 423; 424 %subfp = uitofp i32 %x to float 425 %pow = tail call float @llvm.pow.f32(float 16.000000e+00, float %subfp) 426 %res = fpext float %pow to double 427 ret double %res 428} 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 float 434; CHECK-NEXT: [[POW:%.*]] = tail call float @llvm.pow.f32(float [[BASE]], float [[SUBFP]]) 435; CHECK-NEXT: [[RES:%.*]] = fpext float [[POW]] to double 436; CHECK-NEXT: ret double [[RES]] 437; 438 %subfp = sitofp i32 %x to float 439 %pow = tail call float @llvm.pow.f32(float %base, float %subfp) 440 %res = fpext float %pow to double 441 ret double %res 442} 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 float 448; CHECK-NEXT: [[POW:%.*]] = tail call float @llvm.pow.f32(float [[BASE]], float [[SUBFP]]) 449; CHECK-NEXT: [[RES:%.*]] = fpext float [[POW]] to double 450; CHECK-NEXT: ret double [[RES]] 451; 452 %subfp = uitofp i32 %x to float 453 %pow = tail call float @llvm.pow.f32(float %base, float %subfp) 454 %res = fpext float %pow to double 455 ret double %res 456} 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 double 462; 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 double 466 %pow = tail call double @llvm.pow.f64(double %base, double %subfp) 467 ret double %pow 468} 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 double 474; 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 double 478 %pow = tail call double @llvm.pow.f64(double %base, double %subfp) 479 ret double %pow 480} 481 482; negative test - pow with no FMF is not the same as the loosely-specified powi 483 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 %res 492} 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 %res 504} 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 %res 514} 515 516; negative test - pow with no FMF is not the same as the loosely-specified powi 517 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 %res 526} 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> %r 540} 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