diff --git a/llvm/test/CodeGen/AMDGPU/fmuladd-to-fma.ll b/llvm/test/CodeGen/AMDGPU/fmuladd-to-fma.ll new file mode 100644 --- /dev/null +++ b/llvm/test/CodeGen/AMDGPU/fmuladd-to-fma.ll @@ -0,0 +1,18 @@ +; NOTE: Assertions have been autogenerated by utils/update_llc_test_checks.py UTC_ARGS: --version 2 +; RUN: opt < %s -passes=instcombine | llc -march=amdgcn -mcpu=gfx1030 | FileCheck %s + +define float @f(float %arg) { +; CHECK-LABEL: f: +; CHECK: ; %bb.0: ; %bb +; CHECK-NEXT: s_waitcnt vmcnt(0) expcnt(0) lgkmcnt(0) +; CHECK-NEXT: s_waitcnt_vscnt null, 0x0 +; CHECK-NEXT: v_fma_f32 v0, v0, v0, 1.0 +; CHECK-NEXT: v_add_f32_e32 v0, -1.0, v0 +; CHECK-NEXT: s_setpc_b64 s[30:31] +bb: + %a = call contract float @llvm.fmuladd.f32(float %arg, float %arg, float 1.0) + %b = fadd reassoc nsz float %a, -1.0 + ret float %b +} + +declare float @llvm.fmuladd.f32(float, float, float) diff --git a/llvm/test/Transforms/InstCombine/fma.ll b/llvm/test/Transforms/InstCombine/fma.ll --- a/llvm/test/Transforms/InstCombine/fma.ll +++ b/llvm/test/Transforms/InstCombine/fma.ll @@ -192,6 +192,17 @@ ret float %fmuladd } +define float @fmuladd_fneg_x_fneg_y_contract(float %x, float %y, float %z) { +; CHECK-LABEL: @fmuladd_fneg_x_fneg_y_contract( +; CHECK-NEXT: [[FMULADD:%.*]] = call contract float @llvm.fmuladd.f32(float [[X:%.*]], float [[Y:%.*]], float [[Z:%.*]]) +; CHECK-NEXT: ret float [[FMULADD]] +; + %x.fneg = fsub float -0.0, %x + %y.fneg = fsub float -0.0, %y + %fmuladd = call contract float @llvm.fmuladd.f32(float %x.fneg, float %y.fneg, float %z) + ret float %fmuladd +} + define float @fmuladd_fneg_x_fneg_y_fast(float %x, float %y, float %z) { ; CHECK-LABEL: @fmuladd_fneg_x_fneg_y_fast( ; CHECK-NEXT: [[TMP1:%.*]] = fmul fast float [[X:%.*]], [[Y:%.*]] @@ -204,6 +215,17 @@ ret float %fmuladd } +define float @fmuladd_unary_fneg_x_unary_fneg_y_contract(float %x, float %y, float %z) { +; CHECK-LABEL: @fmuladd_unary_fneg_x_unary_fneg_y_contract( +; CHECK-NEXT: [[FMULADD:%.*]] = call contract float @llvm.fmuladd.f32(float [[X:%.*]], float [[Y:%.*]], float [[Z:%.*]]) +; CHECK-NEXT: ret float [[FMULADD]] +; + %x.fneg = fneg float %x + %y.fneg = fneg float %y + %fmuladd = call contract float @llvm.fmuladd.f32(float %x.fneg, float %y.fneg, float %z) + ret float %fmuladd +} + define float @fmuladd_unary_fneg_x_unary_fneg_y_fast(float %x, float %y, float %z) { ; CHECK-LABEL: @fmuladd_unary_fneg_x_unary_fneg_y_fast( ; CHECK-NEXT: [[TMP1:%.*]] = fmul fast float [[X:%.*]], [[Y:%.*]] @@ -283,6 +305,16 @@ ret float %fmuladd } +define float @fmuladd_fabs_x_fabs_x_contract(float %x, float %z) { +; CHECK-LABEL: @fmuladd_fabs_x_fabs_x_contract( +; CHECK-NEXT: [[FMULADD:%.*]] = call contract float @llvm.fmuladd.f32(float [[X:%.*]], float [[X]], float [[Z:%.*]]) +; CHECK-NEXT: ret float [[FMULADD]] +; + %x.fabs = call float @llvm.fabs.f32(float %x) + %fmuladd = call contract float @llvm.fmuladd.f32(float %x.fabs, float %x.fabs, float %z) + ret float %fmuladd +} + define float @fmuladd_fabs_x_fabs_x_fast(float %x, float %z) { ; CHECK-LABEL: @fmuladd_fabs_x_fabs_x_fast( ; CHECK-NEXT: [[TMP1:%.*]] = fmul fast float [[X:%.*]], [[X]] @@ -312,6 +344,15 @@ ret float %fma } +define float @fmuladd_k_y_z_contract(float %y, float %z) { +; CHECK-LABEL: @fmuladd_k_y_z_contract( +; CHECK-NEXT: [[FMULADD:%.*]] = call contract float @llvm.fmuladd.f32(float [[Y:%.*]], float 4.000000e+00, float [[Z:%.*]]) +; CHECK-NEXT: ret float [[FMULADD]] +; + %fmuladd = call contract float @llvm.fmuladd.f32(float 4.0, float %y, float %z) + ret float %fmuladd +} + define float @fmuladd_k_y_z_fast(float %y, float %z) { ; CHECK-LABEL: @fmuladd_k_y_z_fast( ; CHECK-NEXT: [[TMP1:%.*]] = fmul fast float [[Y:%.*]], 4.000000e+00 @@ -457,6 +498,15 @@ ret float %fma } +define float @fmuladd_x_1_z_contract(float %x, float %z) { +; CHECK-LABEL: @fmuladd_x_1_z_contract( +; CHECK-NEXT: [[FMULADD:%.*]] = fadd contract float [[X:%.*]], [[Z:%.*]] +; CHECK-NEXT: ret float [[FMULADD]] +; + %fmuladd = call contract float @llvm.fmuladd.f32(float %x, float 1.0, float %z) + ret float %fmuladd +} + define float @fmuladd_x_1_z_fast(float %x, float %z) { ; CHECK-LABEL: @fmuladd_x_1_z_fast( ; CHECK-NEXT: [[FMULADD:%.*]] = fadd fast float [[X:%.*]], [[Z:%.*]]