[LoongArch] Support floating-point number reciprocal
authorgonglingqin <gonglingqin@loongson.cn>
Wed, 31 Aug 2022 06:13:08 +0000 (14:13 +0800)
committergonglingqin <gonglingqin@loongson.cn>
Wed, 31 Aug 2022 06:20:46 +0000 (14:20 +0800)
Differential Revision: https://reviews.llvm.org/D132847

llvm/lib/Target/LoongArch/LoongArchFloat32InstrInfo.td
llvm/lib/Target/LoongArch/LoongArchFloat64InstrInfo.td
llvm/test/CodeGen/LoongArch/fp-reciprocal.ll [new file with mode: 0644]

index 447d255..ce48353 100644 (file)
@@ -213,6 +213,9 @@ def : Pat<(f32 fpimm1), (FFINT_S_W (MOVGR2FR_W (ADDI_W R0, 1)))>;
 
 // FP Conversion
 def : Pat<(loongarch_ftint FPR32:$src), (FTINTRZ_W_S FPR32:$src)>;
+
+// FP reciprocal operation
+def : Pat<(fdiv fpimm1, FPR32:$src), (FRECIP_S $src)>;
 } // Predicates = [HasBasicF]
 
 let Predicates = [HasBasicF, IsLA64] in {
index 3104a2d..3ba6826 100644 (file)
@@ -215,6 +215,9 @@ def : Pat<(loongarch_ftint FPR32:$src), (FTINTRZ_L_S FPR32:$src)>;
 def : Pat<(f32 (fpround FPR64:$src)), (FCVT_S_D FPR64:$src)>;
 // f32 -> f64
 def : Pat<(f64 (fpextend FPR32:$src)), (FCVT_D_S FPR32:$src)>;
+
+// FP reciprocal operation
+def : Pat<(fdiv fpimm1, FPR64:$src), (FRECIP_D $src)>;
 } // Predicates = [HasBasicD]
 
 /// Floating point constants
diff --git a/llvm/test/CodeGen/LoongArch/fp-reciprocal.ll b/llvm/test/CodeGen/LoongArch/fp-reciprocal.ll
new file mode 100644 (file)
index 0000000..b858099
--- /dev/null
@@ -0,0 +1,68 @@
+; NOTE: Assertions have been autogenerated by utils/update_llc_test_checks.py
+; RUN: llc --mtriple=loongarch32 --mattr=+f,-d < %s | FileCheck %s --check-prefix=LA32F
+; RUN: llc --mtriple=loongarch32 --mattr=+d < %s | FileCheck %s --check-prefix=LA32D
+; RUN: llc --mtriple=loongarch64 --mattr=+f,-d < %s | FileCheck %s --check-prefix=LA64F
+; RUN: llc --mtriple=loongarch64 --mattr=+d < %s | FileCheck %s --check-prefix=LA64D
+
+
+define float @f32_reciprocal(float %a) nounwind {
+; LA32F-LABEL: f32_reciprocal:
+; LA32F:       # %bb.0:
+; LA32F-NEXT:    frecip.s $fa0, $fa0
+; LA32F-NEXT:    ret
+;
+; LA32D-LABEL: f32_reciprocal:
+; LA32D:       # %bb.0:
+; LA32D-NEXT:    frecip.s $fa0, $fa0
+; LA32D-NEXT:    ret
+;
+; LA64F-LABEL: f32_reciprocal:
+; LA64F:       # %bb.0:
+; LA64F-NEXT:    frecip.s $fa0, $fa0
+; LA64F-NEXT:    ret
+;
+; LA64D-LABEL: f32_reciprocal:
+; LA64D:       # %bb.0:
+; LA64D-NEXT:    frecip.s $fa0, $fa0
+; LA64D-NEXT:    ret
+  %1 = fdiv float 1.0, %a
+  ret float %1
+}
+
+define double @f64_reciprocal(double %a) nounwind {
+; LA32F-LABEL: f64_reciprocal:
+; LA32F:       # %bb.0:
+; LA32F-NEXT:    addi.w $sp, $sp, -16
+; LA32F-NEXT:    st.w $ra, $sp, 12 # 4-byte Folded Spill
+; LA32F-NEXT:    move $a3, $a1
+; LA32F-NEXT:    move $a2, $a0
+; LA32F-NEXT:    lu12i.w $a1, 261888
+; LA32F-NEXT:    move $a0, $zero
+; LA32F-NEXT:    bl %plt(__divdf3)
+; LA32F-NEXT:    ld.w $ra, $sp, 12 # 4-byte Folded Reload
+; LA32F-NEXT:    addi.w $sp, $sp, 16
+; LA32F-NEXT:    ret
+;
+; LA32D-LABEL: f64_reciprocal:
+; LA32D:       # %bb.0:
+; LA32D-NEXT:    frecip.d $fa0, $fa0
+; LA32D-NEXT:    ret
+;
+; LA64F-LABEL: f64_reciprocal:
+; LA64F:       # %bb.0:
+; LA64F-NEXT:    addi.d $sp, $sp, -16
+; LA64F-NEXT:    st.d $ra, $sp, 8 # 8-byte Folded Spill
+; LA64F-NEXT:    move $a1, $a0
+; LA64F-NEXT:    lu52i.d $a0, $zero, 1023
+; LA64F-NEXT:    bl %plt(__divdf3)
+; LA64F-NEXT:    ld.d $ra, $sp, 8 # 8-byte Folded Reload
+; LA64F-NEXT:    addi.d $sp, $sp, 16
+; LA64F-NEXT:    ret
+;
+; LA64D-LABEL: f64_reciprocal:
+; LA64D:       # %bb.0:
+; LA64D-NEXT:    frecip.d $fa0, $fa0
+; LA64D-NEXT:    ret
+  %1 = fdiv double 1.0, %a
+  ret double %1
+}