1; NOTE: Assertions have been autogenerated by utils/update_test_checks.py UTC_ARGS: --version 4 2; Test that the pow library call simplifier works correctly. 3; 4; RUN: opt -passes=instcombine -S < %s | FileCheck %s --check-prefixes=CHECK,LIB,ANY 5; RUN: opt -passes=instcombine -S < %s -mtriple=x86_64-apple-macosx10.9 | FileCheck %s --check-prefixes=CHECK,LIB,ANY,CHECK-EXP10 6; RUN: opt -passes=instcombine -S < %s -mtriple=arm-apple-ios7.0 | FileCheck %s --check-prefixes=CHECK,LIB,ANY,CHECK-EXP10 7; RUN: opt -passes=instcombine -S < %s -mtriple=x86_64-apple-macosx10.8 | FileCheck %s --check-prefixes=CHECK,LIB,ANY,CHECK-NO-EXP10 8; RUN: opt -passes=instcombine -S < %s -mtriple=arm-apple-ios6.0 | FileCheck %s --check-prefixes=CHECK,LIB,ANY,CHECK-NO-EXP10 9; RUN: opt -passes=instcombine -S < %s -mtriple=x86_64-netbsd | FileCheck %s --check-prefixes=CHECK,LIB,ANY,CHECK-NO-EXP10 10; RUN: opt -passes=instcombine -S < %s -mtriple=arm-apple-tvos9.0 | FileCheck %s --check-prefixes=CHECK,LIB,ANY,CHECK-EXP10 11; RUN: opt -passes=instcombine -S < %s -mtriple=arm-apple-watchos2.0 | FileCheck %s --check-prefixes=CHECK,LIB,ANY,CHECK-EXP10 12; rdar://7251832 13; RUN: opt -passes=instcombine -S < %s -mtriple=i386-pc-windows-msvc18 | FileCheck %s --check-prefixes=CHECK,LIB,CHECK-NO-EXP10,VC32 14; RUN: opt -passes=instcombine -S < %s -mtriple=i386-pc-windows-msvc | FileCheck %s --check-prefixes=CHECK,LIB,CHECK-NO-EXP10,VC19,VC51 15; RUN: opt -passes=instcombine -S < %s -mtriple=x86_64-pc-windows-msvc18 | FileCheck %s --check-prefixes=CHECK,LIB,CHECK-NO-EXP10,VC64 16; RUN: opt -passes=instcombine -S < %s -mtriple=x86_64-pc-windows-msvc | FileCheck %s --check-prefixes=CHECK,LIB,CHECK-NO-EXP10,VC19,VC83 17; RUN: opt -passes=instcombine -S < %s -mtriple=amdgcn-- | FileCheck %s --check-prefixes=CHECK,CHECK-NO-EXP10,NOLIB 18 19; NOTE: The readonly attribute on the pow call should be preserved 20; in the cases below where pow is transformed into another function call. 21 22declare float @powf(float, float) 23declare float @llvm.pow.f32(float, float) 24declare float @llvm.fabs.f32(float) 25declare double @pow(double, double) 26declare double @llvm.pow.f64(double, double) 27declare <2 x float> @llvm.pow.v2f32(<2 x float>, <2 x float>) nounwind readonly 28declare <2 x double> @llvm.pow.v2f64(<2 x double>, <2 x double>) nounwind readonly 29declare void @llvm.assume(i1 noundef) 30 31; Check pow(1.0, x) -> 1.0. 32 33define float @test_simplify1(float %x) { 34; ANY-LABEL: define float @test_simplify1( 35; ANY-SAME: float [[X:%.*]]) { 36; ANY-NEXT: ret float 1.000000e+00 37; 38; VC32-LABEL: define float @test_simplify1( 39; VC32-SAME: float [[X:%.*]]) { 40; VC32-NEXT: [[RETVAL:%.*]] = call float @powf(float 1.000000e+00, float [[X]]) 41; VC32-NEXT: ret float [[RETVAL]] 42; 43; VC51-LABEL: define float @test_simplify1( 44; VC51-SAME: float [[X:%.*]]) { 45; VC51-NEXT: [[RETVAL:%.*]] = call float @powf(float 1.000000e+00, float [[X]]) 46; VC51-NEXT: ret float [[RETVAL]] 47; 48; VC64-LABEL: define float @test_simplify1( 49; VC64-SAME: float [[X:%.*]]) { 50; VC64-NEXT: ret float 1.000000e+00 51; 52; VC83-LABEL: define float @test_simplify1( 53; VC83-SAME: float [[X:%.*]]) { 54; VC83-NEXT: ret float 1.000000e+00 55; 56; NOLIB-LABEL: define float @test_simplify1( 57; NOLIB-SAME: float [[X:%.*]]) { 58; NOLIB-NEXT: [[RETVAL:%.*]] = call float @powf(float 1.000000e+00, float [[X]]) 59; NOLIB-NEXT: ret float [[RETVAL]] 60; 61 %retval = call float @powf(float 1.0, float %x) 62 ret float %retval 63} 64 65define float @test_simplify1_noerrno(float %x) { 66; ANY-LABEL: define float @test_simplify1_noerrno( 67; ANY-SAME: float [[X:%.*]]) { 68; ANY-NEXT: ret float 1.000000e+00 69; 70; VC32-LABEL: define float @test_simplify1_noerrno( 71; VC32-SAME: float [[X:%.*]]) { 72; VC32-NEXT: [[RETVAL:%.*]] = call float @powf(float 1.000000e+00, float [[X]]) #[[ATTR2:[0-9]+]] 73; VC32-NEXT: ret float [[RETVAL]] 74; 75; VC51-LABEL: define float @test_simplify1_noerrno( 76; VC51-SAME: float [[X:%.*]]) { 77; VC51-NEXT: [[RETVAL:%.*]] = call float @powf(float 1.000000e+00, float [[X]]) #[[ATTR2:[0-9]+]] 78; VC51-NEXT: ret float [[RETVAL]] 79; 80; VC64-LABEL: define float @test_simplify1_noerrno( 81; VC64-SAME: float [[X:%.*]]) { 82; VC64-NEXT: ret float 1.000000e+00 83; 84; VC83-LABEL: define float @test_simplify1_noerrno( 85; VC83-SAME: float [[X:%.*]]) { 86; VC83-NEXT: ret float 1.000000e+00 87; 88; NOLIB-LABEL: define float @test_simplify1_noerrno( 89; NOLIB-SAME: float [[X:%.*]]) { 90; NOLIB-NEXT: [[RETVAL:%.*]] = call float @powf(float 1.000000e+00, float [[X]]) #[[ATTR2:[0-9]+]] 91; NOLIB-NEXT: ret float [[RETVAL]] 92; 93 %retval = call float @powf(float 1.0, float %x) #0 94 ret float %retval 95} 96 97define <2 x float> @test_simplify1v(<2 x float> %x) { 98; CHECK-LABEL: define <2 x float> @test_simplify1v( 99; CHECK-SAME: <2 x float> [[X:%.*]]) { 100; CHECK-NEXT: ret <2 x float> splat (float 1.000000e+00) 101; 102 %retval = call <2 x float> @llvm.pow.v2f32(<2 x float> <float 1.0, float 1.0>, <2 x float> %x) 103 ret <2 x float> %retval 104} 105 106define double @test_simplify2(double %x) { 107; LIB-LABEL: define double @test_simplify2( 108; LIB-SAME: double [[X:%.*]]) { 109; LIB-NEXT: ret double 1.000000e+00 110; 111; NOLIB-LABEL: define double @test_simplify2( 112; NOLIB-SAME: double [[X:%.*]]) { 113; NOLIB-NEXT: [[RETVAL:%.*]] = call double @pow(double 1.000000e+00, double [[X]]) 114; NOLIB-NEXT: ret double [[RETVAL]] 115; 116 %retval = call double @pow(double 1.0, double %x) 117 ret double %retval 118} 119 120define double @test_simplify2_noerrno(double %x) { 121; LIB-LABEL: define double @test_simplify2_noerrno( 122; LIB-SAME: double [[X:%.*]]) { 123; LIB-NEXT: ret double 1.000000e+00 124; 125; NOLIB-LABEL: define double @test_simplify2_noerrno( 126; NOLIB-SAME: double [[X:%.*]]) { 127; NOLIB-NEXT: [[RETVAL:%.*]] = call double @pow(double 1.000000e+00, double [[X]]) #[[ATTR2]] 128; NOLIB-NEXT: ret double [[RETVAL]] 129; 130 %retval = call double @pow(double 1.0, double %x) #0 131 ret double %retval 132} 133 134define <2 x double> @test_simplify2v(<2 x double> %x) { 135; CHECK-LABEL: define <2 x double> @test_simplify2v( 136; CHECK-SAME: <2 x double> [[X:%.*]]) { 137; CHECK-NEXT: ret <2 x double> splat (double 1.000000e+00) 138; 139 %retval = call <2 x double> @llvm.pow.v2f64(<2 x double> <double 1.0, double 1.0>, <2 x double> %x) 140 ret <2 x double> %retval 141} 142 143; Check pow(2.0 ** n, x) -> exp2(n * x). 144 145define float @test_simplify3(float %x) { 146; ANY-LABEL: define float @test_simplify3( 147; ANY-SAME: float [[X:%.*]]) { 148; ANY-NEXT: [[EXP2F:%.*]] = call float @exp2f(float [[X]]) 149; ANY-NEXT: ret float [[EXP2F]] 150; 151; VC32-LABEL: define float @test_simplify3( 152; VC32-SAME: float [[X:%.*]]) { 153; VC32-NEXT: [[RETVAL:%.*]] = call float @powf(float 2.000000e+00, float [[X]]) 154; VC32-NEXT: ret float [[RETVAL]] 155; 156; VC51-LABEL: define float @test_simplify3( 157; VC51-SAME: float [[X:%.*]]) { 158; VC51-NEXT: [[RETVAL:%.*]] = call float @powf(float 2.000000e+00, float [[X]]) 159; VC51-NEXT: ret float [[RETVAL]] 160; 161; VC64-LABEL: define float @test_simplify3( 162; VC64-SAME: float [[X:%.*]]) { 163; VC64-NEXT: [[RETVAL:%.*]] = call float @powf(float 2.000000e+00, float [[X]]) 164; VC64-NEXT: ret float [[RETVAL]] 165; 166; VC83-LABEL: define float @test_simplify3( 167; VC83-SAME: float [[X:%.*]]) { 168; VC83-NEXT: [[EXP2F:%.*]] = call float @exp2f(float [[X]]) 169; VC83-NEXT: ret float [[EXP2F]] 170; 171; NOLIB-LABEL: define float @test_simplify3( 172; NOLIB-SAME: float [[X:%.*]]) { 173; NOLIB-NEXT: [[RETVAL:%.*]] = call float @powf(float 2.000000e+00, float [[X]]) 174; NOLIB-NEXT: ret float [[RETVAL]] 175; 176 %retval = call float @powf(float 2.0, float %x) 177 ret float %retval 178} 179 180define float @test_simplify3_noerrno(float %x) { 181; ANY-LABEL: define float @test_simplify3_noerrno( 182; ANY-SAME: float [[X:%.*]]) { 183; ANY-NEXT: [[EXP2:%.*]] = call float @llvm.exp2.f32(float [[X]]) 184; ANY-NEXT: ret float [[EXP2]] 185; 186; VC32-LABEL: define float @test_simplify3_noerrno( 187; VC32-SAME: float [[X:%.*]]) { 188; VC32-NEXT: [[RETVAL:%.*]] = call float @powf(float 2.000000e+00, float [[X]]) #[[ATTR2]] 189; VC32-NEXT: ret float [[RETVAL]] 190; 191; VC51-LABEL: define float @test_simplify3_noerrno( 192; VC51-SAME: float [[X:%.*]]) { 193; VC51-NEXT: [[RETVAL:%.*]] = call float @powf(float 2.000000e+00, float [[X]]) #[[ATTR2]] 194; VC51-NEXT: ret float [[RETVAL]] 195; 196; VC64-LABEL: define float @test_simplify3_noerrno( 197; VC64-SAME: float [[X:%.*]]) { 198; VC64-NEXT: [[RETVAL:%.*]] = call float @powf(float 2.000000e+00, float [[X]]) #[[ATTR2:[0-9]+]] 199; VC64-NEXT: ret float [[RETVAL]] 200; 201; VC83-LABEL: define float @test_simplify3_noerrno( 202; VC83-SAME: float [[X:%.*]]) { 203; VC83-NEXT: [[EXP2:%.*]] = call float @llvm.exp2.f32(float [[X]]) 204; VC83-NEXT: ret float [[EXP2]] 205; 206; NOLIB-LABEL: define float @test_simplify3_noerrno( 207; NOLIB-SAME: float [[X:%.*]]) { 208; NOLIB-NEXT: [[RETVAL:%.*]] = call float @powf(float 2.000000e+00, float [[X]]) #[[ATTR2]] 209; NOLIB-NEXT: ret float [[RETVAL]] 210; 211 %retval = call float @powf(float 2.0, float %x) #0 212 ret float %retval 213} 214 215define double @test_simplify3n_noerrno(double %x) { 216; ANY-LABEL: define double @test_simplify3n_noerrno( 217; ANY-SAME: double [[X:%.*]]) { 218; ANY-NEXT: [[MUL:%.*]] = fmul double [[X]], -2.000000e+00 219; ANY-NEXT: [[EXP2:%.*]] = call double @llvm.exp2.f64(double [[MUL]]) 220; ANY-NEXT: ret double [[EXP2]] 221; 222; VC32-LABEL: define double @test_simplify3n_noerrno( 223; VC32-SAME: double [[X:%.*]]) { 224; VC32-NEXT: [[RETVAL:%.*]] = call double @pow(double 2.500000e-01, double [[X]]) #[[ATTR2]] 225; VC32-NEXT: ret double [[RETVAL]] 226; 227; VC19-LABEL: define double @test_simplify3n_noerrno( 228; VC19-SAME: double [[X:%.*]]) { 229; VC19-NEXT: [[MUL:%.*]] = fmul double [[X]], -2.000000e+00 230; VC19-NEXT: [[EXP2:%.*]] = call double @llvm.exp2.f64(double [[MUL]]) 231; VC19-NEXT: ret double [[EXP2]] 232; 233; VC64-LABEL: define double @test_simplify3n_noerrno( 234; VC64-SAME: double [[X:%.*]]) { 235; VC64-NEXT: [[RETVAL:%.*]] = call double @pow(double 2.500000e-01, double [[X]]) #[[ATTR2]] 236; VC64-NEXT: ret double [[RETVAL]] 237; 238; NOLIB-LABEL: define double @test_simplify3n_noerrno( 239; NOLIB-SAME: double [[X:%.*]]) { 240; NOLIB-NEXT: [[RETVAL:%.*]] = call double @pow(double 2.500000e-01, double [[X]]) #[[ATTR2]] 241; NOLIB-NEXT: ret double [[RETVAL]] 242; 243 %retval = call double @pow(double 0.25, double %x) #0 244 ret double %retval 245} 246 247; TODO: should be able to simplify llvm.pow to llvm.exp2 even without libcalls 248define <2 x float> @test_simplify3v(<2 x float> %x) { 249; ANY-LABEL: define <2 x float> @test_simplify3v( 250; ANY-SAME: <2 x float> [[X:%.*]]) { 251; ANY-NEXT: [[EXP2:%.*]] = call <2 x float> @llvm.exp2.v2f32(<2 x float> [[X]]) 252; ANY-NEXT: ret <2 x float> [[EXP2]] 253; 254; VC32-LABEL: define <2 x float> @test_simplify3v( 255; VC32-SAME: <2 x float> [[X:%.*]]) { 256; VC32-NEXT: [[RETVAL:%.*]] = call <2 x float> @llvm.pow.v2f32(<2 x float> splat (float 2.000000e+00), <2 x float> [[X]]) 257; VC32-NEXT: ret <2 x float> [[RETVAL]] 258; 259; VC19-LABEL: define <2 x float> @test_simplify3v( 260; VC19-SAME: <2 x float> [[X:%.*]]) { 261; VC19-NEXT: [[RETVAL:%.*]] = call <2 x float> @llvm.pow.v2f32(<2 x float> splat (float 2.000000e+00), <2 x float> [[X]]) 262; VC19-NEXT: ret <2 x float> [[RETVAL]] 263; 264; VC64-LABEL: define <2 x float> @test_simplify3v( 265; VC64-SAME: <2 x float> [[X:%.*]]) { 266; VC64-NEXT: [[RETVAL:%.*]] = call <2 x float> @llvm.pow.v2f32(<2 x float> splat (float 2.000000e+00), <2 x float> [[X]]) 267; VC64-NEXT: ret <2 x float> [[RETVAL]] 268; 269; NOLIB-LABEL: define <2 x float> @test_simplify3v( 270; NOLIB-SAME: <2 x float> [[X:%.*]]) { 271; NOLIB-NEXT: [[RETVAL:%.*]] = call <2 x float> @llvm.pow.v2f32(<2 x float> splat (float 2.000000e+00), <2 x float> [[X]]) 272; NOLIB-NEXT: ret <2 x float> [[RETVAL]] 273; 274 %retval = call <2 x float> @llvm.pow.v2f32(<2 x float> <float 2.0, float 2.0>, <2 x float> %x) 275 ret <2 x float> %retval 276} 277 278; TODO: should be able to simplify llvm.pow to llvm.exp2 even without libcalls 279define <2 x double> @test_simplify3vn(<2 x double> %x) { 280; ANY-LABEL: define <2 x double> @test_simplify3vn( 281; ANY-SAME: <2 x double> [[X:%.*]]) { 282; ANY-NEXT: [[MUL:%.*]] = fmul <2 x double> [[X]], splat (double 2.000000e+00) 283; ANY-NEXT: [[EXP2:%.*]] = call <2 x double> @llvm.exp2.v2f64(<2 x double> [[MUL]]) 284; ANY-NEXT: ret <2 x double> [[EXP2]] 285; 286; VC32-LABEL: define <2 x double> @test_simplify3vn( 287; VC32-SAME: <2 x double> [[X:%.*]]) { 288; VC32-NEXT: [[RETVAL:%.*]] = call <2 x double> @llvm.pow.v2f64(<2 x double> splat (double 4.000000e+00), <2 x double> [[X]]) 289; VC32-NEXT: ret <2 x double> [[RETVAL]] 290; 291; VC19-LABEL: define <2 x double> @test_simplify3vn( 292; VC19-SAME: <2 x double> [[X:%.*]]) { 293; VC19-NEXT: [[RETVAL:%.*]] = call <2 x double> @llvm.pow.v2f64(<2 x double> splat (double 4.000000e+00), <2 x double> [[X]]) 294; VC19-NEXT: ret <2 x double> [[RETVAL]] 295; 296; VC64-LABEL: define <2 x double> @test_simplify3vn( 297; VC64-SAME: <2 x double> [[X:%.*]]) { 298; VC64-NEXT: [[RETVAL:%.*]] = call <2 x double> @llvm.pow.v2f64(<2 x double> splat (double 4.000000e+00), <2 x double> [[X]]) 299; VC64-NEXT: ret <2 x double> [[RETVAL]] 300; 301; NOLIB-LABEL: define <2 x double> @test_simplify3vn( 302; NOLIB-SAME: <2 x double> [[X:%.*]]) { 303; NOLIB-NEXT: [[RETVAL:%.*]] = call <2 x double> @llvm.pow.v2f64(<2 x double> splat (double 4.000000e+00), <2 x double> [[X]]) 304; NOLIB-NEXT: ret <2 x double> [[RETVAL]] 305; 306 %retval = call <2 x double> @llvm.pow.v2f64(<2 x double> <double 4.0, double 4.0>, <2 x double> %x) 307 ret <2 x double> %retval 308} 309 310define double @test_simplify4(double %x) { 311; ANY-LABEL: define double @test_simplify4( 312; ANY-SAME: double [[X:%.*]]) { 313; ANY-NEXT: [[EXP2:%.*]] = call double @exp2(double [[X]]) 314; ANY-NEXT: ret double [[EXP2]] 315; 316; VC32-LABEL: define double @test_simplify4( 317; VC32-SAME: double [[X:%.*]]) { 318; VC32-NEXT: [[RETVAL:%.*]] = call double @pow(double 2.000000e+00, double [[X]]) 319; VC32-NEXT: ret double [[RETVAL]] 320; 321; VC19-LABEL: define double @test_simplify4( 322; VC19-SAME: double [[X:%.*]]) { 323; VC19-NEXT: [[EXP2:%.*]] = call double @exp2(double [[X]]) 324; VC19-NEXT: ret double [[EXP2]] 325; 326; VC64-LABEL: define double @test_simplify4( 327; VC64-SAME: double [[X:%.*]]) { 328; VC64-NEXT: [[RETVAL:%.*]] = call double @pow(double 2.000000e+00, double [[X]]) 329; VC64-NEXT: ret double [[RETVAL]] 330; 331; NOLIB-LABEL: define double @test_simplify4( 332; NOLIB-SAME: double [[X:%.*]]) { 333; NOLIB-NEXT: [[RETVAL:%.*]] = call double @pow(double 2.000000e+00, double [[X]]) 334; NOLIB-NEXT: ret double [[RETVAL]] 335; 336 %retval = call double @pow(double 2.0, double %x) 337 ret double %retval 338} 339 340define double @test_simplify4_noerrno(double %x) { 341; ANY-LABEL: define double @test_simplify4_noerrno( 342; ANY-SAME: double [[X:%.*]]) { 343; ANY-NEXT: [[EXP2:%.*]] = call double @llvm.exp2.f64(double [[X]]) 344; ANY-NEXT: ret double [[EXP2]] 345; 346; VC32-LABEL: define double @test_simplify4_noerrno( 347; VC32-SAME: double [[X:%.*]]) { 348; VC32-NEXT: [[RETVAL:%.*]] = call double @pow(double 2.000000e+00, double [[X]]) #[[ATTR2]] 349; VC32-NEXT: ret double [[RETVAL]] 350; 351; VC19-LABEL: define double @test_simplify4_noerrno( 352; VC19-SAME: double [[X:%.*]]) { 353; VC19-NEXT: [[EXP2:%.*]] = call double @llvm.exp2.f64(double [[X]]) 354; VC19-NEXT: ret double [[EXP2]] 355; 356; VC64-LABEL: define double @test_simplify4_noerrno( 357; VC64-SAME: double [[X:%.*]]) { 358; VC64-NEXT: [[RETVAL:%.*]] = call double @pow(double 2.000000e+00, double [[X]]) #[[ATTR2]] 359; VC64-NEXT: ret double [[RETVAL]] 360; 361; NOLIB-LABEL: define double @test_simplify4_noerrno( 362; NOLIB-SAME: double [[X:%.*]]) { 363; NOLIB-NEXT: [[RETVAL:%.*]] = call double @pow(double 2.000000e+00, double [[X]]) #[[ATTR2]] 364; NOLIB-NEXT: ret double [[RETVAL]] 365; 366 %retval = call double @pow(double 2.0, double %x) #0 367 ret double %retval 368} 369 370define float @test_simplify4n(float %x) { 371; ANY-LABEL: define float @test_simplify4n( 372; ANY-SAME: float [[X:%.*]]) { 373; ANY-NEXT: [[MUL:%.*]] = fmul float [[X]], 3.000000e+00 374; ANY-NEXT: [[EXP2F:%.*]] = call float @exp2f(float [[MUL]]) 375; ANY-NEXT: ret float [[EXP2F]] 376; 377; VC32-LABEL: define float @test_simplify4n( 378; VC32-SAME: float [[X:%.*]]) { 379; VC32-NEXT: [[RETVAL:%.*]] = call float @powf(float 8.000000e+00, float [[X]]) 380; VC32-NEXT: ret float [[RETVAL]] 381; 382; VC51-LABEL: define float @test_simplify4n( 383; VC51-SAME: float [[X:%.*]]) { 384; VC51-NEXT: [[RETVAL:%.*]] = call float @powf(float 8.000000e+00, float [[X]]) 385; VC51-NEXT: ret float [[RETVAL]] 386; 387; VC64-LABEL: define float @test_simplify4n( 388; VC64-SAME: float [[X:%.*]]) { 389; VC64-NEXT: [[RETVAL:%.*]] = call float @powf(float 8.000000e+00, float [[X]]) 390; VC64-NEXT: ret float [[RETVAL]] 391; 392; VC83-LABEL: define float @test_simplify4n( 393; VC83-SAME: float [[X:%.*]]) { 394; VC83-NEXT: [[MUL:%.*]] = fmul float [[X]], 3.000000e+00 395; VC83-NEXT: [[EXP2F:%.*]] = call float @exp2f(float [[MUL]]) 396; VC83-NEXT: ret float [[EXP2F]] 397; 398; NOLIB-LABEL: define float @test_simplify4n( 399; NOLIB-SAME: float [[X:%.*]]) { 400; NOLIB-NEXT: [[RETVAL:%.*]] = call float @powf(float 8.000000e+00, float [[X]]) 401; NOLIB-NEXT: ret float [[RETVAL]] 402; 403 %retval = call float @powf(float 8.0, float %x) 404 ret float %retval 405} 406 407define float @test_simplify4n_noerrno(float %x) { 408; ANY-LABEL: define float @test_simplify4n_noerrno( 409; ANY-SAME: float [[X:%.*]]) { 410; ANY-NEXT: [[MUL:%.*]] = fmul float [[X]], 3.000000e+00 411; ANY-NEXT: [[EXP2:%.*]] = call float @llvm.exp2.f32(float [[MUL]]) 412; ANY-NEXT: ret float [[EXP2]] 413; 414; VC32-LABEL: define float @test_simplify4n_noerrno( 415; VC32-SAME: float [[X:%.*]]) { 416; VC32-NEXT: [[RETVAL:%.*]] = call float @powf(float 8.000000e+00, float [[X]]) #[[ATTR2]] 417; VC32-NEXT: ret float [[RETVAL]] 418; 419; VC51-LABEL: define float @test_simplify4n_noerrno( 420; VC51-SAME: float [[X:%.*]]) { 421; VC51-NEXT: [[RETVAL:%.*]] = call float @powf(float 8.000000e+00, float [[X]]) #[[ATTR2]] 422; VC51-NEXT: ret float [[RETVAL]] 423; 424; VC64-LABEL: define float @test_simplify4n_noerrno( 425; VC64-SAME: float [[X:%.*]]) { 426; VC64-NEXT: [[RETVAL:%.*]] = call float @powf(float 8.000000e+00, float [[X]]) #[[ATTR2]] 427; VC64-NEXT: ret float [[RETVAL]] 428; 429; VC83-LABEL: define float @test_simplify4n_noerrno( 430; VC83-SAME: float [[X:%.*]]) { 431; VC83-NEXT: [[MUL:%.*]] = fmul float [[X]], 3.000000e+00 432; VC83-NEXT: [[EXP2:%.*]] = call float @llvm.exp2.f32(float [[MUL]]) 433; VC83-NEXT: ret float [[EXP2]] 434; 435; NOLIB-LABEL: define float @test_simplify4n_noerrno( 436; NOLIB-SAME: float [[X:%.*]]) { 437; NOLIB-NEXT: [[RETVAL:%.*]] = call float @powf(float 8.000000e+00, float [[X]]) #[[ATTR2]] 438; NOLIB-NEXT: ret float [[RETVAL]] 439; 440 %retval = call float @powf(float 8.0, float %x) #0 441 ret float %retval 442} 443 444; TODO: should be able to simplify llvm.pow to llvm.exp2 even without libcalls 445define <2 x double> @test_simplify4v(<2 x double> %x) { 446; ANY-LABEL: define <2 x double> @test_simplify4v( 447; ANY-SAME: <2 x double> [[X:%.*]]) { 448; ANY-NEXT: [[EXP2:%.*]] = call <2 x double> @llvm.exp2.v2f64(<2 x double> [[X]]) 449; ANY-NEXT: ret <2 x double> [[EXP2]] 450; 451; VC32-LABEL: define <2 x double> @test_simplify4v( 452; VC32-SAME: <2 x double> [[X:%.*]]) { 453; VC32-NEXT: [[RETVAL:%.*]] = call <2 x double> @llvm.pow.v2f64(<2 x double> splat (double 2.000000e+00), <2 x double> [[X]]) 454; VC32-NEXT: ret <2 x double> [[RETVAL]] 455; 456; VC19-LABEL: define <2 x double> @test_simplify4v( 457; VC19-SAME: <2 x double> [[X:%.*]]) { 458; VC19-NEXT: [[RETVAL:%.*]] = call <2 x double> @llvm.pow.v2f64(<2 x double> splat (double 2.000000e+00), <2 x double> [[X]]) 459; VC19-NEXT: ret <2 x double> [[RETVAL]] 460; 461; VC64-LABEL: define <2 x double> @test_simplify4v( 462; VC64-SAME: <2 x double> [[X:%.*]]) { 463; VC64-NEXT: [[RETVAL:%.*]] = call <2 x double> @llvm.pow.v2f64(<2 x double> splat (double 2.000000e+00), <2 x double> [[X]]) 464; VC64-NEXT: ret <2 x double> [[RETVAL]] 465; 466; NOLIB-LABEL: define <2 x double> @test_simplify4v( 467; NOLIB-SAME: <2 x double> [[X:%.*]]) { 468; NOLIB-NEXT: [[RETVAL:%.*]] = call <2 x double> @llvm.pow.v2f64(<2 x double> splat (double 2.000000e+00), <2 x double> [[X]]) 469; NOLIB-NEXT: ret <2 x double> [[RETVAL]] 470; 471 %retval = call <2 x double> @llvm.pow.v2f64(<2 x double> <double 2.0, double 2.0>, <2 x double> %x) 472 ret <2 x double> %retval 473} 474 475; TODO: should be able to simplify llvm.pow to llvm.exp2 even without libcalls 476define <2 x float> @test_simplify4vn(<2 x float> %x) { 477; ANY-LABEL: define <2 x float> @test_simplify4vn( 478; ANY-SAME: <2 x float> [[X:%.*]]) { 479; ANY-NEXT: [[MUL:%.*]] = fneg <2 x float> [[X]] 480; ANY-NEXT: [[EXP2:%.*]] = call <2 x float> @llvm.exp2.v2f32(<2 x float> [[MUL]]) 481; ANY-NEXT: ret <2 x float> [[EXP2]] 482; 483; VC32-LABEL: define <2 x float> @test_simplify4vn( 484; VC32-SAME: <2 x float> [[X:%.*]]) { 485; VC32-NEXT: [[RETVAL:%.*]] = call <2 x float> @llvm.pow.v2f32(<2 x float> splat (float 5.000000e-01), <2 x float> [[X]]) 486; VC32-NEXT: ret <2 x float> [[RETVAL]] 487; 488; VC19-LABEL: define <2 x float> @test_simplify4vn( 489; VC19-SAME: <2 x float> [[X:%.*]]) { 490; VC19-NEXT: [[RETVAL:%.*]] = call <2 x float> @llvm.pow.v2f32(<2 x float> splat (float 5.000000e-01), <2 x float> [[X]]) 491; VC19-NEXT: ret <2 x float> [[RETVAL]] 492; 493; VC64-LABEL: define <2 x float> @test_simplify4vn( 494; VC64-SAME: <2 x float> [[X:%.*]]) { 495; VC64-NEXT: [[RETVAL:%.*]] = call <2 x float> @llvm.pow.v2f32(<2 x float> splat (float 5.000000e-01), <2 x float> [[X]]) 496; VC64-NEXT: ret <2 x float> [[RETVAL]] 497; 498; NOLIB-LABEL: define <2 x float> @test_simplify4vn( 499; NOLIB-SAME: <2 x float> [[X:%.*]]) { 500; NOLIB-NEXT: [[RETVAL:%.*]] = call <2 x float> @llvm.pow.v2f32(<2 x float> splat (float 5.000000e-01), <2 x float> [[X]]) 501; NOLIB-NEXT: ret <2 x float> [[RETVAL]] 502; 503 %retval = call <2 x float> @llvm.pow.v2f32(<2 x float> <float 0.5, float 0.5>, <2 x float> %x) 504 ret <2 x float> %retval 505} 506 507; Check pow(x, 0.0) -> 1.0. 508 509define float @test_simplify5(float %x) { 510; ANY-LABEL: define float @test_simplify5( 511; ANY-SAME: float [[X:%.*]]) { 512; ANY-NEXT: ret float 1.000000e+00 513; 514; VC32-LABEL: define float @test_simplify5( 515; VC32-SAME: float [[X:%.*]]) { 516; VC32-NEXT: [[RETVAL:%.*]] = call float @powf(float [[X]], float 0.000000e+00) 517; VC32-NEXT: ret float [[RETVAL]] 518; 519; VC51-LABEL: define float @test_simplify5( 520; VC51-SAME: float [[X:%.*]]) { 521; VC51-NEXT: [[RETVAL:%.*]] = call float @powf(float [[X]], float 0.000000e+00) 522; VC51-NEXT: ret float [[RETVAL]] 523; 524; VC64-LABEL: define float @test_simplify5( 525; VC64-SAME: float [[X:%.*]]) { 526; VC64-NEXT: ret float 1.000000e+00 527; 528; VC83-LABEL: define float @test_simplify5( 529; VC83-SAME: float [[X:%.*]]) { 530; VC83-NEXT: ret float 1.000000e+00 531; 532; NOLIB-LABEL: define float @test_simplify5( 533; NOLIB-SAME: float [[X:%.*]]) { 534; NOLIB-NEXT: [[RETVAL:%.*]] = call float @powf(float [[X]], float 0.000000e+00) 535; NOLIB-NEXT: ret float [[RETVAL]] 536; 537 %retval = call float @powf(float %x, float 0.0) 538 ret float %retval 539} 540 541define float @test_simplify5_noerrno(float %x) { 542; ANY-LABEL: define float @test_simplify5_noerrno( 543; ANY-SAME: float [[X:%.*]]) { 544; ANY-NEXT: ret float 1.000000e+00 545; 546; VC32-LABEL: define float @test_simplify5_noerrno( 547; VC32-SAME: float [[X:%.*]]) { 548; VC32-NEXT: [[RETVAL:%.*]] = call float @powf(float [[X]], float 0.000000e+00) #[[ATTR2]] 549; VC32-NEXT: ret float [[RETVAL]] 550; 551; VC51-LABEL: define float @test_simplify5_noerrno( 552; VC51-SAME: float [[X:%.*]]) { 553; VC51-NEXT: [[RETVAL:%.*]] = call float @powf(float [[X]], float 0.000000e+00) #[[ATTR2]] 554; VC51-NEXT: ret float [[RETVAL]] 555; 556; VC64-LABEL: define float @test_simplify5_noerrno( 557; VC64-SAME: float [[X:%.*]]) { 558; VC64-NEXT: ret float 1.000000e+00 559; 560; VC83-LABEL: define float @test_simplify5_noerrno( 561; VC83-SAME: float [[X:%.*]]) { 562; VC83-NEXT: ret float 1.000000e+00 563; 564; NOLIB-LABEL: define float @test_simplify5_noerrno( 565; NOLIB-SAME: float [[X:%.*]]) { 566; NOLIB-NEXT: [[RETVAL:%.*]] = call float @powf(float [[X]], float 0.000000e+00) #[[ATTR2]] 567; NOLIB-NEXT: ret float [[RETVAL]] 568; 569 %retval = call float @powf(float %x, float 0.0) #0 570 ret float %retval 571} 572 573define <2 x float> @test_simplify5v(<2 x float> %x) { 574; CHECK-LABEL: define <2 x float> @test_simplify5v( 575; CHECK-SAME: <2 x float> [[X:%.*]]) { 576; CHECK-NEXT: ret <2 x float> splat (float 1.000000e+00) 577; 578 %retval = call <2 x float> @llvm.pow.v2f32(<2 x float> %x, <2 x float> <float 0.0, float 0.0>) 579 ret <2 x float> %retval 580} 581 582define double @test_simplify6(double %x) { 583; LIB-LABEL: define double @test_simplify6( 584; LIB-SAME: double [[X:%.*]]) { 585; LIB-NEXT: ret double 1.000000e+00 586; 587; NOLIB-LABEL: define double @test_simplify6( 588; NOLIB-SAME: double [[X:%.*]]) { 589; NOLIB-NEXT: [[RETVAL:%.*]] = call double @pow(double [[X]], double 0.000000e+00) 590; NOLIB-NEXT: ret double [[RETVAL]] 591; 592 %retval = call double @pow(double %x, double 0.0) 593 ret double %retval 594} 595 596define double @test_simplify6_noerrno(double %x) { 597; LIB-LABEL: define double @test_simplify6_noerrno( 598; LIB-SAME: double [[X:%.*]]) { 599; LIB-NEXT: ret double 1.000000e+00 600; 601; NOLIB-LABEL: define double @test_simplify6_noerrno( 602; NOLIB-SAME: double [[X:%.*]]) { 603; NOLIB-NEXT: [[RETVAL:%.*]] = call double @pow(double [[X]], double 0.000000e+00) #[[ATTR2]] 604; NOLIB-NEXT: ret double [[RETVAL]] 605; 606 %retval = call double @pow(double %x, double 0.0) #0 607 ret double %retval 608} 609 610define <2 x double> @test_simplify6v(<2 x double> %x) { 611; CHECK-LABEL: define <2 x double> @test_simplify6v( 612; CHECK-SAME: <2 x double> [[X:%.*]]) { 613; CHECK-NEXT: ret <2 x double> splat (double 1.000000e+00) 614; 615 %retval = call <2 x double> @llvm.pow.v2f64(<2 x double> %x, <2 x double> <double 0.0, double 0.0>) 616 ret <2 x double> %retval 617} 618 619; Check pow(x, 0.5) -> fabs(sqrt(x)), where x != -infinity. 620 621define float @powf_libcall_half_ninf(float %x) { 622; ANY-LABEL: define float @powf_libcall_half_ninf( 623; ANY-SAME: float [[X:%.*]]) { 624; ANY-NEXT: [[SQRTF:%.*]] = call ninf float @sqrtf(float [[X]]) 625; ANY-NEXT: [[ABS:%.*]] = call ninf float @llvm.fabs.f32(float [[SQRTF]]) 626; ANY-NEXT: ret float [[ABS]] 627; 628; VC32-LABEL: define float @powf_libcall_half_ninf( 629; VC32-SAME: float [[X:%.*]]) { 630; VC32-NEXT: [[RETVAL:%.*]] = call ninf float @powf(float [[X]], float 5.000000e-01) 631; VC32-NEXT: ret float [[RETVAL]] 632; 633; VC51-LABEL: define float @powf_libcall_half_ninf( 634; VC51-SAME: float [[X:%.*]]) { 635; VC51-NEXT: [[RETVAL:%.*]] = call ninf float @powf(float [[X]], float 5.000000e-01) 636; VC51-NEXT: ret float [[RETVAL]] 637; 638; VC64-LABEL: define float @powf_libcall_half_ninf( 639; VC64-SAME: float [[X:%.*]]) { 640; VC64-NEXT: [[SQRTF:%.*]] = call ninf float @sqrtf(float [[X]]) 641; VC64-NEXT: [[ABS:%.*]] = call ninf float @llvm.fabs.f32(float [[SQRTF]]) 642; VC64-NEXT: ret float [[ABS]] 643; 644; VC83-LABEL: define float @powf_libcall_half_ninf( 645; VC83-SAME: float [[X:%.*]]) { 646; VC83-NEXT: [[SQRTF:%.*]] = call ninf float @sqrtf(float [[X]]) 647; VC83-NEXT: [[ABS:%.*]] = call ninf float @llvm.fabs.f32(float [[SQRTF]]) 648; VC83-NEXT: ret float [[ABS]] 649; 650; NOLIB-LABEL: define float @powf_libcall_half_ninf( 651; NOLIB-SAME: float [[X:%.*]]) { 652; NOLIB-NEXT: [[RETVAL:%.*]] = call ninf float @powf(float [[X]], float 5.000000e-01) 653; NOLIB-NEXT: ret float [[RETVAL]] 654; 655 %retval = call ninf float @powf(float %x, float 0.5) 656 ret float %retval 657} 658 659define float @powf_libcall_half_ninf_noerrno(float %x) { 660; ANY-LABEL: define float @powf_libcall_half_ninf_noerrno( 661; ANY-SAME: float [[X:%.*]]) { 662; ANY-NEXT: [[SQRT:%.*]] = call ninf float @llvm.sqrt.f32(float [[X]]) 663; ANY-NEXT: [[ABS:%.*]] = call ninf float @llvm.fabs.f32(float [[SQRT]]) 664; ANY-NEXT: ret float [[ABS]] 665; 666; VC32-LABEL: define float @powf_libcall_half_ninf_noerrno( 667; VC32-SAME: float [[X:%.*]]) { 668; VC32-NEXT: [[RETVAL:%.*]] = call ninf float @powf(float [[X]], float 5.000000e-01) #[[ATTR2]] 669; VC32-NEXT: ret float [[RETVAL]] 670; 671; VC51-LABEL: define float @powf_libcall_half_ninf_noerrno( 672; VC51-SAME: float [[X:%.*]]) { 673; VC51-NEXT: [[RETVAL:%.*]] = call ninf float @powf(float [[X]], float 5.000000e-01) #[[ATTR2]] 674; VC51-NEXT: ret float [[RETVAL]] 675; 676; VC64-LABEL: define float @powf_libcall_half_ninf_noerrno( 677; VC64-SAME: float [[X:%.*]]) { 678; VC64-NEXT: [[SQRT:%.*]] = call ninf float @llvm.sqrt.f32(float [[X]]) 679; VC64-NEXT: [[ABS:%.*]] = call ninf float @llvm.fabs.f32(float [[SQRT]]) 680; VC64-NEXT: ret float [[ABS]] 681; 682; VC83-LABEL: define float @powf_libcall_half_ninf_noerrno( 683; VC83-SAME: float [[X:%.*]]) { 684; VC83-NEXT: [[SQRT:%.*]] = call ninf float @llvm.sqrt.f32(float [[X]]) 685; VC83-NEXT: [[ABS:%.*]] = call ninf float @llvm.fabs.f32(float [[SQRT]]) 686; VC83-NEXT: ret float [[ABS]] 687; 688; NOLIB-LABEL: define float @powf_libcall_half_ninf_noerrno( 689; NOLIB-SAME: float [[X:%.*]]) { 690; NOLIB-NEXT: [[RETVAL:%.*]] = call ninf float @powf(float [[X]], float 5.000000e-01) #[[ATTR2]] 691; NOLIB-NEXT: ret float [[RETVAL]] 692; 693 %retval = call ninf float @powf(float %x, float 0.5) #0 694 ret float %retval 695} 696 697; Make sure assume works when inferring no infinities 698define float @powf_libcall_half_assume_ninf_noerrno(float %x) { 699; ANY-LABEL: define float @powf_libcall_half_assume_ninf_noerrno( 700; ANY-SAME: float [[X:%.*]]) { 701; ANY-NEXT: [[FABS:%.*]] = call float @llvm.fabs.f32(float [[X]]) 702; ANY-NEXT: [[NOT_INF:%.*]] = fcmp one float [[FABS]], 0x7FF0000000000000 703; ANY-NEXT: call void @llvm.assume(i1 [[NOT_INF]]) 704; ANY-NEXT: [[SQRT:%.*]] = call float @llvm.sqrt.f32(float [[X]]) 705; ANY-NEXT: [[ABS:%.*]] = call float @llvm.fabs.f32(float [[SQRT]]) 706; ANY-NEXT: ret float [[ABS]] 707; 708; VC32-LABEL: define float @powf_libcall_half_assume_ninf_noerrno( 709; VC32-SAME: float [[X:%.*]]) { 710; VC32-NEXT: [[FABS:%.*]] = call float @llvm.fabs.f32(float [[X]]) 711; VC32-NEXT: [[NOT_INF:%.*]] = fcmp one float [[FABS]], 0x7FF0000000000000 712; VC32-NEXT: call void @llvm.assume(i1 [[NOT_INF]]) 713; VC32-NEXT: [[RETVAL:%.*]] = call float @powf(float [[X]], float 5.000000e-01) #[[ATTR2]] 714; VC32-NEXT: ret float [[RETVAL]] 715; 716; VC51-LABEL: define float @powf_libcall_half_assume_ninf_noerrno( 717; VC51-SAME: float [[X:%.*]]) { 718; VC51-NEXT: [[FABS:%.*]] = call float @llvm.fabs.f32(float [[X]]) 719; VC51-NEXT: [[NOT_INF:%.*]] = fcmp one float [[FABS]], 0x7FF0000000000000 720; VC51-NEXT: call void @llvm.assume(i1 [[NOT_INF]]) 721; VC51-NEXT: [[RETVAL:%.*]] = call float @powf(float [[X]], float 5.000000e-01) #[[ATTR2]] 722; VC51-NEXT: ret float [[RETVAL]] 723; 724; VC64-LABEL: define float @powf_libcall_half_assume_ninf_noerrno( 725; VC64-SAME: float [[X:%.*]]) { 726; VC64-NEXT: [[FABS:%.*]] = call float @llvm.fabs.f32(float [[X]]) 727; VC64-NEXT: [[NOT_INF:%.*]] = fcmp one float [[FABS]], 0x7FF0000000000000 728; VC64-NEXT: call void @llvm.assume(i1 [[NOT_INF]]) 729; VC64-NEXT: [[SQRT:%.*]] = call float @llvm.sqrt.f32(float [[X]]) 730; VC64-NEXT: [[ABS:%.*]] = call float @llvm.fabs.f32(float [[SQRT]]) 731; VC64-NEXT: ret float [[ABS]] 732; 733; VC83-LABEL: define float @powf_libcall_half_assume_ninf_noerrno( 734; VC83-SAME: float [[X:%.*]]) { 735; VC83-NEXT: [[FABS:%.*]] = call float @llvm.fabs.f32(float [[X]]) 736; VC83-NEXT: [[NOT_INF:%.*]] = fcmp one float [[FABS]], 0x7FF0000000000000 737; VC83-NEXT: call void @llvm.assume(i1 [[NOT_INF]]) 738; VC83-NEXT: [[SQRT:%.*]] = call float @llvm.sqrt.f32(float [[X]]) 739; VC83-NEXT: [[ABS:%.*]] = call float @llvm.fabs.f32(float [[SQRT]]) 740; VC83-NEXT: ret float [[ABS]] 741; 742; NOLIB-LABEL: define float @powf_libcall_half_assume_ninf_noerrno( 743; NOLIB-SAME: float [[X:%.*]]) { 744; NOLIB-NEXT: [[FABS:%.*]] = call float @llvm.fabs.f32(float [[X]]) 745; NOLIB-NEXT: [[NOT_INF:%.*]] = fcmp one float [[FABS]], 0x7FF0000000000000 746; NOLIB-NEXT: call void @llvm.assume(i1 [[NOT_INF]]) 747; NOLIB-NEXT: [[RETVAL:%.*]] = call float @powf(float [[X]], float 5.000000e-01) #[[ATTR2]] 748; NOLIB-NEXT: ret float [[RETVAL]] 749; 750 %fabs = call float @llvm.fabs.f32(float %x) 751 %not.inf = fcmp one float %fabs, 0x7FF0000000000000 752 call void @llvm.assume(i1 %not.inf) 753 %retval = call float @powf(float %x, float 0.5) #0 754 ret float %retval 755} 756 757define float @powf_libcall_half_ninf_tail(float %x) { 758; ANY-LABEL: define float @powf_libcall_half_ninf_tail( 759; ANY-SAME: float [[X:%.*]]) { 760; ANY-NEXT: [[SQRTF:%.*]] = call ninf float @sqrtf(float [[X]]) 761; ANY-NEXT: [[ABS:%.*]] = tail call ninf float @llvm.fabs.f32(float [[SQRTF]]) 762; ANY-NEXT: ret float [[ABS]] 763; 764; VC32-LABEL: define float @powf_libcall_half_ninf_tail( 765; VC32-SAME: float [[X:%.*]]) { 766; VC32-NEXT: [[RETVAL:%.*]] = tail call ninf float @powf(float [[X]], float 5.000000e-01) 767; VC32-NEXT: ret float [[RETVAL]] 768; 769; VC51-LABEL: define float @powf_libcall_half_ninf_tail( 770; VC51-SAME: float [[X:%.*]]) { 771; VC51-NEXT: [[RETVAL:%.*]] = tail call ninf float @powf(float [[X]], float 5.000000e-01) 772; VC51-NEXT: ret float [[RETVAL]] 773; 774; VC64-LABEL: define float @powf_libcall_half_ninf_tail( 775; VC64-SAME: float [[X:%.*]]) { 776; VC64-NEXT: [[SQRTF:%.*]] = call ninf float @sqrtf(float [[X]]) 777; VC64-NEXT: [[ABS:%.*]] = tail call ninf float @llvm.fabs.f32(float [[SQRTF]]) 778; VC64-NEXT: ret float [[ABS]] 779; 780; VC83-LABEL: define float @powf_libcall_half_ninf_tail( 781; VC83-SAME: float [[X:%.*]]) { 782; VC83-NEXT: [[SQRTF:%.*]] = call ninf float @sqrtf(float [[X]]) 783; VC83-NEXT: [[ABS:%.*]] = tail call ninf float @llvm.fabs.f32(float [[SQRTF]]) 784; VC83-NEXT: ret float [[ABS]] 785; 786; NOLIB-LABEL: define float @powf_libcall_half_ninf_tail( 787; NOLIB-SAME: float [[X:%.*]]) { 788; NOLIB-NEXT: [[RETVAL:%.*]] = tail call ninf float @powf(float [[X]], float 5.000000e-01) 789; NOLIB-NEXT: ret float [[RETVAL]] 790; 791 %retval = tail call ninf float @powf(float %x, float 0.5) 792 ret float %retval 793} 794 795define float @powf_libcall_half_ninf_tail_noerrno(float %x) { 796; ANY-LABEL: define float @powf_libcall_half_ninf_tail_noerrno( 797; ANY-SAME: float [[X:%.*]]) { 798; ANY-NEXT: [[SQRT:%.*]] = call ninf float @llvm.sqrt.f32(float [[X]]) 799; ANY-NEXT: [[ABS:%.*]] = tail call ninf float @llvm.fabs.f32(float [[SQRT]]) 800; ANY-NEXT: ret float [[ABS]] 801; 802; VC32-LABEL: define float @powf_libcall_half_ninf_tail_noerrno( 803; VC32-SAME: float [[X:%.*]]) { 804; VC32-NEXT: [[RETVAL:%.*]] = tail call ninf float @powf(float [[X]], float 5.000000e-01) #[[ATTR2]] 805; VC32-NEXT: ret float [[RETVAL]] 806; 807; VC51-LABEL: define float @powf_libcall_half_ninf_tail_noerrno( 808; VC51-SAME: float [[X:%.*]]) { 809; VC51-NEXT: [[RETVAL:%.*]] = tail call ninf float @powf(float [[X]], float 5.000000e-01) #[[ATTR2]] 810; VC51-NEXT: ret float [[RETVAL]] 811; 812; VC64-LABEL: define float @powf_libcall_half_ninf_tail_noerrno( 813; VC64-SAME: float [[X:%.*]]) { 814; VC64-NEXT: [[SQRT:%.*]] = call ninf float @llvm.sqrt.f32(float [[X]]) 815; VC64-NEXT: [[ABS:%.*]] = tail call ninf float @llvm.fabs.f32(float [[SQRT]]) 816; VC64-NEXT: ret float [[ABS]] 817; 818; VC83-LABEL: define float @powf_libcall_half_ninf_tail_noerrno( 819; VC83-SAME: float [[X:%.*]]) { 820; VC83-NEXT: [[SQRT:%.*]] = call ninf float @llvm.sqrt.f32(float [[X]]) 821; VC83-NEXT: [[ABS:%.*]] = tail call ninf float @llvm.fabs.f32(float [[SQRT]]) 822; VC83-NEXT: ret float [[ABS]] 823; 824; NOLIB-LABEL: define float @powf_libcall_half_ninf_tail_noerrno( 825; NOLIB-SAME: float [[X:%.*]]) { 826; NOLIB-NEXT: [[RETVAL:%.*]] = tail call ninf float @powf(float [[X]], float 5.000000e-01) #[[ATTR2]] 827; NOLIB-NEXT: ret float [[RETVAL]] 828; 829 %retval = tail call ninf float @powf(float %x, float 0.5) #0 830 ret float %retval 831} 832 833define float @powf_libcall_half_ninf_musttail(float %x, float %y) { 834; CHECK-LABEL: define float @powf_libcall_half_ninf_musttail( 835; CHECK-SAME: float [[X:%.*]], float [[Y:%.*]]) { 836; CHECK-NEXT: [[RETVAL:%.*]] = musttail call ninf float @powf(float [[X]], float 5.000000e-01) 837; CHECK-NEXT: ret float [[RETVAL]] 838; 839 %retval = musttail call ninf float @powf(float %x, float 0.5) 840 ret float %retval 841} 842 843define float @powf_libcall_half_ninf_musttail_noerrno(float %x, float %y) { 844; CHECK-LABEL: define float @powf_libcall_half_ninf_musttail_noerrno( 845; CHECK-SAME: float [[X:%.*]], float [[Y:%.*]]) { 846; CHECK-NEXT: [[RETVAL:%.*]] = musttail call ninf float @powf(float [[X]], float 5.000000e-01) #[[ATTR2:[0-9]+]] 847; CHECK-NEXT: ret float [[RETVAL]] 848; 849 %retval = musttail call ninf float @powf(float %x, float 0.5) #0 850 ret float %retval 851} 852 853; Check pow(x, 0.5) where x may be -infinity does not call a library sqrt function. 854 855define double @pow_libcall_half_no_FMF(double %x) { 856; CHECK-LABEL: define double @pow_libcall_half_no_FMF( 857; CHECK-SAME: double [[X:%.*]]) { 858; CHECK-NEXT: [[RETVAL:%.*]] = call double @pow(double [[X]], double 5.000000e-01) 859; CHECK-NEXT: ret double [[RETVAL]] 860; 861 %retval = call double @pow(double %x, double 0.5) 862 ret double %retval 863} 864 865define double @pow_libcall_half_fromdomcondition(double %x) { 866; LIB-LABEL: define double @pow_libcall_half_fromdomcondition( 867; LIB-SAME: double [[X:%.*]]) { 868; LIB-NEXT: [[A:%.*]] = call double @llvm.fabs.f64(double [[X]]) 869; LIB-NEXT: [[C:%.*]] = fcmp oeq double [[A]], 0x7FF0000000000000 870; LIB-NEXT: br i1 [[C]], label [[THEN:%.*]], label [[ELSE:%.*]] 871; LIB: then: 872; LIB-NEXT: ret double 0.000000e+00 873; LIB: else: 874; LIB-NEXT: [[SQRT:%.*]] = call double @sqrt(double [[X]]) 875; LIB-NEXT: [[ABS:%.*]] = call double @llvm.fabs.f64(double [[SQRT]]) 876; LIB-NEXT: ret double [[ABS]] 877; 878; NOLIB-LABEL: define double @pow_libcall_half_fromdomcondition( 879; NOLIB-SAME: double [[X:%.*]]) { 880; NOLIB-NEXT: [[A:%.*]] = call double @llvm.fabs.f64(double [[X]]) 881; NOLIB-NEXT: [[C:%.*]] = fcmp oeq double [[A]], 0x7FF0000000000000 882; NOLIB-NEXT: br i1 [[C]], label [[THEN:%.*]], label [[ELSE:%.*]] 883; NOLIB: then: 884; NOLIB-NEXT: ret double 0.000000e+00 885; NOLIB: else: 886; NOLIB-NEXT: [[RETVAL:%.*]] = call double @pow(double [[X]], double 5.000000e-01) 887; NOLIB-NEXT: ret double [[RETVAL]] 888; 889 %a = call double @llvm.fabs.f64(double %x) 890 %c = fcmp oeq double %a, 0x7FF0000000000000 891 br i1 %c, label %then, label %else 892 893then: 894 ret double 0.0 895 896else: 897 %retval = call double @pow(double %x, double 0.5) 898 ret double %retval 899} 900 901define double @pow_libcall_half_no_FMF_noerrno(double %x) { 902; LIB-LABEL: define double @pow_libcall_half_no_FMF_noerrno( 903; LIB-SAME: double [[X:%.*]]) { 904; LIB-NEXT: [[SQRT:%.*]] = call double @llvm.sqrt.f64(double [[X]]) 905; LIB-NEXT: [[ABS:%.*]] = call double @llvm.fabs.f64(double [[SQRT]]) 906; LIB-NEXT: [[ISINF:%.*]] = fcmp oeq double [[X]], 0xFFF0000000000000 907; LIB-NEXT: [[RETVAL:%.*]] = select i1 [[ISINF]], double 0x7FF0000000000000, double [[ABS]] 908; LIB-NEXT: ret double [[RETVAL]] 909; 910; NOLIB-LABEL: define double @pow_libcall_half_no_FMF_noerrno( 911; NOLIB-SAME: double [[X:%.*]]) { 912; NOLIB-NEXT: [[RETVAL:%.*]] = call double @pow(double [[X]], double 5.000000e-01) #[[ATTR2]] 913; NOLIB-NEXT: ret double [[RETVAL]] 914; 915 %retval = call double @pow(double %x, double 0.5) #0 916 ret double %retval 917} 918 919; Check pow(-infinity, 0.5) -> +infinity. 920 921define float @test_simplify9(float %x) { 922; CHECK-LABEL: define float @test_simplify9( 923; CHECK-SAME: float [[X:%.*]]) { 924; CHECK-NEXT: ret float 0x7FF0000000000000 925; 926 %retval = call float @llvm.pow.f32(float 0xFFF0000000000000, float 0.5) 927 ret float %retval 928} 929 930define double @test_simplify10(double %x) { 931; CHECK-LABEL: define double @test_simplify10( 932; CHECK-SAME: double [[X:%.*]]) { 933; CHECK-NEXT: ret double 0x7FF0000000000000 934; 935 %retval = call double @llvm.pow.f64(double 0xFFF0000000000000, double 0.5) 936 ret double %retval 937} 938 939; Check pow(x, 1.0) -> x. 940 941define float @test_simplify11(float %x) { 942; ANY-LABEL: define float @test_simplify11( 943; ANY-SAME: float [[X:%.*]]) { 944; ANY-NEXT: ret float [[X]] 945; 946; VC32-LABEL: define float @test_simplify11( 947; VC32-SAME: float [[X:%.*]]) { 948; VC32-NEXT: [[RETVAL:%.*]] = call float @powf(float [[X]], float 1.000000e+00) 949; VC32-NEXT: ret float [[RETVAL]] 950; 951; VC51-LABEL: define float @test_simplify11( 952; VC51-SAME: float [[X:%.*]]) { 953; VC51-NEXT: [[RETVAL:%.*]] = call float @powf(float [[X]], float 1.000000e+00) 954; VC51-NEXT: ret float [[RETVAL]] 955; 956; VC64-LABEL: define float @test_simplify11( 957; VC64-SAME: float [[X:%.*]]) { 958; VC64-NEXT: ret float [[X]] 959; 960; VC83-LABEL: define float @test_simplify11( 961; VC83-SAME: float [[X:%.*]]) { 962; VC83-NEXT: ret float [[X]] 963; 964; NOLIB-LABEL: define float @test_simplify11( 965; NOLIB-SAME: float [[X:%.*]]) { 966; NOLIB-NEXT: [[RETVAL:%.*]] = call float @powf(float [[X]], float 1.000000e+00) 967; NOLIB-NEXT: ret float [[RETVAL]] 968; 969 %retval = call float @powf(float %x, float 1.0) 970 ret float %retval 971} 972 973define float @test_simplify11_noerrno(float %x) { 974; ANY-LABEL: define float @test_simplify11_noerrno( 975; ANY-SAME: float [[X:%.*]]) { 976; ANY-NEXT: ret float [[X]] 977; 978; VC32-LABEL: define float @test_simplify11_noerrno( 979; VC32-SAME: float [[X:%.*]]) { 980; VC32-NEXT: [[RETVAL:%.*]] = call float @powf(float [[X]], float 1.000000e+00) #[[ATTR2]] 981; VC32-NEXT: ret float [[RETVAL]] 982; 983; VC51-LABEL: define float @test_simplify11_noerrno( 984; VC51-SAME: float [[X:%.*]]) { 985; VC51-NEXT: [[RETVAL:%.*]] = call float @powf(float [[X]], float 1.000000e+00) #[[ATTR2]] 986; VC51-NEXT: ret float [[RETVAL]] 987; 988; VC64-LABEL: define float @test_simplify11_noerrno( 989; VC64-SAME: float [[X:%.*]]) { 990; VC64-NEXT: ret float [[X]] 991; 992; VC83-LABEL: define float @test_simplify11_noerrno( 993; VC83-SAME: float [[X:%.*]]) { 994; VC83-NEXT: ret float [[X]] 995; 996; NOLIB-LABEL: define float @test_simplify11_noerrno( 997; NOLIB-SAME: float [[X:%.*]]) { 998; NOLIB-NEXT: [[RETVAL:%.*]] = call float @powf(float [[X]], float 1.000000e+00) #[[ATTR2]] 999; NOLIB-NEXT: ret float [[RETVAL]] 1000; 1001 %retval = call float @powf(float %x, float 1.0) #0 1002 ret float %retval 1003} 1004 1005define <2 x float> @test_simplify11v(<2 x float> %x) { 1006; CHECK-LABEL: define <2 x float> @test_simplify11v( 1007; CHECK-SAME: <2 x float> [[X:%.*]]) { 1008; CHECK-NEXT: ret <2 x float> [[X]] 1009; 1010 %retval = call <2 x float> @llvm.pow.v2f32(<2 x float> %x, <2 x float> <float 1.0, float 1.0>) 1011 ret <2 x float> %retval 1012} 1013 1014define double @test_simplify12(double %x) { 1015; LIB-LABEL: define double @test_simplify12( 1016; LIB-SAME: double [[X:%.*]]) { 1017; LIB-NEXT: ret double [[X]] 1018; 1019; NOLIB-LABEL: define double @test_simplify12( 1020; NOLIB-SAME: double [[X:%.*]]) { 1021; NOLIB-NEXT: [[RETVAL:%.*]] = call double @pow(double [[X]], double 1.000000e+00) 1022; NOLIB-NEXT: ret double [[RETVAL]] 1023; 1024 %retval = call double @pow(double %x, double 1.0) 1025 ret double %retval 1026} 1027 1028define double @test_simplify12_noerrno(double %x) { 1029; LIB-LABEL: define double @test_simplify12_noerrno( 1030; LIB-SAME: double [[X:%.*]]) { 1031; LIB-NEXT: ret double [[X]] 1032; 1033; NOLIB-LABEL: define double @test_simplify12_noerrno( 1034; NOLIB-SAME: double [[X:%.*]]) { 1035; NOLIB-NEXT: [[RETVAL:%.*]] = call double @pow(double [[X]], double 1.000000e+00) #[[ATTR2]] 1036; NOLIB-NEXT: ret double [[RETVAL]] 1037; 1038 %retval = call double @pow(double %x, double 1.0) #0 1039 ret double %retval 1040} 1041 1042define <2 x double> @test_simplify12v(<2 x double> %x) { 1043; CHECK-LABEL: define <2 x double> @test_simplify12v( 1044; CHECK-SAME: <2 x double> [[X:%.*]]) { 1045; CHECK-NEXT: ret <2 x double> [[X]] 1046; 1047 %retval = call <2 x double> @llvm.pow.v2f64(<2 x double> %x, <2 x double> <double 1.0, double 1.0>) 1048 ret <2 x double> %retval 1049} 1050 1051; Check pow(x, 2.0) -> x*x. 1052 1053define float @pow2_strict(float %x) { 1054; ANY-LABEL: define float @pow2_strict( 1055; ANY-SAME: float [[X:%.*]]) { 1056; ANY-NEXT: [[SQUARE:%.*]] = fmul float [[X]], [[X]] 1057; ANY-NEXT: ret float [[SQUARE]] 1058; 1059; VC32-LABEL: define float @pow2_strict( 1060; VC32-SAME: float [[X:%.*]]) { 1061; VC32-NEXT: [[R:%.*]] = call float @powf(float [[X]], float 2.000000e+00) 1062; VC32-NEXT: ret float [[R]] 1063; 1064; VC51-LABEL: define float @pow2_strict( 1065; VC51-SAME: float [[X:%.*]]) { 1066; VC51-NEXT: [[R:%.*]] = call float @powf(float [[X]], float 2.000000e+00) 1067; VC51-NEXT: ret float [[R]] 1068; 1069; VC64-LABEL: define float @pow2_strict( 1070; VC64-SAME: float [[X:%.*]]) { 1071; VC64-NEXT: [[SQUARE:%.*]] = fmul float [[X]], [[X]] 1072; VC64-NEXT: ret float [[SQUARE]] 1073; 1074; VC83-LABEL: define float @pow2_strict( 1075; VC83-SAME: float [[X:%.*]]) { 1076; VC83-NEXT: [[SQUARE:%.*]] = fmul float [[X]], [[X]] 1077; VC83-NEXT: ret float [[SQUARE]] 1078; 1079; NOLIB-LABEL: define float @pow2_strict( 1080; NOLIB-SAME: float [[X:%.*]]) { 1081; NOLIB-NEXT: [[R:%.*]] = call float @powf(float [[X]], float 2.000000e+00) 1082; NOLIB-NEXT: ret float [[R]] 1083; 1084 %r = call float @powf(float %x, float 2.0) 1085 ret float %r 1086} 1087 1088define float @pow2_strict_noerrno(float %x) { 1089; ANY-LABEL: define float @pow2_strict_noerrno( 1090; ANY-SAME: float [[X:%.*]]) { 1091; ANY-NEXT: [[SQUARE:%.*]] = fmul float [[X]], [[X]] 1092; ANY-NEXT: ret float [[SQUARE]] 1093; 1094; VC32-LABEL: define float @pow2_strict_noerrno( 1095; VC32-SAME: float [[X:%.*]]) { 1096; VC32-NEXT: [[R:%.*]] = call float @powf(float [[X]], float 2.000000e+00) #[[ATTR2]] 1097; VC32-NEXT: ret float [[R]] 1098; 1099; VC51-LABEL: define float @pow2_strict_noerrno( 1100; VC51-SAME: float [[X:%.*]]) { 1101; VC51-NEXT: [[R:%.*]] = call float @powf(float [[X]], float 2.000000e+00) #[[ATTR2]] 1102; VC51-NEXT: ret float [[R]] 1103; 1104; VC64-LABEL: define float @pow2_strict_noerrno( 1105; VC64-SAME: float [[X:%.*]]) { 1106; VC64-NEXT: [[SQUARE:%.*]] = fmul float [[X]], [[X]] 1107; VC64-NEXT: ret float [[SQUARE]] 1108; 1109; VC83-LABEL: define float @pow2_strict_noerrno( 1110; VC83-SAME: float [[X:%.*]]) { 1111; VC83-NEXT: [[SQUARE:%.*]] = fmul float [[X]], [[X]] 1112; VC83-NEXT: ret float [[SQUARE]] 1113; 1114; NOLIB-LABEL: define float @pow2_strict_noerrno( 1115; NOLIB-SAME: float [[X:%.*]]) { 1116; NOLIB-NEXT: [[R:%.*]] = call float @powf(float [[X]], float 2.000000e+00) #[[ATTR2]] 1117; NOLIB-NEXT: ret float [[R]] 1118; 1119 %r = call float @powf(float %x, float 2.0) #0 1120 ret float %r 1121} 1122 1123define <2 x float> @pow2_strictv(<2 x float> %x) { 1124; CHECK-LABEL: define <2 x float> @pow2_strictv( 1125; CHECK-SAME: <2 x float> [[X:%.*]]) { 1126; CHECK-NEXT: [[SQUARE:%.*]] = fmul <2 x float> [[X]], [[X]] 1127; CHECK-NEXT: ret <2 x float> [[SQUARE]] 1128; 1129 %r = call <2 x float> @llvm.pow.v2f32(<2 x float> %x, <2 x float> <float 2.0, float 2.0>) 1130 ret <2 x float> %r 1131} 1132 1133define double @pow2_double_strict(double %x) { 1134; LIB-LABEL: define double @pow2_double_strict( 1135; LIB-SAME: double [[X:%.*]]) { 1136; LIB-NEXT: [[SQUARE:%.*]] = fmul double [[X]], [[X]] 1137; LIB-NEXT: ret double [[SQUARE]] 1138; 1139; NOLIB-LABEL: define double @pow2_double_strict( 1140; NOLIB-SAME: double [[X:%.*]]) { 1141; NOLIB-NEXT: [[R:%.*]] = call double @pow(double [[X]], double 2.000000e+00) 1142; NOLIB-NEXT: ret double [[R]] 1143; 1144 %r = call double @pow(double %x, double 2.0) 1145 ret double %r 1146} 1147 1148define double @pow2_double_strict_noerrno(double %x) { 1149; LIB-LABEL: define double @pow2_double_strict_noerrno( 1150; LIB-SAME: double [[X:%.*]]) { 1151; LIB-NEXT: [[SQUARE:%.*]] = fmul double [[X]], [[X]] 1152; LIB-NEXT: ret double [[SQUARE]] 1153; 1154; NOLIB-LABEL: define double @pow2_double_strict_noerrno( 1155; NOLIB-SAME: double [[X:%.*]]) { 1156; NOLIB-NEXT: [[R:%.*]] = call double @pow(double [[X]], double 2.000000e+00) #[[ATTR2]] 1157; NOLIB-NEXT: ret double [[R]] 1158; 1159 %r = call double @pow(double %x, double 2.0) #0 1160 ret double %r 1161} 1162 1163define <2 x double> @pow2_double_strictv(<2 x double> %x) { 1164; CHECK-LABEL: define <2 x double> @pow2_double_strictv( 1165; CHECK-SAME: <2 x double> [[X:%.*]]) { 1166; CHECK-NEXT: [[SQUARE:%.*]] = fmul <2 x double> [[X]], [[X]] 1167; CHECK-NEXT: ret <2 x double> [[SQUARE]] 1168; 1169 %r = call <2 x double> @llvm.pow.v2f64(<2 x double> %x, <2 x double> <double 2.0, double 2.0>) 1170 ret <2 x double> %r 1171} 1172 1173; Don't drop the FMF - PR35601 ( https://bugs.llvm.org/show_bug.cgi?id=35601 ) 1174 1175define float @pow2_fast(float %x) { 1176; ANY-LABEL: define float @pow2_fast( 1177; ANY-SAME: float [[X:%.*]]) { 1178; ANY-NEXT: [[SQUARE:%.*]] = fmul fast float [[X]], [[X]] 1179; ANY-NEXT: ret float [[SQUARE]] 1180; 1181; VC32-LABEL: define float @pow2_fast( 1182; VC32-SAME: float [[X:%.*]]) { 1183; VC32-NEXT: [[R:%.*]] = call fast float @powf(float [[X]], float 2.000000e+00) 1184; VC32-NEXT: ret float [[R]] 1185; 1186; VC51-LABEL: define float @pow2_fast( 1187; VC51-SAME: float [[X:%.*]]) { 1188; VC51-NEXT: [[R:%.*]] = call fast float @powf(float [[X]], float 2.000000e+00) 1189; VC51-NEXT: ret float [[R]] 1190; 1191; VC64-LABEL: define float @pow2_fast( 1192; VC64-SAME: float [[X:%.*]]) { 1193; VC64-NEXT: [[SQUARE:%.*]] = fmul fast float [[X]], [[X]] 1194; VC64-NEXT: ret float [[SQUARE]] 1195; 1196; VC83-LABEL: define float @pow2_fast( 1197; VC83-SAME: float [[X:%.*]]) { 1198; VC83-NEXT: [[SQUARE:%.*]] = fmul fast float [[X]], [[X]] 1199; VC83-NEXT: ret float [[SQUARE]] 1200; 1201; NOLIB-LABEL: define float @pow2_fast( 1202; NOLIB-SAME: float [[X:%.*]]) { 1203; NOLIB-NEXT: [[R:%.*]] = call fast float @powf(float [[X]], float 2.000000e+00) 1204; NOLIB-NEXT: ret float [[R]] 1205; 1206 %r = call fast float @powf(float %x, float 2.0) 1207 ret float %r 1208} 1209 1210define float @pow2_fast_noerrno(float %x) { 1211; ANY-LABEL: define float @pow2_fast_noerrno( 1212; ANY-SAME: float [[X:%.*]]) { 1213; ANY-NEXT: [[SQUARE:%.*]] = fmul fast float [[X]], [[X]] 1214; ANY-NEXT: ret float [[SQUARE]] 1215; 1216; VC32-LABEL: define float @pow2_fast_noerrno( 1217; VC32-SAME: float [[X:%.*]]) { 1218; VC32-NEXT: [[R:%.*]] = call fast float @powf(float [[X]], float 2.000000e+00) #[[ATTR2]] 1219; VC32-NEXT: ret float [[R]] 1220; 1221; VC51-LABEL: define float @pow2_fast_noerrno( 1222; VC51-SAME: float [[X:%.*]]) { 1223; VC51-NEXT: [[R:%.*]] = call fast float @powf(float [[X]], float 2.000000e+00) #[[ATTR2]] 1224; VC51-NEXT: ret float [[R]] 1225; 1226; VC64-LABEL: define float @pow2_fast_noerrno( 1227; VC64-SAME: float [[X:%.*]]) { 1228; VC64-NEXT: [[SQUARE:%.*]] = fmul fast float [[X]], [[X]] 1229; VC64-NEXT: ret float [[SQUARE]] 1230; 1231; VC83-LABEL: define float @pow2_fast_noerrno( 1232; VC83-SAME: float [[X:%.*]]) { 1233; VC83-NEXT: [[SQUARE:%.*]] = fmul fast float [[X]], [[X]] 1234; VC83-NEXT: ret float [[SQUARE]] 1235; 1236; NOLIB-LABEL: define float @pow2_fast_noerrno( 1237; NOLIB-SAME: float [[X:%.*]]) { 1238; NOLIB-NEXT: [[R:%.*]] = call fast float @powf(float [[X]], float 2.000000e+00) #[[ATTR2]] 1239; NOLIB-NEXT: ret float [[R]] 1240; 1241 %r = call fast float @powf(float %x, float 2.0) #0 1242 ret float %r 1243} 1244 1245; Check pow(x, -1.0) -> 1.0/x. 1246 1247define float @pow_neg1_strict(float %x) { 1248; ANY-LABEL: define float @pow_neg1_strict( 1249; ANY-SAME: float [[X:%.*]]) { 1250; ANY-NEXT: [[RECIPROCAL:%.*]] = fdiv float 1.000000e+00, [[X]] 1251; ANY-NEXT: ret float [[RECIPROCAL]] 1252; 1253; VC32-LABEL: define float @pow_neg1_strict( 1254; VC32-SAME: float [[X:%.*]]) { 1255; VC32-NEXT: [[R:%.*]] = call float @powf(float [[X]], float -1.000000e+00) 1256; VC32-NEXT: ret float [[R]] 1257; 1258; VC51-LABEL: define float @pow_neg1_strict( 1259; VC51-SAME: float [[X:%.*]]) { 1260; VC51-NEXT: [[R:%.*]] = call float @powf(float [[X]], float -1.000000e+00) 1261; VC51-NEXT: ret float [[R]] 1262; 1263; VC64-LABEL: define float @pow_neg1_strict( 1264; VC64-SAME: float [[X:%.*]]) { 1265; VC64-NEXT: [[RECIPROCAL:%.*]] = fdiv float 1.000000e+00, [[X]] 1266; VC64-NEXT: ret float [[RECIPROCAL]] 1267; 1268; VC83-LABEL: define float @pow_neg1_strict( 1269; VC83-SAME: float [[X:%.*]]) { 1270; VC83-NEXT: [[RECIPROCAL:%.*]] = fdiv float 1.000000e+00, [[X]] 1271; VC83-NEXT: ret float [[RECIPROCAL]] 1272; 1273; NOLIB-LABEL: define float @pow_neg1_strict( 1274; NOLIB-SAME: float [[X:%.*]]) { 1275; NOLIB-NEXT: [[R:%.*]] = call float @powf(float [[X]], float -1.000000e+00) 1276; NOLIB-NEXT: ret float [[R]] 1277; 1278 %r = call float @powf(float %x, float -1.0) 1279 ret float %r 1280} 1281 1282define float @pow_neg1_strict_noerrno(float %x) { 1283; ANY-LABEL: define float @pow_neg1_strict_noerrno( 1284; ANY-SAME: float [[X:%.*]]) { 1285; ANY-NEXT: [[RECIPROCAL:%.*]] = fdiv float 1.000000e+00, [[X]] 1286; ANY-NEXT: ret float [[RECIPROCAL]] 1287; 1288; VC32-LABEL: define float @pow_neg1_strict_noerrno( 1289; VC32-SAME: float [[X:%.*]]) { 1290; VC32-NEXT: [[R:%.*]] = call float @powf(float [[X]], float -1.000000e+00) #[[ATTR2]] 1291; VC32-NEXT: ret float [[R]] 1292; 1293; VC51-LABEL: define float @pow_neg1_strict_noerrno( 1294; VC51-SAME: float [[X:%.*]]) { 1295; VC51-NEXT: [[R:%.*]] = call float @powf(float [[X]], float -1.000000e+00) #[[ATTR2]] 1296; VC51-NEXT: ret float [[R]] 1297; 1298; VC64-LABEL: define float @pow_neg1_strict_noerrno( 1299; VC64-SAME: float [[X:%.*]]) { 1300; VC64-NEXT: [[RECIPROCAL:%.*]] = fdiv float 1.000000e+00, [[X]] 1301; VC64-NEXT: ret float [[RECIPROCAL]] 1302; 1303; VC83-LABEL: define float @pow_neg1_strict_noerrno( 1304; VC83-SAME: float [[X:%.*]]) { 1305; VC83-NEXT: [[RECIPROCAL:%.*]] = fdiv float 1.000000e+00, [[X]] 1306; VC83-NEXT: ret float [[RECIPROCAL]] 1307; 1308; NOLIB-LABEL: define float @pow_neg1_strict_noerrno( 1309; NOLIB-SAME: float [[X:%.*]]) { 1310; NOLIB-NEXT: [[R:%.*]] = call float @powf(float [[X]], float -1.000000e+00) #[[ATTR2]] 1311; NOLIB-NEXT: ret float [[R]] 1312; 1313 %r = call float @powf(float %x, float -1.0) #0 1314 ret float %r 1315} 1316 1317define <2 x float> @pow_neg1_strictv(<2 x float> %x) { 1318; CHECK-LABEL: define <2 x float> @pow_neg1_strictv( 1319; CHECK-SAME: <2 x float> [[X:%.*]]) { 1320; CHECK-NEXT: [[RECIPROCAL:%.*]] = fdiv <2 x float> splat (float 1.000000e+00), [[X]] 1321; CHECK-NEXT: ret <2 x float> [[RECIPROCAL]] 1322; 1323 %r = call <2 x float> @llvm.pow.v2f32(<2 x float> %x, <2 x float> <float -1.0, float -1.0>) 1324 ret <2 x float> %r 1325} 1326 1327define double @pow_neg1_double_fast(double %x) { 1328; LIB-LABEL: define double @pow_neg1_double_fast( 1329; LIB-SAME: double [[X:%.*]]) { 1330; LIB-NEXT: [[RECIPROCAL:%.*]] = fdiv fast double 1.000000e+00, [[X]] 1331; LIB-NEXT: ret double [[RECIPROCAL]] 1332; 1333; NOLIB-LABEL: define double @pow_neg1_double_fast( 1334; NOLIB-SAME: double [[X:%.*]]) { 1335; NOLIB-NEXT: [[R:%.*]] = call fast double @pow(double [[X]], double -1.000000e+00) 1336; NOLIB-NEXT: ret double [[R]] 1337; 1338 %r = call fast double @pow(double %x, double -1.0) 1339 ret double %r 1340} 1341 1342define double @pow_neg1_double_fast_noerrno(double %x) { 1343; LIB-LABEL: define double @pow_neg1_double_fast_noerrno( 1344; LIB-SAME: double [[X:%.*]]) { 1345; LIB-NEXT: [[RECIPROCAL:%.*]] = fdiv fast double 1.000000e+00, [[X]] 1346; LIB-NEXT: ret double [[RECIPROCAL]] 1347; 1348; NOLIB-LABEL: define double @pow_neg1_double_fast_noerrno( 1349; NOLIB-SAME: double [[X:%.*]]) { 1350; NOLIB-NEXT: [[R:%.*]] = call fast double @pow(double [[X]], double -1.000000e+00) #[[ATTR2]] 1351; NOLIB-NEXT: ret double [[R]] 1352; 1353 %r = call fast double @pow(double %x, double -1.0) #0 1354 ret double %r 1355} 1356 1357define <2 x double> @pow_neg1_double_fastv(<2 x double> %x) { 1358; CHECK-LABEL: define <2 x double> @pow_neg1_double_fastv( 1359; CHECK-SAME: <2 x double> [[X:%.*]]) { 1360; CHECK-NEXT: [[RECIPROCAL:%.*]] = fdiv fast <2 x double> splat (double 1.000000e+00), [[X]] 1361; CHECK-NEXT: ret <2 x double> [[RECIPROCAL]] 1362; 1363 %r = call fast <2 x double> @llvm.pow.v2f64(<2 x double> %x, <2 x double> <double -1.0, double -1.0>) 1364 ret <2 x double> %r 1365} 1366 1367define double @pow_intrinsic_half_no_FMF(double %x) { 1368; CHECK-LABEL: define double @pow_intrinsic_half_no_FMF( 1369; CHECK-SAME: double [[X:%.*]]) { 1370; CHECK-NEXT: [[SQRT:%.*]] = call double @llvm.sqrt.f64(double [[X]]) 1371; CHECK-NEXT: [[ABS:%.*]] = call double @llvm.fabs.f64(double [[SQRT]]) 1372; CHECK-NEXT: [[ISINF:%.*]] = fcmp oeq double [[X]], 0xFFF0000000000000 1373; CHECK-NEXT: [[RETVAL:%.*]] = select i1 [[ISINF]], double 0x7FF0000000000000, double [[ABS]] 1374; CHECK-NEXT: ret double [[RETVAL]] 1375; 1376 %retval = call double @llvm.pow.f64(double %x, double 0.5) 1377 ret double %retval 1378} 1379 1380; Check pow(10.0, x) -> __exp10(x) on OS X 10.9+ and iOS 7.0+. 1381 1382define float @test_simplify18(float %x) { 1383; CHECK-EXP10-LABEL: define float @test_simplify18( 1384; CHECK-EXP10-SAME: float [[X:%.*]]) { 1385; CHECK-EXP10-NEXT: [[__EXP10F:%.*]] = call float @__exp10f(float [[X]]) 1386; CHECK-EXP10-NEXT: ret float [[__EXP10F]] 1387; 1388; CHECK-NO-EXP10-LABEL: define float @test_simplify18( 1389; CHECK-NO-EXP10-SAME: float [[X:%.*]]) { 1390; CHECK-NO-EXP10-NEXT: [[RETVAL:%.*]] = call float @powf(float 1.000000e+01, float [[X]]) 1391; CHECK-NO-EXP10-NEXT: ret float [[RETVAL]] 1392; 1393 %retval = call float @powf(float 10.0, float %x) 1394 ret float %retval 1395} 1396 1397define float @test_simplify18_noerrno(float %x) { 1398; CHECK-EXP10-LABEL: define float @test_simplify18_noerrno( 1399; CHECK-EXP10-SAME: float [[X:%.*]]) { 1400; CHECK-EXP10-NEXT: [[EXP10:%.*]] = call float @llvm.exp10.f32(float [[X]]) 1401; CHECK-EXP10-NEXT: ret float [[EXP10]] 1402; 1403; CHECK-NO-EXP10-LABEL: define float @test_simplify18_noerrno( 1404; CHECK-NO-EXP10-SAME: float [[X:%.*]]) { 1405; CHECK-NO-EXP10-NEXT: [[RETVAL:%.*]] = call float @powf(float 1.000000e+01, float [[X]]) #[[ATTR2]] 1406; CHECK-NO-EXP10-NEXT: ret float [[RETVAL]] 1407; 1408 %retval = call float @powf(float 10.0, float %x) #0 1409 ret float %retval 1410} 1411 1412define double @test_simplify19(double %x) { 1413; CHECK-EXP10-LABEL: define double @test_simplify19( 1414; CHECK-EXP10-SAME: double [[X:%.*]]) { 1415; CHECK-EXP10-NEXT: [[__EXP10:%.*]] = call double @__exp10(double [[X]]) 1416; CHECK-EXP10-NEXT: ret double [[__EXP10]] 1417; 1418; CHECK-NO-EXP10-LABEL: define double @test_simplify19( 1419; CHECK-NO-EXP10-SAME: double [[X:%.*]]) { 1420; CHECK-NO-EXP10-NEXT: [[RETVAL:%.*]] = call double @pow(double 1.000000e+01, double [[X]]) 1421; CHECK-NO-EXP10-NEXT: ret double [[RETVAL]] 1422; 1423 %retval = call double @pow(double 10.0, double %x) 1424 ret double %retval 1425} 1426 1427define double @test_simplify19_noerrno(double %x) { 1428; CHECK-EXP10-LABEL: define double @test_simplify19_noerrno( 1429; CHECK-EXP10-SAME: double [[X:%.*]]) { 1430; CHECK-EXP10-NEXT: [[EXP10:%.*]] = call double @llvm.exp10.f64(double [[X]]) 1431; CHECK-EXP10-NEXT: ret double [[EXP10]] 1432; 1433; CHECK-NO-EXP10-LABEL: define double @test_simplify19_noerrno( 1434; CHECK-NO-EXP10-SAME: double [[X:%.*]]) { 1435; CHECK-NO-EXP10-NEXT: [[RETVAL:%.*]] = call double @pow(double 1.000000e+01, double [[X]]) #[[ATTR2]] 1436; CHECK-NO-EXP10-NEXT: ret double [[RETVAL]] 1437; 1438 %retval = call double @pow(double 10.0, double %x) #0 1439 ret double %retval 1440} 1441 1442define float @test_libcall_powf_10_f32_noerrno(float %x) { 1443; CHECK-EXP10-LABEL: define float @test_libcall_powf_10_f32_noerrno( 1444; CHECK-EXP10-SAME: float [[X:%.*]]) { 1445; CHECK-EXP10-NEXT: [[__EXP10F:%.*]] = call float @llvm.exp10.f32(float [[X]]) 1446; CHECK-EXP10-NEXT: ret float [[__EXP10F]] 1447; 1448; CHECK-NO-EXP10-LABEL: define float @test_libcall_powf_10_f32_noerrno( 1449; CHECK-NO-EXP10-SAME: float [[X:%.*]]) { 1450; CHECK-NO-EXP10-NEXT: [[RETVAL:%.*]] = call float @powf(float 1.000000e+01, float [[X]]) #[[ATTR2]] 1451; CHECK-NO-EXP10-NEXT: ret float [[RETVAL]] 1452; 1453 %retval = call float @powf(float 10.0, float %x) #0 1454 ret float %retval 1455} 1456 1457define double @test_libcall_pow_10_f64_noerrno(double %x) { 1458; CHECK-EXP10-LABEL: define double @test_libcall_pow_10_f64_noerrno( 1459; CHECK-EXP10-SAME: double [[X:%.*]]) { 1460; CHECK-EXP10-NEXT: [[__EXP10:%.*]] = call double @llvm.exp10.f64(double [[X]]) 1461; CHECK-EXP10-NEXT: ret double [[__EXP10]] 1462; 1463; CHECK-NO-EXP10-LABEL: define double @test_libcall_pow_10_f64_noerrno( 1464; CHECK-NO-EXP10-SAME: double [[X:%.*]]) { 1465; CHECK-NO-EXP10-NEXT: [[RETVAL:%.*]] = call double @pow(double 1.000000e+01, double [[X]]) #[[ATTR2]] 1466; CHECK-NO-EXP10-NEXT: ret double [[RETVAL]] 1467; 1468 %retval = call double @pow(double 10.0, double %x) #0 1469 ret double %retval 1470} 1471 1472define half @test_pow_10_f16(half %x) { 1473; CHECK-LABEL: define half @test_pow_10_f16( 1474; CHECK-SAME: half [[X:%.*]]) { 1475; CHECK-NEXT: [[RETVAL:%.*]] = call half @llvm.pow.f16(half 0xH4900, half [[X]]) 1476; CHECK-NEXT: ret half [[RETVAL]] 1477; 1478 %retval = call half @llvm.pow.f16(half 10.0, half %x) 1479 ret half %retval 1480} 1481 1482define float @test_pow_10_f32(float %x) { 1483; CHECK-EXP10-LABEL: define float @test_pow_10_f32( 1484; CHECK-EXP10-SAME: float [[X:%.*]]) { 1485; CHECK-EXP10-NEXT: [[__EXP10F:%.*]] = call float @llvm.exp10.f32(float [[X]]) 1486; CHECK-EXP10-NEXT: ret float [[__EXP10F]] 1487; 1488; CHECK-NO-EXP10-LABEL: define float @test_pow_10_f32( 1489; CHECK-NO-EXP10-SAME: float [[X:%.*]]) { 1490; CHECK-NO-EXP10-NEXT: [[RETVAL:%.*]] = call float @llvm.pow.f32(float 1.000000e+01, float [[X]]) 1491; CHECK-NO-EXP10-NEXT: ret float [[RETVAL]] 1492; 1493 %retval = call float @llvm.pow.f32(float 10.0, float %x) 1494 ret float %retval 1495} 1496 1497define double @test_pow_10_f64(double %x) { 1498; CHECK-EXP10-LABEL: define double @test_pow_10_f64( 1499; CHECK-EXP10-SAME: double [[X:%.*]]) { 1500; CHECK-EXP10-NEXT: [[__EXP10:%.*]] = call double @llvm.exp10.f64(double [[X]]) 1501; CHECK-EXP10-NEXT: ret double [[__EXP10]] 1502; 1503; CHECK-NO-EXP10-LABEL: define double @test_pow_10_f64( 1504; CHECK-NO-EXP10-SAME: double [[X:%.*]]) { 1505; CHECK-NO-EXP10-NEXT: [[RETVAL:%.*]] = call double @llvm.pow.f64(double 1.000000e+01, double [[X]]) 1506; CHECK-NO-EXP10-NEXT: ret double [[RETVAL]] 1507; 1508 %retval = call double @llvm.pow.f64(double 10.0, double %x) 1509 ret double %retval 1510} 1511 1512define fp128 @test_pow_10_fp128(fp128 %x) { 1513; CHECK-LABEL: define fp128 @test_pow_10_fp128( 1514; CHECK-SAME: fp128 [[X:%.*]]) { 1515; CHECK-NEXT: [[RETVAL:%.*]] = call fp128 @llvm.pow.f128(fp128 0xL00000000000000004002400000000000, fp128 [[X]]) 1516; CHECK-NEXT: ret fp128 [[RETVAL]] 1517; 1518 %ten = fpext double 10.0 to fp128 1519 %retval = call fp128 @llvm.pow.fp128(fp128 %ten, fp128 %x) 1520 ret fp128 %retval 1521} 1522 1523define bfloat @test_pow_10_bf16(bfloat %x) { 1524; CHECK-LABEL: define bfloat @test_pow_10_bf16( 1525; CHECK-SAME: bfloat [[X:%.*]]) { 1526; CHECK-NEXT: [[RETVAL:%.*]] = call bfloat @llvm.pow.bf16(bfloat 0xR4120, bfloat [[X]]) 1527; CHECK-NEXT: ret bfloat [[RETVAL]] 1528; 1529 %retval = call bfloat @llvm.pow.bf16(bfloat 10.0, bfloat %x) 1530 ret bfloat %retval 1531} 1532 1533define <2 x half> @test_pow_10_v2f16(<2 x half> %x) { 1534; CHECK-LABEL: define <2 x half> @test_pow_10_v2f16( 1535; CHECK-SAME: <2 x half> [[X:%.*]]) { 1536; CHECK-NEXT: [[RETVAL:%.*]] = call <2 x half> @llvm.pow.v2f16(<2 x half> splat (half 0xH4900), <2 x half> [[X]]) 1537; CHECK-NEXT: ret <2 x half> [[RETVAL]] 1538; 1539 %retval = call <2 x half> @llvm.pow.v2f16(<2 x half> <half 10.0, half 10.0>, <2 x half> %x) 1540 ret <2 x half> %retval 1541} 1542 1543define <2 x float> @test_pow_10_v2f32(<2 x float> %x) { 1544; CHECK-LABEL: define <2 x float> @test_pow_10_v2f32( 1545; CHECK-SAME: <2 x float> [[X:%.*]]) { 1546; CHECK-NEXT: [[RETVAL:%.*]] = call <2 x float> @llvm.pow.v2f32(<2 x float> splat (float 1.000000e+01), <2 x float> [[X]]) 1547; CHECK-NEXT: ret <2 x float> [[RETVAL]] 1548; 1549 %retval = call <2 x float> @llvm.pow.v2f32(<2 x float> <float 10.0, float 10.0>, <2 x float> %x) 1550 ret <2 x float> %retval 1551} 1552 1553define <2 x double> @test_pow_10_v2f64(<2 x double> %x) { 1554; CHECK-LABEL: define <2 x double> @test_pow_10_v2f64( 1555; CHECK-SAME: <2 x double> [[X:%.*]]) { 1556; CHECK-NEXT: [[RETVAL:%.*]] = call <2 x double> @llvm.pow.v2f64(<2 x double> splat (double 1.000000e+01), <2 x double> [[X]]) 1557; CHECK-NEXT: ret <2 x double> [[RETVAL]] 1558; 1559 %retval = call <2 x double> @llvm.pow.v2f64(<2 x double> <double 10.0, double 10.0>, <2 x double> %x) 1560 ret <2 x double> %retval 1561} 1562 1563define <2 x bfloat> @test_pow_10_v2bf16(<2 x bfloat> %x) { 1564; CHECK-LABEL: define <2 x bfloat> @test_pow_10_v2bf16( 1565; CHECK-SAME: <2 x bfloat> [[X:%.*]]) { 1566; CHECK-NEXT: [[RETVAL:%.*]] = call <2 x bfloat> @llvm.pow.v2bf16(<2 x bfloat> splat (bfloat 0xR4120), <2 x bfloat> [[X]]) 1567; CHECK-NEXT: ret <2 x bfloat> [[RETVAL]] 1568; 1569 %retval = call <2 x bfloat> @llvm.pow.v2bf16(<2 x bfloat> <bfloat 10.0, bfloat 10.0>, <2 x bfloat> %x) 1570 ret <2 x bfloat> %retval 1571} 1572 1573attributes #0 = { nounwind memory(none) } 1574