1; Test that the pow library call simplifier works correctly. 2; 3; RUN: opt -instcombine -S < %s | FileCheck %s --check-prefixes=CHECK,LIB,ANY 4; RUN: opt -instcombine -S < %s -mtriple=x86_64-apple-macosx10.9 | FileCheck %s --check-prefixes=CHECK,LIB,ANY,CHECK-EXP10 5; RUN: opt -instcombine -S < %s -mtriple=arm-apple-ios7.0 | FileCheck %s --check-prefixes=CHECK,LIB,ANY,CHECK-EXP10 6; RUN: opt -instcombine -S < %s -mtriple=x86_64-apple-macosx10.8 | FileCheck %s --check-prefixes=CHECK,LIB,ANY,CHECK-NO-EXP10 7; RUN: opt -instcombine -S < %s -mtriple=arm-apple-ios6.0 | FileCheck %s --check-prefixes=CHECK,LIB,ANY,CHECK-NO-EXP10 8; RUN: opt -instcombine -S < %s -mtriple=x86_64-netbsd | FileCheck %s --check-prefixes=CHECK,LIB,ANY,CHECK-NO-EXP10 9; RUN: opt -instcombine -S < %s -mtriple=arm-apple-tvos9.0 | FileCheck %s --check-prefixes=CHECK,LIB,ANY,CHECK-EXP10 10; RUN: opt -instcombine -S < %s -mtriple=arm-apple-watchos2.0 | FileCheck %s --check-prefixes=CHECK,LIB,ANY,CHECK-EXP10 11; rdar://7251832 12; RUN: opt -instcombine -S < %s -mtriple=i386-pc-windows-msvc18 | FileCheck %s --check-prefixes=CHECK,LIB,MSVC,VC32,CHECK-NO-EXP10 13; RUN: opt -instcombine -S < %s -mtriple=i386-pc-windows-msvc | FileCheck %s --check-prefixes=CHECK,LIB,MSVC,VC51,VC19,CHECK-NO-EXP10 14; RUN: opt -instcombine -S < %s -mtriple=x86_64-pc-windows-msvc18 | FileCheck %s --check-prefixes=CHECK,LIB,MSVC,VC64,CHECK-NO-EXP10 15; RUN: opt -instcombine -S < %s -mtriple=x86_64-pc-windows-msvc | FileCheck %s --check-prefixes=CHECK,LIB,MSVC,VC83,VC19,CHECK-NO-EXP10 16; RUN: opt -instcombine -S < %s -mtriple=amdgcn-- | FileCheck %s --check-prefixes=CHECK,NOLIB,CHECK-NO-EXP10 17 18; NOTE: The readonly attribute on the pow call should be preserved 19; in the cases below where pow is transformed into another function call. 20 21declare float @powf(float, float) nounwind readonly 22declare float @llvm.pow.f32(float, float) 23declare double @pow(double, double) nounwind readonly 24declare double @llvm.pow.f64(double, double) 25declare <2 x float> @llvm.pow.v2f32(<2 x float>, <2 x float>) nounwind readonly 26declare <2 x double> @llvm.pow.v2f64(<2 x double>, <2 x double>) nounwind readonly 27 28; Check pow(1.0, x) -> 1.0. 29 30define float @test_simplify1(float %x) { 31; CHECK-LABEL: @test_simplify1( 32; ANY-NEXT: ret float 1.000000e+00 33; VC32-NEXT: [[POW:%.*]] = call float @powf(float 1.000000e+00, float [[X:%.*]]) 34; VC32-NEXT: ret float [[POW]] 35; VC64-NEXT: ret float 1.000000e+00 36; NOLIB-NEXT: [[POW:%.*]] = call float @powf(float 1.000000e+00, float [[X:%.*]]) 37; NOLIB-NEXT: ret float [[POW]] 38; 39 %retval = call float @powf(float 1.0, float %x) 40 ret float %retval 41} 42 43define <2 x float> @test_simplify1v(<2 x float> %x) { 44; CHECK-LABEL: @test_simplify1v( 45; CHECK-NEXT: ret <2 x float> <float 1.000000e+00, float 1.000000e+00> 46; 47 %retval = call <2 x float> @llvm.pow.v2f32(<2 x float> <float 1.0, float 1.0>, <2 x float> %x) 48 ret <2 x float> %retval 49} 50 51define double @test_simplify2(double %x) { 52; CHECK-LABEL: @test_simplify2( 53; LIB-NEXT: ret double 1.000000e+00 54; NOLIB-NEXT: [[POW:%.*]] = call double @pow(double 1.000000e+00, double [[X:%.*]]) 55; NOLIB-NEXT: ret double [[POW]] 56; 57 %retval = call double @pow(double 1.0, double %x) 58 ret double %retval 59} 60 61define <2 x double> @test_simplify2v(<2 x double> %x) { 62; CHECK-LABEL: @test_simplify2v( 63; CHECK-NEXT: ret <2 x double> <double 1.000000e+00, double 1.000000e+00> 64; 65 %retval = call <2 x double> @llvm.pow.v2f64(<2 x double> <double 1.0, double 1.0>, <2 x double> %x) 66 ret <2 x double> %retval 67} 68 69; Check pow(2.0 ** n, x) -> exp2(n * x). 70 71define float @test_simplify3(float %x) { 72; CHECK-LABEL: @test_simplify3( 73; ANY-NEXT: [[EXP2F:%.*]] = call float @exp2f(float [[X:%.*]]) 74; ANY-NEXT: ret float [[EXP2F]] 75; VC32-NEXT: [[POW:%.*]] = call float @powf(float 2.000000e+00, float [[X:%.*]]) 76; VC32-NEXT: ret float [[POW]] 77; VC51-NEXT: [[POW:%.*]] = call float @powf(float 2.000000e+00, float [[X:%.*]]) 78; VC51-NEXT: ret float [[POW]] 79; VC64-NEXT: [[POW:%.*]] = call float @powf(float 2.000000e+00, float [[X:%.*]]) 80; VC64-NEXT: ret float [[POW]] 81; VC83-NEXT: [[EXP2F:%.*]] = call float @exp2f(float [[X:%.*]]) 82; VC83-NEXT: ret float [[EXP2F]] 83; NOLIB-NEXT: [[POW:%.*]] = call float @powf(float 2.000000e+00, float [[X:%.*]]) 84; NOLIB-NEXT: ret float [[POW]] 85; 86 %retval = call float @powf(float 2.0, float %x) 87 ret float %retval 88} 89 90define double @test_simplify3n(double %x) { 91; CHECK-LABEL: @test_simplify3n( 92; ANY-NEXT: [[MUL:%.*]] = fmul double [[X:%.*]], -2.000000e+00 93; ANY-NEXT: [[EXP2:%.*]] = call double @exp2(double [[MUL]]) 94; ANY-NEXT: ret double [[EXP2]] 95; VC19-NEXT: [[MUL:%.*]] = fmul double [[X:%.*]], -2.000000e+00 96; VC19-NEXT: [[EXP2:%.*]] = call double @exp2(double [[MUL]]) 97; VC19-NEXT: ret double [[EXP2]] 98; VC32-NEXT: [[POW:%.*]] = call double @pow(double 2.500000e-01, double [[X:%.*]]) 99; VC32-NEXT: ret double [[POW]] 100; VC64-NEXT: [[POW:%.*]] = call double @pow(double 2.500000e-01, double [[X:%.*]]) 101; VC64-NEXT: ret double [[POW]] 102; NOLIB-NEXT: [[POW:%.*]] = call double @pow(double 2.500000e-01, double [[X:%.*]]) 103; NOLIB-NEXT: ret double [[POW]] 104; 105 %retval = call double @pow(double 0.25, double %x) 106 ret double %retval 107} 108 109define <2 x float> @test_simplify3v(<2 x float> %x) { 110; CHECK-LABEL: @test_simplify3v( 111; ANY-NEXT: [[EXP2:%.*]] = call <2 x float> @llvm.exp2.v2f32(<2 x float> [[X:%.*]]) 112; ANY-NEXT: ret <2 x float> [[EXP2]] 113; MSVC-NEXT: [[POW:%.*]] = call <2 x float> @llvm.pow.v2f32(<2 x float> <float 2.000000e+00, float 2.000000e+00>, <2 x float> [[X:%.*]]) 114; MSVC-NEXT: ret <2 x float> [[POW]] 115; TODO: should be able to simplify llvm.pow to llvm.exp2 even without libcalls 116; NOLIB-NEXT: [[POW:%.*]] = call <2 x float> @llvm.pow.v2f32(<2 x float> <float 2.000000e+00, float 2.000000e+00>, <2 x float> [[X:%.*]]) 117; NOLIB-NEXT: ret <2 x float> [[POW]] 118; 119 %retval = call <2 x float> @llvm.pow.v2f32(<2 x float> <float 2.0, float 2.0>, <2 x float> %x) 120 ret <2 x float> %retval 121} 122 123define <2 x double> @test_simplify3vn(<2 x double> %x) { 124; CHECK-LABEL: @test_simplify3vn( 125; ANY-NEXT: [[MUL:%.*]] = fmul <2 x double> [[X:%.*]], <double 2.000000e+00, double 2.000000e+00> 126; ANY-NEXT: [[EXP2:%.*]] = call <2 x double> @llvm.exp2.v2f64(<2 x double> [[MUL]]) 127; ANY-NEXT: ret <2 x double> [[EXP2]] 128; MSVC-NEXT: [[POW:%.*]] = call <2 x double> @llvm.pow.v2f64(<2 x double> <double 4.000000e+00, double 4.000000e+00>, <2 x double> [[X:%.*]]) 129; MSVC-NEXT: ret <2 x double> [[POW]] 130; TODO: should be able to simplify llvm.pow to llvm.exp2 even without libcalls 131; NOLIB-NEXT: [[POW:%.*]] = call <2 x double> @llvm.pow.v2f64(<2 x double> <double 4.000000e+00, double 4.000000e+00>, <2 x double> [[X:%.*]]) 132; NOLIB-NEXT: ret <2 x double> [[POW]] 133; 134 %retval = call <2 x double> @llvm.pow.v2f64(<2 x double> <double 4.0, double 4.0>, <2 x double> %x) 135 ret <2 x double> %retval 136} 137 138define double @test_simplify4(double %x) { 139; CHECK-LABEL: @test_simplify4( 140; ANY-NEXT: [[EXP2:%.*]] = call double @exp2(double [[X:%.*]]) 141; ANY-NEXT: ret double [[EXP2]] 142; VC19-NEXT: [[EXP2:%.*]] = call double @exp2(double [[X:%.*]]) 143; VC19-NEXT: ret double [[EXP2]] 144; VC32-NEXT: [[POW:%.*]] = call double @pow(double 2.000000e+00, double [[X:%.*]]) 145; VC32-NEXT: ret double [[POW]] 146; VC64-NEXT: [[POW:%.*]] = call double @pow(double 2.000000e+00, double [[X:%.*]]) 147; VC64-NEXT: ret double [[POW]] 148; NOLIB-NEXT: [[POW:%.*]] = call double @pow(double 2.000000e+00, double [[X:%.*]]) 149; NOLIB-NEXT: ret double [[POW]] 150; 151 %retval = call double @pow(double 2.0, double %x) 152 ret double %retval 153} 154 155define float @test_simplify4n(float %x) { 156; CHECK-LABEL: @test_simplify4n( 157; ANY-NEXT: [[MUL:%.*]] = fmul float [[X:%.*]], 3.000000e+00 158; ANY-NEXT: [[EXP2F:%.*]] = call float @exp2f(float [[MUL]]) 159; ANY-NEXT: ret float [[EXP2F]] 160; VC32-NEXT: [[POW:%.*]] = call float @powf(float 8.000000e+00, float [[X:%.*]]) 161; VC32-NEXT: ret float [[POW]] 162; VC51-NEXT: [[POW:%.*]] = call float @powf(float 8.000000e+00, float [[X:%.*]]) 163; VC51-NEXT: ret float [[POW]] 164; VC64-NEXT: [[POW:%.*]] = call float @powf(float 8.000000e+00, float [[X:%.*]]) 165; VC64-NEXT: ret float [[POW]] 166; VC83-NEXT: [[MUL:%.*]] = fmul float [[X:%.*]], 3.000000e+00 167; VC83-NEXT: [[EXP2F:%.*]] = call float @exp2f(float [[MUL]]) 168; VC83-NEXT: ret float [[EXP2F]] 169; NOLIB-NEXT: [[POW:%.*]] = call float @powf(float 8.000000e+00, float [[X:%.*]]) 170; NOLIB-NEXT: ret float [[POW]] 171; 172 %retval = call float @powf(float 8.0, float %x) 173 ret float %retval 174} 175 176define <2 x double> @test_simplify4v(<2 x double> %x) { 177; CHECK-LABEL: @test_simplify4v( 178; ANY-NEXT: [[EXP2:%.*]] = call <2 x double> @llvm.exp2.v2f64(<2 x double> [[X:%.*]]) 179; ANY-NEXT: ret <2 x double> [[EXP2]] 180; MSVC-NEXT: [[POW:%.*]] = call <2 x double> @llvm.pow.v2f64(<2 x double> <double 2.000000e+00, double 2.000000e+00>, <2 x double> [[X:%.*]]) 181; MSVC-NEXT: ret <2 x double> [[POW]] 182; TODO: should be able to simplify llvm.pow to llvm.exp2 even without libcalls 183; NOLIB-NEXT: [[POW:%.*]] = call <2 x double> @llvm.pow.v2f64(<2 x double> <double 2.000000e+00, double 2.000000e+00>, <2 x double> [[X:%.*]]) 184; NOLIB-NEXT: ret <2 x double> [[POW]] 185; 186 %retval = call <2 x double> @llvm.pow.v2f64(<2 x double> <double 2.0, double 2.0>, <2 x double> %x) 187 ret <2 x double> %retval 188} 189 190define <2 x float> @test_simplify4vn(<2 x float> %x) { 191; CHECK-LABEL: @test_simplify4vn( 192; ANY-NEXT: [[MUL:%.*]] = fneg <2 x float> [[X:%.*]] 193; ANY-NEXT: [[EXP2:%.*]] = call <2 x float> @llvm.exp2.v2f32(<2 x float> [[MUL]]) 194; ANY-NEXT: ret <2 x float> [[EXP2]] 195; MSVC-NEXT: [[POW:%.*]] = call <2 x float> @llvm.pow.v2f32(<2 x float> <float 5.000000e-01, float 5.000000e-01>, <2 x float> [[X:%.*]]) 196; MSVC-NEXT: ret <2 x float> [[POW]] 197; TODO: should be able to simplify llvm.pow to llvm.exp2 even without libcalls 198; NOLIB-NEXT: [[POW:%.*]] = call <2 x float> @llvm.pow.v2f32(<2 x float> <float 5.000000e-01, float 5.000000e-01>, <2 x float> [[X:%.*]]) 199; NOLIB-NEXT: ret <2 x float> [[POW]] 200; 201 %retval = call <2 x float> @llvm.pow.v2f32(<2 x float> <float 0.5, float 0.5>, <2 x float> %x) 202 ret <2 x float> %retval 203} 204 205; Check pow(x, 0.0) -> 1.0. 206 207define float @test_simplify5(float %x) { 208; CHECK-LABEL: @test_simplify5( 209; ANY-NEXT: ret float 1.000000e+00 210; VC32-NEXT: [[POW:%.*]] = call float @powf(float [[X:%.*]], float 0.000000e+00) 211; VC32-NEXT: ret float [[POW]] 212; VC51-NEXT: [[POW:%.*]] = call float @powf(float [[X:%.*]], float 0.000000e+00) 213; VC51-NEXT: ret float [[POW]] 214; VC64-NEXT: ret float 1.000000e+00 215; VC83-NEXT: ret float 1.000000e+00 216; NOLIB-NEXT: [[POW:%.*]] = call float @powf(float [[X:%.*]], float 0.000000e+00) 217; NOLIB-NEXT: ret float [[POW]] 218; 219 %retval = call float @powf(float %x, float 0.0) 220 ret float %retval 221} 222 223define <2 x float> @test_simplify5v(<2 x float> %x) { 224; CHECK-LABEL: @test_simplify5v( 225; CHECK-NEXT: ret <2 x float> <float 1.000000e+00, float 1.000000e+00> 226; 227 %retval = call <2 x float> @llvm.pow.v2f32(<2 x float> %x, <2 x float> <float 0.0, float 0.0>) 228 ret <2 x float> %retval 229} 230 231define double @test_simplify6(double %x) { 232; CHECK-LABEL: @test_simplify6( 233; LIB-NEXT: ret double 1.000000e+00 234; NOLIB-NEXT: [[POW:%.*]] = call double @pow(double [[X:%.*]], double 0.000000e+00) 235; NOLIB-NEXT: ret double [[POW]] 236; 237 %retval = call double @pow(double %x, double 0.0) 238 ret double %retval 239} 240 241define <2 x double> @test_simplify6v(<2 x double> %x) { 242; CHECK-LABEL: @test_simplify6v( 243; CHECK-NEXT: ret <2 x double> <double 1.000000e+00, double 1.000000e+00> 244; 245 %retval = call <2 x double> @llvm.pow.v2f64(<2 x double> %x, <2 x double> <double 0.0, double 0.0>) 246 ret <2 x double> %retval 247} 248 249; Check pow(x, 0.5) -> fabs(sqrt(x)), where x != -infinity. 250 251define float @powf_libcall_half_ninf(float %x) { 252; CHECK-LABEL: @powf_libcall_half_ninf( 253; ANY-NEXT: [[SQRTF:%.*]] = call ninf float @sqrtf(float [[X:%.*]]) 254; ANY-NEXT: [[ABS:%.*]] = call ninf float @llvm.fabs.f32(float [[SQRTF]]) 255; ANY-NEXT: ret float [[ABS]] 256; VC32-NEXT: [[POW:%.*]] = call ninf float @powf(float [[X:%.*]], float 5.000000e-01) 257; VC32-NEXT: ret float [[POW]] 258; VC51-NEXT: [[POW:%.*]] = call ninf float @powf(float [[X:%.*]], float 5.000000e-01) 259; VC51-NEXT: ret float [[POW]] 260; VC64-NEXT: [[SQRTF:%.*]] = call ninf float @sqrtf(float [[X:%.*]]) 261; VC64-NEXT: [[ABS:%.*]] = call ninf float @llvm.fabs.f32(float [[SQRTF]]) 262; VC64-NEXT: ret float [[ABS]] 263; VC83-NEXT: [[SQRTF:%.*]] = call ninf float @sqrtf(float [[X:%.*]]) 264; VC83-NEXT: [[ABS:%.*]] = call ninf float @llvm.fabs.f32(float [[SQRTF]]) 265; VC83-NEXT: ret float [[ABS]] 266; NOLIB-NEXT: [[POW:%.*]] = call ninf float @powf(float [[X:%.*]], float 5.000000e-01) 267; NOLIB-NEXT: ret float [[POW]] 268; 269 %retval = call ninf float @powf(float %x, float 0.5) 270 ret float %retval 271} 272 273; Check pow(x, 0.5) where x may be -infinity does not call a library sqrt function. 274 275define double @pow_libcall_half_no_FMF(double %x) { 276; CHECK-LABEL: @pow_libcall_half_no_FMF( 277; CHECK-NEXT: [[POW:%.*]] = call double @pow(double [[X:%.*]], double 5.000000e-01) 278; CHECK-NEXT: ret double [[POW]] 279; 280 %retval = call double @pow(double %x, double 0.5) 281 ret double %retval 282} 283 284; Check pow(-infinity, 0.5) -> +infinity. 285 286define float @test_simplify9(float %x) { 287; CHECK-LABEL: @test_simplify9( 288; CHECK-NEXT: ret float 0x7FF0000000000000 289; 290 %retval = call float @llvm.pow.f32(float 0xFFF0000000000000, float 0.5) 291 ret float %retval 292} 293 294define double @test_simplify10(double %x) { 295; CHECK-LABEL: @test_simplify10( 296; CHECK-NEXT: ret double 0x7FF0000000000000 297; 298 %retval = call double @llvm.pow.f64(double 0xFFF0000000000000, double 0.5) 299 ret double %retval 300} 301 302; Check pow(x, 1.0) -> x. 303 304define float @test_simplify11(float %x) { 305; CHECK-LABEL: @test_simplify11( 306; ANY-NEXT: ret float [[X:%.*]] 307; VC32-NEXT: [[POW:%.*]] = call float @powf(float [[X:%.*]], float 1.000000e+00) 308; VC32-NEXT: ret float [[POW]] 309; VC51-NEXT: [[POW:%.*]] = call float @powf(float [[X:%.*]], float 1.000000e+00) 310; VC51-NEXT: ret float [[POW]] 311; VC64-NEXT: ret float [[X:%.*]] 312; VC83-NEXT: ret float [[X:%.*]] 313; NOLIB-NEXT: [[POW:%.*]] = call float @powf(float [[X:%.*]], float 1.000000e+00) 314; NOLIB-NEXT: ret float [[POW]] 315; 316 %retval = call float @powf(float %x, float 1.0) 317 ret float %retval 318} 319 320define <2 x float> @test_simplify11v(<2 x float> %x) { 321; CHECK-LABEL: @test_simplify11v( 322; CHECK-NEXT: ret <2 x float> [[X:%.*]] 323; 324 %retval = call <2 x float> @llvm.pow.v2f32(<2 x float> %x, <2 x float> <float 1.0, float 1.0>) 325 ret <2 x float> %retval 326} 327 328define double @test_simplify12(double %x) { 329; CHECK-LABEL: @test_simplify12( 330; LIB-NEXT: ret double [[X:%.*]] 331; NOLIB-NEXT: [[POW:%.*]] = call double @pow(double [[X:%.*]], double 1.000000e+00) 332; NOLIB-NEXT: ret double [[POW]] 333; 334 %retval = call double @pow(double %x, double 1.0) 335 ret double %retval 336} 337 338define <2 x double> @test_simplify12v(<2 x double> %x) { 339; CHECK-LABEL: @test_simplify12v( 340; CHECK-NEXT: ret <2 x double> [[X:%.*]] 341; 342 %retval = call <2 x double> @llvm.pow.v2f64(<2 x double> %x, <2 x double> <double 1.0, double 1.0>) 343 ret <2 x double> %retval 344} 345 346; Check pow(x, 2.0) -> x*x. 347 348define float @pow2_strict(float %x) { 349; CHECK-LABEL: @pow2_strict( 350; ANY-NEXT: [[SQUARE:%.*]] = fmul float [[X:%.*]], [[X]] 351; ANY-NEXT: ret float [[SQUARE]] 352; VC32-NEXT: [[POW:%.*]] = call float @powf(float [[X:%.*]], float 2.000000e+00) 353; VC32-NEXT: ret float [[POW]] 354; VC51-NEXT: [[POW:%.*]] = call float @powf(float [[X:%.*]], float 2.000000e+00) 355; VC51-NEXT: ret float [[POW]] 356; VC64-NEXT: [[SQUARE:%.*]] = fmul float [[X:%.*]], [[X]] 357; VC64-NEXT: ret float [[SQUARE]] 358; VC83-NEXT: [[SQUARE:%.*]] = fmul float [[X:%.*]], [[X]] 359; VC83-NEXT: ret float [[SQUARE]] 360; NOLIB-NEXT: [[POW:%.*]] = call float @powf(float [[X:%.*]], float 2.000000e+00) 361; NOLIB-NEXT: ret float [[POW]] 362; 363 %r = call float @powf(float %x, float 2.0) 364 ret float %r 365} 366 367define <2 x float> @pow2_strictv(<2 x float> %x) { 368; CHECK-LABEL: @pow2_strictv( 369; CHECK-NEXT: [[SQUARE:%.*]] = fmul <2 x float> [[X:%.*]], [[X]] 370; CHECK-NEXT: ret <2 x float> [[SQUARE]] 371; 372 %r = call <2 x float> @llvm.pow.v2f32(<2 x float> %x, <2 x float> <float 2.0, float 2.0>) 373 ret <2 x float> %r 374} 375 376define double @pow2_double_strict(double %x) { 377; CHECK-LABEL: @pow2_double_strict( 378; LIB-NEXT: [[SQUARE:%.*]] = fmul double [[X:%.*]], [[X]] 379; LIB-NEXT: ret double [[SQUARE]] 380; NOLIB-NEXT: [[POW:%.*]] = call double @pow(double [[X:%.*]], double 2.000000e+00) 381; NOLIB-NEXT: ret double [[POW]] 382; 383 %r = call double @pow(double %x, double 2.0) 384 ret double %r 385} 386 387define <2 x double> @pow2_double_strictv(<2 x double> %x) { 388; CHECK-LABEL: @pow2_double_strictv( 389; CHECK-NEXT: [[SQUARE:%.*]] = fmul <2 x double> [[X:%.*]], [[X]] 390; CHECK-NEXT: ret <2 x double> [[SQUARE]] 391; 392 %r = call <2 x double> @llvm.pow.v2f64(<2 x double> %x, <2 x double> <double 2.0, double 2.0>) 393 ret <2 x double> %r 394} 395 396; Don't drop the FMF - PR35601 ( https://bugs.llvm.org/show_bug.cgi?id=35601 ) 397 398define float @pow2_fast(float %x) { 399; CHECK-LABEL: @pow2_fast( 400; ANY-NEXT: [[SQUARE:%.*]] = fmul fast float [[X:%.*]], [[X]] 401; ANY-NEXT: ret float [[SQUARE]] 402; VC32-NEXT: [[POW:%.*]] = call fast float @powf(float [[X:%.*]], float 2.000000e+00) 403; VC32-NEXT: ret float [[POW]] 404; VC51-NEXT: [[POW:%.*]] = call fast float @powf(float [[X:%.*]], float 2.000000e+00) 405; VC51-NEXT: ret float [[POW]] 406; VC64-NEXT: [[SQUARE:%.*]] = fmul fast float [[X:%.*]], [[X]] 407; VC64-NEXT: ret float [[SQUARE]] 408; VC83-NEXT: [[SQUARE:%.*]] = fmul fast float [[X:%.*]], [[X]] 409; VC83-NEXT: ret float [[SQUARE]] 410; NOLIB-NEXT: [[POW:%.*]] = call fast float @powf(float [[X:%.*]], float 2.000000e+00) 411; NOLIB-NEXT: ret float [[POW]] 412; 413 %r = call fast float @powf(float %x, float 2.0) 414 ret float %r 415} 416 417; Check pow(x, -1.0) -> 1.0/x. 418 419define float @pow_neg1_strict(float %x) { 420; CHECK-LABEL: @pow_neg1_strict( 421; ANY-NEXT: [[RECIPROCAL:%.*]] = fdiv float 1.000000e+00, [[X:%.*]] 422; ANY-NEXT: ret float [[RECIPROCAL]] 423; VC32-NEXT: [[POW:%.*]] = call float @powf(float [[X:%.*]], float -1.000000e+00) 424; VC32-NEXT: ret float [[POW]] 425; VC51-NEXT: [[POW:%.*]] = call float @powf(float [[X:%.*]], float -1.000000e+00) 426; VC51-NEXT: ret float [[POW]] 427; VC64-NEXT: [[RECIPROCAL:%.*]] = fdiv float 1.000000e+00, [[X:%.*]] 428; VC64-NEXT: ret float [[RECIPROCAL]] 429; VC83-NEXT: [[RECIPROCAL:%.*]] = fdiv float 1.000000e+00, [[X:%.*]] 430; VC83-NEXT: ret float [[RECIPROCAL]] 431; NOLIB-NEXT: [[POW:%.*]] = call float @powf(float [[X:%.*]], float -1.000000e+00) 432; NOLIB-NEXT: ret float [[POW]] 433; 434 %r = call float @powf(float %x, float -1.0) 435 ret float %r 436} 437 438define <2 x float> @pow_neg1_strictv(<2 x float> %x) { 439; CHECK-LABEL: @pow_neg1_strictv( 440; CHECK-NEXT: [[RECIPROCAL:%.*]] = fdiv <2 x float> <float 1.000000e+00, float 1.000000e+00>, [[X:%.*]] 441; CHECK-NEXT: ret <2 x float> [[RECIPROCAL]] 442; 443 %r = call <2 x float> @llvm.pow.v2f32(<2 x float> %x, <2 x float> <float -1.0, float -1.0>) 444 ret <2 x float> %r 445} 446 447define double @pow_neg1_double_fast(double %x) { 448; CHECK-LABEL: @pow_neg1_double_fast( 449; LIB-NEXT: [[RECIPROCAL:%.*]] = fdiv fast double 1.000000e+00, [[X:%.*]] 450; LIB-NEXT: ret double [[RECIPROCAL]] 451; NOLIB-NEXT: [[POW:%.*]] = call fast double @pow(double [[X:%.*]], double -1.000000e+00) 452; NOLIB-NEXT: ret double [[POW]] 453; 454 %r = call fast double @pow(double %x, double -1.0) 455 ret double %r 456} 457 458define <2 x double> @pow_neg1_double_fastv(<2 x double> %x) { 459; CHECK-LABEL: @pow_neg1_double_fastv( 460; CHECK-NEXT: [[RECIPROCAL:%.*]] = fdiv fast <2 x double> <double 1.000000e+00, double 1.000000e+00>, [[X:%.*]] 461; CHECK-NEXT: ret <2 x double> [[RECIPROCAL]] 462; 463 %r = call fast <2 x double> @llvm.pow.v2f64(<2 x double> %x, <2 x double> <double -1.0, double -1.0>) 464 ret <2 x double> %r 465} 466 467define double @pow_intrinsic_half_no_FMF(double %x) { 468; CHECK-LABEL: @pow_intrinsic_half_no_FMF( 469; CHECK-NEXT: [[SQRT:%.*]] = call double @llvm.sqrt.f64(double [[X:%.*]]) 470; CHECK-NEXT: [[ABS:%.*]] = call double @llvm.fabs.f64(double [[SQRT]]) 471; CHECK-NEXT: [[ISINF:%.*]] = fcmp oeq double [[X]], 0xFFF0000000000000 472; CHECK-NEXT: [[TMP1:%.*]] = select i1 [[ISINF]], double 0x7FF0000000000000, double [[ABS]] 473; CHECK-NEXT: ret double [[TMP1]] 474; 475 %retval = call double @llvm.pow.f64(double %x, double 0.5) 476 ret double %retval 477} 478 479; Check pow(10.0, x) -> __exp10(x) on OS X 10.9+ and iOS 7.0+. 480 481define float @test_simplify18(float %x) { 482; CHECK-LABEL: @test_simplify18( 483; CHECK-EXP10-NEXT: [[__EXP10F:%.*]] = call float @__exp10f(float [[X:%.*]]) 484; CHECK-EXP10-NEXT: ret float [[__EXP10F]] 485; CHECK-NO-EXP10-NEXT: [[RETVAL:%.*]] = call float @powf(float 1.000000e+01, float [[X:%.*]]) 486; CHECK-NO-EXP10-NEXT: ret float [[RETVAL]] 487; 488 %retval = call float @powf(float 10.0, float %x) 489 ret float %retval 490} 491 492define double @test_simplify19(double %x) { 493; CHECK-LABEL: @test_simplify19( 494; CHECK-EXP10-NEXT: [[__EXP10:%.*]] = call double @__exp10(double [[X:%.*]]) 495; CHECK-EXP10-NEXT: ret double [[__EXP10]] 496; CHECK-NO-EXP10-NEXT: [[RETVAL:%.*]] = call double @pow(double 1.000000e+01, double [[X:%.*]]) 497; CHECK-NO-EXP10-NEXT: ret double [[RETVAL]] 498; 499 %retval = call double @pow(double 10.0, double %x) 500 ret double %retval 501} 502