Index: llvm/lib/Analysis/ConstantFolding.cpp =================================================================== --- llvm/lib/Analysis/ConstantFolding.cpp +++ llvm/lib/Analysis/ConstantFolding.cpp @@ -1555,6 +1555,7 @@ case Intrinsic::log10: case Intrinsic::exp: case Intrinsic::exp2: + case Intrinsic::exp10: case Intrinsic::sqrt: case Intrinsic::sin: case Intrinsic::cos: @@ -2213,6 +2214,9 @@ case Intrinsic::exp2: // Fold exp2(x) as pow(2, x), in case the host lacks a C99 library. return ConstantFoldBinaryFP(pow, APFloat(2.0), APF, Ty); + case Intrinsic::exp10: + // Fold exp10(x) as pow(10, x), in case the host lacks a C99 library. + return ConstantFoldBinaryFP(pow, APFloat(10.0), APF, Ty); case Intrinsic::sin: return ConstantFoldFP(sin, APF, Ty); case Intrinsic::cos: Index: llvm/test/CodeGen/AMDGPU/llvm.exp10.ll =================================================================== --- llvm/test/CodeGen/AMDGPU/llvm.exp10.ll +++ llvm/test/CodeGen/AMDGPU/llvm.exp10.ll @@ -5469,98 +5469,17 @@ } define float @v_exp10_f32_0() { -; GCN-SDAG-LABEL: v_exp10_f32_0: -; GCN-SDAG: ; %bb.0: -; GCN-SDAG-NEXT: s_waitcnt vmcnt(0) expcnt(0) lgkmcnt(0) -; GCN-SDAG-NEXT: v_rndne_f32_e32 v0, 0 -; GCN-SDAG-NEXT: v_add_f32_e64 v1, -v0, 0 -; GCN-SDAG-NEXT: v_exp_f32_e32 v1, v1 -; GCN-SDAG-NEXT: v_cvt_i32_f32_e32 v0, v0 -; GCN-SDAG-NEXT: v_ldexp_f32 v0, v1, v0 -; GCN-SDAG-NEXT: s_setpc_b64 s[30:31] -; -; VI-GISEL-LABEL: v_exp10_f32_0: -; VI-GISEL: ; %bb.0: -; VI-GISEL-NEXT: s_waitcnt vmcnt(0) expcnt(0) lgkmcnt(0) -; VI-GISEL-NEXT: v_sub_f32_e64 v0, 0, 0 -; VI-GISEL-NEXT: v_mov_b32_e32 v1, 0x40549000 -; VI-GISEL-NEXT: v_mov_b32_e32 v2, 0x3a2784bc -; VI-GISEL-NEXT: v_mul_f32_e32 v3, 0x3a2784bc, v0 -; VI-GISEL-NEXT: v_mul_f32_e32 v0, 0x40549000, v0 -; VI-GISEL-NEXT: v_mul_f32_e32 v1, 0, v1 -; VI-GISEL-NEXT: v_add_f32_e32 v0, v0, v3 -; VI-GISEL-NEXT: v_mul_f32_e32 v2, 0, v2 -; VI-GISEL-NEXT: v_add_f32_e32 v0, v2, v0 -; VI-GISEL-NEXT: v_rndne_f32_e32 v2, v1 -; VI-GISEL-NEXT: v_sub_f32_e32 v1, v1, v2 -; VI-GISEL-NEXT: v_add_f32_e32 v0, v1, v0 -; VI-GISEL-NEXT: v_cvt_i32_f32_e32 v1, v2 -; VI-GISEL-NEXT: v_exp_f32_e32 v0, v0 -; VI-GISEL-NEXT: v_mov_b32_e32 v2, 0x7f800000 -; VI-GISEL-NEXT: v_ldexp_f32 v0, v0, v1 -; VI-GISEL-NEXT: v_mov_b32_e32 v1, 0xc23369f4 -; VI-GISEL-NEXT: v_cmp_lt_f32_e32 vcc, 0, v1 -; VI-GISEL-NEXT: v_mov_b32_e32 v1, 0x421a209b -; VI-GISEL-NEXT: v_cndmask_b32_e64 v0, v0, 0, vcc -; VI-GISEL-NEXT: v_cmp_gt_f32_e32 vcc, 0, v1 -; VI-GISEL-NEXT: v_cndmask_b32_e32 v0, v0, v2, vcc -; VI-GISEL-NEXT: s_setpc_b64 s[30:31] -; -; GFX900-GISEL-LABEL: v_exp10_f32_0: -; GFX900-GISEL: ; %bb.0: -; GFX900-GISEL-NEXT: s_waitcnt vmcnt(0) expcnt(0) lgkmcnt(0) -; GFX900-GISEL-NEXT: v_mov_b32_e32 v0, 0x40549a78 -; GFX900-GISEL-NEXT: v_bfrev_b32_e32 v1, 1 -; GFX900-GISEL-NEXT: v_fma_f32 v0, 0, v0, v1 -; GFX900-GISEL-NEXT: v_mov_b32_e32 v1, 0x33979a37 -; GFX900-GISEL-NEXT: v_fma_f32 v0, 0, v1, v0 -; GFX900-GISEL-NEXT: v_rndne_f32_e32 v1, 0 -; GFX900-GISEL-NEXT: v_sub_f32_e32 v2, 0, v1 -; GFX900-GISEL-NEXT: v_add_f32_e32 v0, v2, v0 -; GFX900-GISEL-NEXT: v_cvt_i32_f32_e32 v1, v1 -; GFX900-GISEL-NEXT: v_exp_f32_e32 v0, v0 -; GFX900-GISEL-NEXT: v_mov_b32_e32 v2, 0x7f800000 -; GFX900-GISEL-NEXT: v_ldexp_f32 v0, v0, v1 -; GFX900-GISEL-NEXT: v_mov_b32_e32 v1, 0xc23369f4 -; GFX900-GISEL-NEXT: v_cmp_lt_f32_e32 vcc, 0, v1 -; GFX900-GISEL-NEXT: v_mov_b32_e32 v1, 0x421a209b -; GFX900-GISEL-NEXT: v_cndmask_b32_e64 v0, v0, 0, vcc -; GFX900-GISEL-NEXT: v_cmp_gt_f32_e32 vcc, 0, v1 -; GFX900-GISEL-NEXT: v_cndmask_b32_e32 v0, v0, v2, vcc -; GFX900-GISEL-NEXT: s_setpc_b64 s[30:31] -; -; SI-SDAG-LABEL: v_exp10_f32_0: -; SI-SDAG: ; %bb.0: -; SI-SDAG-NEXT: s_waitcnt vmcnt(0) expcnt(0) lgkmcnt(0) -; SI-SDAG-NEXT: v_rndne_f32_e32 v0, 0 -; SI-SDAG-NEXT: v_add_f32_e64 v1, -v0, 0 -; SI-SDAG-NEXT: v_exp_f32_e32 v1, v1 -; SI-SDAG-NEXT: v_cvt_i32_f32_e32 v0, v0 -; SI-SDAG-NEXT: v_ldexp_f32_e32 v0, v1, v0 -; SI-SDAG-NEXT: s_setpc_b64 s[30:31] +; GCN-LABEL: v_exp10_f32_0: +; GCN: ; %bb.0: +; GCN-NEXT: s_waitcnt vmcnt(0) expcnt(0) lgkmcnt(0) +; GCN-NEXT: v_mov_b32_e32 v0, 1.0 +; GCN-NEXT: s_setpc_b64 s[30:31] ; -; SI-GISEL-LABEL: v_exp10_f32_0: -; SI-GISEL: ; %bb.0: -; SI-GISEL-NEXT: s_waitcnt vmcnt(0) expcnt(0) lgkmcnt(0) -; SI-GISEL-NEXT: v_mov_b32_e32 v0, 0x40549a78 -; SI-GISEL-NEXT: v_bfrev_b32_e32 v1, 1 -; SI-GISEL-NEXT: v_fma_f32 v0, 0, v0, v1 -; SI-GISEL-NEXT: v_mov_b32_e32 v1, 0x33979a37 -; SI-GISEL-NEXT: v_fma_f32 v0, 0, v1, v0 -; SI-GISEL-NEXT: v_rndne_f32_e32 v1, 0 -; SI-GISEL-NEXT: v_sub_f32_e32 v2, 0, v1 -; SI-GISEL-NEXT: v_add_f32_e32 v0, v2, v0 -; SI-GISEL-NEXT: v_cvt_i32_f32_e32 v1, v1 -; SI-GISEL-NEXT: v_exp_f32_e32 v0, v0 -; SI-GISEL-NEXT: v_mov_b32_e32 v2, 0x7f800000 -; SI-GISEL-NEXT: v_ldexp_f32_e32 v0, v0, v1 -; SI-GISEL-NEXT: v_mov_b32_e32 v1, 0xc23369f4 -; SI-GISEL-NEXT: v_cmp_lt_f32_e32 vcc, 0, v1 -; SI-GISEL-NEXT: v_mov_b32_e32 v1, 0x421a209b -; SI-GISEL-NEXT: v_cndmask_b32_e64 v0, v0, 0, vcc -; SI-GISEL-NEXT: v_cmp_gt_f32_e32 vcc, 0, v1 -; SI-GISEL-NEXT: v_cndmask_b32_e32 v0, v0, v2, vcc -; SI-GISEL-NEXT: s_setpc_b64 s[30:31] +; SI-LABEL: v_exp10_f32_0: +; SI: ; %bb.0: +; SI-NEXT: s_waitcnt vmcnt(0) expcnt(0) lgkmcnt(0) +; SI-NEXT: v_mov_b32_e32 v0, 1.0 +; SI-NEXT: s_setpc_b64 s[30:31] ; ; R600-LABEL: v_exp10_f32_0: ; R600: ; %bb.0: @@ -7734,5 +7653,3 @@ attributes #0 = { "denormal-fp-math-f32"="ieee,preserve-sign" } attributes #1 = { "denormal-fp-math-f32"="dynamic,dynamic" } attributes #2 = { nocallback nofree nosync nounwind speculatable willreturn memory(none) } -;; NOTE: These prefixes are unused and the list is autogenerated. Do not add tests below this line: -; SI: {{.*}} Index: llvm/test/Transforms/InstSimplify/exp10.ll =================================================================== --- llvm/test/Transforms/InstSimplify/exp10.ll +++ llvm/test/Transforms/InstSimplify/exp10.ll @@ -35,8 +35,7 @@ define float @exp10_exp10_const(float %x) { ; CHECK-LABEL: define float @exp10_exp10_const ; CHECK-SAME: (float [[X:%.*]]) { -; CHECK-NEXT: [[EXP100:%.*]] = call float @llvm.exp10.f32(float 4.200000e+01) -; CHECK-NEXT: [[EXP101:%.*]] = call float @llvm.exp10.f32(float [[EXP100]]) +; CHECK-NEXT: [[EXP101:%.*]] = call float @llvm.exp10.f32(float 0x7FF0000000000000) ; CHECK-NEXT: ret float [[EXP101]] ; %exp100 = call float @llvm.exp10.f32(float 42.0) @@ -102,8 +101,7 @@ define <2 x float> @exp10_zero_vector() { ; CHECK-LABEL: define <2 x float> @exp10_zero_vector() { -; CHECK-NEXT: [[RET:%.*]] = call <2 x float> @llvm.exp10.v2f32(<2 x float> zeroinitializer) -; CHECK-NEXT: ret <2 x float> [[RET]] +; CHECK-NEXT: ret <2 x float> ; %ret = call <2 x float> @llvm.exp10.v2f32(<2 x float> zeroinitializer) ret <2 x float> %ret @@ -120,8 +118,7 @@ define <2 x float> @exp10_zero_negzero_vector() { ; CHECK-LABEL: define <2 x float> @exp10_zero_negzero_vector() { -; CHECK-NEXT: [[RET:%.*]] = call <2 x float> @llvm.exp10.v2f32(<2 x float> ) -; CHECK-NEXT: ret <2 x float> [[RET]] +; CHECK-NEXT: ret <2 x float> ; %ret = call <2 x float> @llvm.exp10.v2f32(<2 x float> ) ret <2 x float> %ret @@ -138,8 +135,7 @@ define float @exp10_zero() { ; CHECK-LABEL: define float @exp10_zero() { -; CHECK-NEXT: [[RET:%.*]] = call float @llvm.exp10.f32(float 0.000000e+00) -; CHECK-NEXT: ret float [[RET]] +; CHECK-NEXT: ret float 1.000000e+00 ; %ret = call float @llvm.exp10.f32(float 0.0) ret float %ret @@ -147,8 +143,7 @@ define float @exp10_negzero() { ; CHECK-LABEL: define float @exp10_negzero() { -; CHECK-NEXT: [[RET:%.*]] = call float @llvm.exp10.f32(float -0.000000e+00) -; CHECK-NEXT: ret float [[RET]] +; CHECK-NEXT: ret float 1.000000e+00 ; %ret = call float @llvm.exp10.f32(float -0.0) ret float %ret @@ -156,8 +151,7 @@ define float @exp10_one() { ; CHECK-LABEL: define float @exp10_one() { -; CHECK-NEXT: [[RET:%.*]] = call float @llvm.exp10.f32(float 1.000000e+00) -; CHECK-NEXT: ret float [[RET]] +; CHECK-NEXT: ret float 1.000000e+01 ; %ret = call float @llvm.exp10.f32(float 1.0) ret float %ret @@ -165,8 +159,7 @@ define float @exp10_negone() { ; CHECK-LABEL: define float @exp10_negone() { -; CHECK-NEXT: [[RET:%.*]] = call float @llvm.exp10.f32(float -1.000000e+00) -; CHECK-NEXT: ret float [[RET]] +; CHECK-NEXT: ret float 0x3FB99999A0000000 ; %ret = call float @llvm.exp10.f32(float -1.0) ret float %ret @@ -174,8 +167,7 @@ define float @exp10_two() { ; CHECK-LABEL: define float @exp10_two() { -; CHECK-NEXT: [[RET:%.*]] = call float @llvm.exp10.f32(float 2.000000e+00) -; CHECK-NEXT: ret float [[RET]] +; CHECK-NEXT: ret float 1.000000e+02 ; %ret = call float @llvm.exp10.f32(float 2.0) ret float %ret @@ -183,8 +175,7 @@ define float @exp10_negtwo() { ; CHECK-LABEL: define float @exp10_negtwo() { -; CHECK-NEXT: [[RET:%.*]] = call float @llvm.exp10.f32(float -2.000000e+00) -; CHECK-NEXT: ret float [[RET]] +; CHECK-NEXT: ret float 0x3F847AE140000000 ; %ret = call float @llvm.exp10.f32(float -2.0) ret float %ret @@ -228,8 +219,7 @@ define float @exp10_pos_denorm() { ; CHECK-LABEL: define float @exp10_pos_denorm() { -; CHECK-NEXT: [[RET:%.*]] = call float @llvm.exp10.f32(float 0x380FFFFFC0000000) -; CHECK-NEXT: ret float [[RET]] +; CHECK-NEXT: ret float 1.000000e+00 ; %ret = call float @llvm.exp10.f32(float bitcast (i32 8388607 to float)) ret float %ret @@ -237,8 +227,7 @@ define float @exp10_neg_denorm() { ; CHECK-LABEL: define float @exp10_neg_denorm() { -; CHECK-NEXT: [[RET:%.*]] = call float @llvm.exp10.f32(float 0xB80FFFFFC0000000) -; CHECK-NEXT: ret float [[RET]] +; CHECK-NEXT: ret float 1.000000e+00 ; %ret = call float @llvm.exp10.f32(float bitcast (i32 -2139095041 to float)) ret float %ret @@ -273,8 +262,7 @@ define <2 x float> @exp10_splat_4() { ; CHECK-LABEL: define <2 x float> @exp10_splat_4() { -; CHECK-NEXT: [[RET:%.*]] = call <2 x float> @llvm.exp10.v2f32(<2 x float> ) -; CHECK-NEXT: ret <2 x float> [[RET]] +; CHECK-NEXT: ret <2 x float> ; %ret = call <2 x float> @llvm.exp10.v2f32(<2 x float> ) ret <2 x float> %ret