1; NOTE: Assertions have been autogenerated by utils/update_test_checks.py 2; RUN: opt -instcombine -S < %s | FileCheck %s --check-prefixes=CHECK,SQRT 3; RUN: opt -instcombine -S < %s -disable-builtin sqrt | FileCheck %s --check-prefixes=CHECK,NOSQRT 4 5declare double @llvm.pow.f64(double, double) 6declare float @llvm.pow.f32(float, float) 7declare <2 x double> @llvm.pow.v2f64(<2 x double>, <2 x double>) 8declare <2 x float> @llvm.pow.v2f32(<2 x float>, <2 x float>) 9declare <4 x float> @llvm.pow.v4f32(<4 x float>, <4 x float>) 10declare double @pow(double, double) 11 12; pow(x, 3.0) 13define double @test_simplify_3(double %x) { 14; CHECK-LABEL: @test_simplify_3( 15; CHECK-NEXT: [[SQUARE:%.*]] = fmul fast double [[X:%.*]], [[X]] 16; CHECK-NEXT: [[TMP1:%.*]] = fmul fast double [[SQUARE]], [[X]] 17; CHECK-NEXT: ret double [[TMP1]] 18; 19 %1 = call fast double @llvm.pow.f64(double %x, double 3.000000e+00) 20 ret double %1 21} 22 23; powf(x, 4.0) 24define float @test_simplify_4f(float %x) { 25; CHECK-LABEL: @test_simplify_4f( 26; CHECK-NEXT: [[SQUARE:%.*]] = fmul fast float [[X:%.*]], [[X]] 27; CHECK-NEXT: [[TMP1:%.*]] = fmul fast float [[SQUARE]], [[SQUARE]] 28; CHECK-NEXT: ret float [[TMP1]] 29; 30 %1 = call fast float @llvm.pow.f32(float %x, float 4.000000e+00) 31 ret float %1 32} 33 34; pow(x, 4.0) 35define double @test_simplify_4(double %x) { 36; CHECK-LABEL: @test_simplify_4( 37; CHECK-NEXT: [[SQUARE:%.*]] = fmul fast double [[X:%.*]], [[X]] 38; CHECK-NEXT: [[TMP1:%.*]] = fmul fast double [[SQUARE]], [[SQUARE]] 39; CHECK-NEXT: ret double [[TMP1]] 40; 41 %1 = call fast double @llvm.pow.f64(double %x, double 4.000000e+00) 42 ret double %1 43} 44 45; powf(x, <15.0, 15.0>) 46define <2 x float> @test_simplify_15(<2 x float> %x) { 47; CHECK-LABEL: @test_simplify_15( 48; CHECK-NEXT: [[SQUARE:%.*]] = fmul fast <2 x float> [[X:%.*]], [[X]] 49; CHECK-NEXT: [[TMP1:%.*]] = fmul fast <2 x float> [[SQUARE]], [[X]] 50; CHECK-NEXT: [[TMP2:%.*]] = fmul fast <2 x float> [[TMP1]], [[TMP1]] 51; CHECK-NEXT: [[TMP3:%.*]] = fmul fast <2 x float> [[TMP2]], [[TMP2]] 52; CHECK-NEXT: [[TMP4:%.*]] = fmul fast <2 x float> [[TMP1]], [[TMP3]] 53; CHECK-NEXT: ret <2 x float> [[TMP4]] 54; 55 %1 = call fast <2 x float> @llvm.pow.v2f32(<2 x float> %x, <2 x float> <float 1.500000e+01, float 1.500000e+01>) 56 ret <2 x float> %1 57} 58 59; pow(x, -7.0) 60define <2 x double> @test_simplify_neg_7(<2 x double> %x) { 61; CHECK-LABEL: @test_simplify_neg_7( 62; CHECK-NEXT: [[SQUARE:%.*]] = fmul fast <2 x double> [[X:%.*]], [[X]] 63; CHECK-NEXT: [[TMP1:%.*]] = fmul fast <2 x double> [[SQUARE]], [[SQUARE]] 64; CHECK-NEXT: [[TMP2:%.*]] = fmul fast <2 x double> [[TMP1]], [[X]] 65; CHECK-NEXT: [[TMP3:%.*]] = fmul fast <2 x double> [[SQUARE]], [[TMP2]] 66; CHECK-NEXT: [[RECIPROCAL:%.*]] = fdiv fast <2 x double> <double 1.000000e+00, double 1.000000e+00>, [[TMP3]] 67; CHECK-NEXT: ret <2 x double> [[RECIPROCAL]] 68; 69 %1 = call fast <2 x double> @llvm.pow.v2f64(<2 x double> %x, <2 x double> <double -7.000000e+00, double -7.000000e+00>) 70 ret <2 x double> %1 71} 72 73; powf(x, -19.0) 74define float @test_simplify_neg_19(float %x) { 75; CHECK-LABEL: @test_simplify_neg_19( 76; CHECK-NEXT: [[SQUARE:%.*]] = fmul fast float [[X:%.*]], [[X]] 77; CHECK-NEXT: [[TMP1:%.*]] = fmul fast float [[SQUARE]], [[SQUARE]] 78; CHECK-NEXT: [[TMP2:%.*]] = fmul fast float [[TMP1]], [[TMP1]] 79; CHECK-NEXT: [[TMP3:%.*]] = fmul fast float [[TMP2]], [[TMP2]] 80; CHECK-NEXT: [[TMP4:%.*]] = fmul fast float [[SQUARE]], [[TMP3]] 81; CHECK-NEXT: [[TMP5:%.*]] = fmul fast float [[TMP4]], [[X]] 82; CHECK-NEXT: [[RECIPROCAL:%.*]] = fdiv fast float 1.000000e+00, [[TMP5]] 83; CHECK-NEXT: ret float [[RECIPROCAL]] 84; 85 %1 = call fast float @llvm.pow.f32(float %x, float -1.900000e+01) 86 ret float %1 87} 88 89; pow(x, 11.23) 90define double @test_simplify_11_23(double %x) { 91; CHECK-LABEL: @test_simplify_11_23( 92; CHECK-NEXT: [[TMP1:%.*]] = call fast double @llvm.pow.f64(double [[X:%.*]], double 1.123000e+01) 93; CHECK-NEXT: ret double [[TMP1]] 94; 95 %1 = call fast double @llvm.pow.f64(double %x, double 1.123000e+01) 96 ret double %1 97} 98 99; powf(x, 32.0) 100define float @test_simplify_32(float %x) { 101; CHECK-LABEL: @test_simplify_32( 102; CHECK-NEXT: [[SQUARE:%.*]] = fmul fast float [[X:%.*]], [[X]] 103; CHECK-NEXT: [[TMP1:%.*]] = fmul fast float [[SQUARE]], [[SQUARE]] 104; CHECK-NEXT: [[TMP2:%.*]] = fmul fast float [[TMP1]], [[TMP1]] 105; CHECK-NEXT: [[TMP3:%.*]] = fmul fast float [[TMP2]], [[TMP2]] 106; CHECK-NEXT: [[TMP4:%.*]] = fmul fast float [[TMP3]], [[TMP3]] 107; CHECK-NEXT: ret float [[TMP4]] 108; 109 %1 = call fast float @llvm.pow.f32(float %x, float 3.200000e+01) 110 ret float %1 111} 112 113; pow(x, 33.0) 114define double @test_simplify_33(double %x) { 115; CHECK-LABEL: @test_simplify_33( 116; CHECK-NEXT: [[TMP1:%.*]] = call fast double @llvm.powi.f64(double [[X:%.*]], i32 33) 117; CHECK-NEXT: ret double [[TMP1]] 118; 119 %1 = call fast double @llvm.pow.f64(double %x, double 3.300000e+01) 120 ret double %1 121} 122 123; pow(x, 16.5) with double 124define double @test_simplify_16_5(double %x) { 125; CHECK-LABEL: @test_simplify_16_5( 126; CHECK-NEXT: [[SQRT:%.*]] = call fast double @llvm.sqrt.f64(double [[X:%.*]]) 127; CHECK-NEXT: [[SQUARE:%.*]] = fmul fast double [[X]], [[X]] 128; CHECK-NEXT: [[TMP1:%.*]] = fmul fast double [[SQUARE]], [[SQUARE]] 129; CHECK-NEXT: [[TMP2:%.*]] = fmul fast double [[TMP1]], [[TMP1]] 130; CHECK-NEXT: [[TMP3:%.*]] = fmul fast double [[TMP2]], [[TMP2]] 131; CHECK-NEXT: [[TMP4:%.*]] = fmul fast double [[TMP3]], [[SQRT]] 132; CHECK-NEXT: ret double [[TMP4]] 133; 134 %1 = call fast double @llvm.pow.f64(double %x, double 1.650000e+01) 135 ret double %1 136} 137 138; pow(x, -16.5) with double 139define double @test_simplify_neg_16_5(double %x) { 140; CHECK-LABEL: @test_simplify_neg_16_5( 141; CHECK-NEXT: [[SQRT:%.*]] = call fast double @llvm.sqrt.f64(double [[X:%.*]]) 142; CHECK-NEXT: [[SQUARE:%.*]] = fmul fast double [[X]], [[X]] 143; CHECK-NEXT: [[TMP1:%.*]] = fmul fast double [[SQUARE]], [[SQUARE]] 144; CHECK-NEXT: [[TMP2:%.*]] = fmul fast double [[TMP1]], [[TMP1]] 145; CHECK-NEXT: [[TMP3:%.*]] = fmul fast double [[TMP2]], [[TMP2]] 146; CHECK-NEXT: [[TMP4:%.*]] = fmul fast double [[TMP3]], [[SQRT]] 147; CHECK-NEXT: [[RECIPROCAL:%.*]] = fdiv fast double 1.000000e+00, [[TMP4]] 148; CHECK-NEXT: ret double [[RECIPROCAL]] 149; 150 %1 = call fast double @llvm.pow.f64(double %x, double -1.650000e+01) 151 ret double %1 152} 153 154; pow(x, 16.5) with double 155 156define double @test_simplify_16_5_libcall(double %x) { 157; SQRT-LABEL: @test_simplify_16_5_libcall( 158; SQRT-NEXT: [[SQRT:%.*]] = call fast double @sqrt(double [[X:%.*]]) 159; SQRT-NEXT: [[SQUARE:%.*]] = fmul fast double [[X]], [[X]] 160; SQRT-NEXT: [[TMP1:%.*]] = fmul fast double [[SQUARE]], [[SQUARE]] 161; SQRT-NEXT: [[TMP2:%.*]] = fmul fast double [[TMP1]], [[TMP1]] 162; SQRT-NEXT: [[TMP3:%.*]] = fmul fast double [[TMP2]], [[TMP2]] 163; SQRT-NEXT: [[TMP4:%.*]] = fmul fast double [[TMP3]], [[SQRT]] 164; SQRT-NEXT: ret double [[TMP4]] 165; 166; NOSQRT-LABEL: @test_simplify_16_5_libcall( 167; NOSQRT-NEXT: [[TMP1:%.*]] = call fast double @pow(double [[X:%.*]], double 1.650000e+01) 168; NOSQRT-NEXT: ret double [[TMP1]] 169; 170 %1 = call fast double @pow(double %x, double 1.650000e+01) 171 ret double %1 172} 173 174; pow(x, -16.5) with double 175 176define double @test_simplify_neg_16_5_libcall(double %x) { 177; SQRT-LABEL: @test_simplify_neg_16_5_libcall( 178; SQRT-NEXT: [[SQRT:%.*]] = call fast double @sqrt(double [[X:%.*]]) 179; SQRT-NEXT: [[SQUARE:%.*]] = fmul fast double [[X]], [[X]] 180; SQRT-NEXT: [[TMP1:%.*]] = fmul fast double [[SQUARE]], [[SQUARE]] 181; SQRT-NEXT: [[TMP2:%.*]] = fmul fast double [[TMP1]], [[TMP1]] 182; SQRT-NEXT: [[TMP3:%.*]] = fmul fast double [[TMP2]], [[TMP2]] 183; SQRT-NEXT: [[TMP4:%.*]] = fmul fast double [[TMP3]], [[SQRT]] 184; SQRT-NEXT: [[RECIPROCAL:%.*]] = fdiv fast double 1.000000e+00, [[TMP4]] 185; SQRT-NEXT: ret double [[RECIPROCAL]] 186; 187; NOSQRT-LABEL: @test_simplify_neg_16_5_libcall( 188; NOSQRT-NEXT: [[TMP1:%.*]] = call fast double @pow(double [[X:%.*]], double -1.650000e+01) 189; NOSQRT-NEXT: ret double [[TMP1]] 190; 191 %1 = call fast double @pow(double %x, double -1.650000e+01) 192 ret double %1 193} 194 195; pow(x, -8.5) with float 196define float @test_simplify_neg_8_5(float %x) { 197; CHECK-LABEL: @test_simplify_neg_8_5( 198; CHECK-NEXT: [[SQRT:%.*]] = call fast float @llvm.sqrt.f32(float [[X:%.*]]) 199; CHECK-NEXT: [[SQUARE:%.*]] = fmul fast float [[X]], [[X]] 200; CHECK-NEXT: [[TMP1:%.*]] = fmul fast float [[SQUARE]], [[SQUARE]] 201; CHECK-NEXT: [[TMP2:%.*]] = fmul fast float [[TMP1]], [[SQRT]] 202; CHECK-NEXT: [[RECIPROCAL:%.*]] = fdiv fast float 1.000000e+00, [[TMP2]] 203; CHECK-NEXT: ret float [[RECIPROCAL]] 204; 205 %1 = call fast float @llvm.pow.f32(float %x, float -0.450000e+01) 206 ret float %1 207} 208 209; pow(x, 7.5) with <2 x double> 210define <2 x double> @test_simplify_7_5(<2 x double> %x) { 211; CHECK-LABEL: @test_simplify_7_5( 212; CHECK-NEXT: [[SQRT:%.*]] = call fast <2 x double> @llvm.sqrt.v2f64(<2 x double> [[X:%.*]]) 213; CHECK-NEXT: [[SQUARE:%.*]] = fmul fast <2 x double> [[X]], [[X]] 214; CHECK-NEXT: [[TMP1:%.*]] = fmul fast <2 x double> [[SQUARE]], [[SQUARE]] 215; CHECK-NEXT: [[TMP2:%.*]] = fmul fast <2 x double> [[TMP1]], [[X]] 216; CHECK-NEXT: [[TMP3:%.*]] = fmul fast <2 x double> [[SQUARE]], [[TMP2]] 217; CHECK-NEXT: [[TMP4:%.*]] = fmul fast <2 x double> [[TMP3]], [[SQRT]] 218; CHECK-NEXT: ret <2 x double> [[TMP4]] 219; 220 %1 = call fast <2 x double> @llvm.pow.v2f64(<2 x double> %x, <2 x double> <double 7.500000e+00, double 7.500000e+00>) 221 ret <2 x double> %1 222} 223 224; pow(x, 3.5) with <4 x float> 225define <4 x float> @test_simplify_3_5(<4 x float> %x) { 226; CHECK-LABEL: @test_simplify_3_5( 227; CHECK-NEXT: [[SQRT:%.*]] = call fast <4 x float> @llvm.sqrt.v4f32(<4 x float> [[X:%.*]]) 228; CHECK-NEXT: [[SQUARE:%.*]] = fmul fast <4 x float> [[X]], [[X]] 229; CHECK-NEXT: [[TMP1:%.*]] = fmul fast <4 x float> [[SQUARE]], [[X]] 230; CHECK-NEXT: [[TMP2:%.*]] = fmul fast <4 x float> [[TMP1]], [[SQRT]] 231; CHECK-NEXT: ret <4 x float> [[TMP2]] 232; 233 %1 = call fast <4 x float> @llvm.pow.v4f32(<4 x float> %x, <4 x float> <float 3.500000e+00, float 3.500000e+00, float 3.500000e+00, float 3.500000e+00>) 234 ret <4 x float> %1 235} 236 237; (float)pow((double)(float)x, 0.5) 238; FIXME: One call to `sqrtf` would suffice (PR47613). 239define float @shrink_pow_libcall_half(float %x) { 240; SQRT-LABEL: @shrink_pow_libcall_half( 241; SQRT-NEXT: [[SQRTF:%.*]] = call fast float @sqrtf(float [[X:%.*]]) 242; SQRT-NEXT: [[SQRTF1:%.*]] = call fast float @sqrtf(float [[X]]) 243; SQRT-NEXT: ret float [[SQRTF1]] 244; 245; NOSQRT-LABEL: @shrink_pow_libcall_half( 246; NOSQRT-NEXT: [[SQRTF:%.*]] = call fast float @sqrtf(float [[X:%.*]]) 247; NOSQRT-NEXT: ret float [[SQRTF]] 248; 249 %dx = fpext float %x to double 250 %call = call fast double @pow(double %dx, double 0.5) 251 %fr = fptrunc double %call to float 252 ret float %fr 253} 254 255; Make sure that -0.0 exponent is always simplified. 256 257define double @PR43233(double %x) { 258; CHECK-LABEL: @PR43233( 259; CHECK-NEXT: ret double 1.000000e+00 260; 261 %r = call fast double @llvm.pow.f64(double %x, double -0.0) 262 ret double %r 263} 264 265