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