| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,80 @@ | ||
| ; NOTE: Assertions have been autogenerated by utils/update_llc_test_checks.py | ||
| ; RUN: llc --mtriple=loongarch32 --mattr=+f,-d,-frecipe < %s | FileCheck %s --check-prefix=LA32F | ||
| ; RUN: llc --mtriple=loongarch32 --mattr=+f,-d,+frecipe < %s | FileCheck %s --check-prefix=LA32F-FRECIPE | ||
| ; RUN: llc --mtriple=loongarch64 --mattr=+d,-frecipe < %s | FileCheck %s --check-prefix=LA64D | ||
| ; RUN: llc --mtriple=loongarch64 --mattr=+d,+frecipe < %s | FileCheck %s --check-prefix=LA64D-FRECIPE | ||
|
|
||
| ;; Exercise the 'fdiv' LLVM IR: https://llvm.org/docs/LangRef.html#fdiv-instruction | ||
|
|
||
| define float @fdiv_s(float %x, float %y) { | ||
| ; LA32F-LABEL: fdiv_s: | ||
| ; LA32F: # %bb.0: | ||
| ; LA32F-NEXT: fdiv.s $fa0, $fa0, $fa1 | ||
| ; LA32F-NEXT: ret | ||
| ; | ||
| ; LA32F-FRECIPE-LABEL: fdiv_s: | ||
| ; LA32F-FRECIPE: # %bb.0: | ||
| ; LA32F-FRECIPE-NEXT: frecipe.s $fa2, $fa1 | ||
| ; LA32F-FRECIPE-NEXT: fmul.s $fa3, $fa0, $fa2 | ||
| ; LA32F-FRECIPE-NEXT: fnmsub.s $fa0, $fa1, $fa3, $fa0 | ||
| ; LA32F-FRECIPE-NEXT: fmadd.s $fa0, $fa2, $fa0, $fa3 | ||
| ; LA32F-FRECIPE-NEXT: ret | ||
| ; | ||
| ; LA64D-LABEL: fdiv_s: | ||
| ; LA64D: # %bb.0: | ||
| ; LA64D-NEXT: fdiv.s $fa0, $fa0, $fa1 | ||
| ; LA64D-NEXT: ret | ||
| ; | ||
| ; LA64D-FRECIPE-LABEL: fdiv_s: | ||
| ; LA64D-FRECIPE: # %bb.0: | ||
| ; LA64D-FRECIPE-NEXT: frecipe.s $fa2, $fa1 | ||
| ; LA64D-FRECIPE-NEXT: fmul.s $fa3, $fa0, $fa2 | ||
| ; LA64D-FRECIPE-NEXT: fnmsub.s $fa0, $fa1, $fa3, $fa0 | ||
| ; LA64D-FRECIPE-NEXT: fmadd.s $fa0, $fa2, $fa0, $fa3 | ||
| ; LA64D-FRECIPE-NEXT: ret | ||
| %div = fdiv fast float %x, %y | ||
| ret float %div | ||
| } | ||
|
|
||
| define double @fdiv_d(double %x, double %y) { | ||
| ; LA32F-LABEL: fdiv_d: | ||
| ; LA32F: # %bb.0: | ||
| ; LA32F-NEXT: addi.w $sp, $sp, -16 | ||
| ; LA32F-NEXT: .cfi_def_cfa_offset 16 | ||
| ; LA32F-NEXT: st.w $ra, $sp, 12 # 4-byte Folded Spill | ||
| ; LA32F-NEXT: .cfi_offset 1, -4 | ||
| ; 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 | ||
| ; | ||
| ; LA32F-FRECIPE-LABEL: fdiv_d: | ||
| ; LA32F-FRECIPE: # %bb.0: | ||
| ; LA32F-FRECIPE-NEXT: addi.w $sp, $sp, -16 | ||
| ; LA32F-FRECIPE-NEXT: .cfi_def_cfa_offset 16 | ||
| ; LA32F-FRECIPE-NEXT: st.w $ra, $sp, 12 # 4-byte Folded Spill | ||
| ; LA32F-FRECIPE-NEXT: .cfi_offset 1, -4 | ||
| ; LA32F-FRECIPE-NEXT: bl %plt(__divdf3) | ||
| ; LA32F-FRECIPE-NEXT: ld.w $ra, $sp, 12 # 4-byte Folded Reload | ||
| ; LA32F-FRECIPE-NEXT: addi.w $sp, $sp, 16 | ||
| ; LA32F-FRECIPE-NEXT: ret | ||
| ; | ||
| ; LA64D-LABEL: fdiv_d: | ||
| ; LA64D: # %bb.0: | ||
| ; LA64D-NEXT: fdiv.d $fa0, $fa0, $fa1 | ||
| ; LA64D-NEXT: ret | ||
| ; | ||
| ; LA64D-FRECIPE-LABEL: fdiv_d: | ||
| ; LA64D-FRECIPE: # %bb.0: | ||
| ; LA64D-FRECIPE-NEXT: pcalau12i $a0, %pc_hi20(.LCPI1_0) | ||
| ; LA64D-FRECIPE-NEXT: fld.d $fa2, $a0, %pc_lo12(.LCPI1_0) | ||
| ; LA64D-FRECIPE-NEXT: frecipe.d $fa3, $fa1 | ||
| ; LA64D-FRECIPE-NEXT: fmadd.d $fa2, $fa1, $fa3, $fa2 | ||
| ; LA64D-FRECIPE-NEXT: fnmsub.d $fa2, $fa2, $fa3, $fa3 | ||
| ; LA64D-FRECIPE-NEXT: fmul.d $fa3, $fa0, $fa2 | ||
| ; LA64D-FRECIPE-NEXT: fnmsub.d $fa0, $fa1, $fa3, $fa0 | ||
| ; LA64D-FRECIPE-NEXT: fmadd.d $fa0, $fa2, $fa0, $fa3 | ||
| ; LA64D-FRECIPE-NEXT: ret | ||
| %div = fdiv fast double %x, %y | ||
| ret double %div | ||
| } |
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,114 @@ | ||
| ; NOTE: Assertions have been autogenerated by utils/update_llc_test_checks.py UTC_ARGS: --version 4 | ||
| ; RUN: llc --mtriple=loongarch64 --mattr=+lasx,-frecipe < %s | FileCheck %s --check-prefix=FAULT | ||
| ; RUN: llc --mtriple=loongarch64 --mattr=+lasx,+frecipe < %s | FileCheck %s | ||
|
|
||
| define void @fdiv_v8f32(ptr %res, ptr %a0, ptr %a1) nounwind { | ||
| ; FAULT-LABEL: fdiv_v8f32: | ||
| ; FAULT: # %bb.0: | ||
| ; FAULT-NEXT: xvld $xr0, $a1, 0 | ||
| ; FAULT-NEXT: xvld $xr1, $a2, 0 | ||
| ; FAULT-NEXT: xvfdiv.s $xr0, $xr0, $xr1 | ||
| ; FAULT-NEXT: xvst $xr0, $a0, 0 | ||
| ; FAULT-NEXT: ret | ||
| ; | ||
| ; CHECK-LABEL: fdiv_v8f32: | ||
| ; CHECK: # %bb.0: # %entry | ||
| ; CHECK-NEXT: xvld $xr0, $a2, 0 | ||
| ; CHECK-NEXT: xvld $xr1, $a1, 0 | ||
| ; CHECK-NEXT: xvfrecipe.s $xr2, $xr0 | ||
| ; CHECK-NEXT: xvfmul.s $xr3, $xr1, $xr2 | ||
| ; CHECK-NEXT: xvfnmsub.s $xr0, $xr0, $xr3, $xr1 | ||
| ; CHECK-NEXT: xvfmadd.s $xr0, $xr2, $xr0, $xr3 | ||
| ; CHECK-NEXT: xvst $xr0, $a0, 0 | ||
| ; CHECK-NEXT: ret | ||
| entry: | ||
| %v0 = load <8 x float>, ptr %a0 | ||
| %v1 = load <8 x float>, ptr %a1 | ||
| %v2 = fdiv fast <8 x float> %v0, %v1 | ||
| store <8 x float> %v2, ptr %res | ||
| ret void | ||
| } | ||
|
|
||
| define void @fdiv_v4f64(ptr %res, ptr %a0, ptr %a1) nounwind { | ||
| ; FAULT-LABEL: fdiv_v4f64: | ||
| ; FAULT: # %bb.0: | ||
| ; FAULT-NEXT: xvld $xr0, $a1, 0 | ||
| ; FAULT-NEXT: xvld $xr1, $a2, 0 | ||
| ; FAULT-NEXT: xvfdiv.d $xr0, $xr0, $xr1 | ||
| ; FAULT-NEXT: xvst $xr0, $a0, 0 | ||
| ; FAULT-NEXT: ret | ||
| ; | ||
| ; CHECK-LABEL: fdiv_v4f64: | ||
| ; CHECK: # %bb.0: # %entry | ||
| ; CHECK-NEXT: xvld $xr0, $a2, 0 | ||
| ; CHECK-NEXT: xvld $xr1, $a1, 0 | ||
| ; CHECK-NEXT: lu52i.d $a1, $zero, -1025 | ||
| ; CHECK-NEXT: xvreplgr2vr.d $xr2, $a1 | ||
| ; CHECK-NEXT: xvfrecipe.d $xr3, $xr0 | ||
| ; CHECK-NEXT: xvfmadd.d $xr2, $xr0, $xr3, $xr2 | ||
| ; CHECK-NEXT: xvfnmsub.d $xr2, $xr2, $xr3, $xr3 | ||
| ; CHECK-NEXT: xvfmul.d $xr3, $xr1, $xr2 | ||
| ; CHECK-NEXT: xvfnmsub.d $xr0, $xr0, $xr3, $xr1 | ||
| ; CHECK-NEXT: xvfmadd.d $xr0, $xr2, $xr0, $xr3 | ||
| ; CHECK-NEXT: xvst $xr0, $a0, 0 | ||
| ; CHECK-NEXT: ret | ||
| entry: | ||
| %v0 = load <4 x double>, ptr %a0 | ||
| %v1 = load <4 x double>, ptr %a1 | ||
| %v2 = fdiv fast <4 x double> %v0, %v1 | ||
| store <4 x double> %v2, ptr %res | ||
| ret void | ||
| } | ||
|
|
||
| ;; 1.0 / vec | ||
| define void @one_fdiv_v8f32(ptr %res, ptr %a0) nounwind { | ||
| ; FAULT-LABEL: one_fdiv_v8f32: | ||
| ; FAULT: # %bb.0: | ||
| ; FAULT-NEXT: xvld $xr0, $a1, 0 | ||
| ; FAULT-NEXT: xvfrecip.s $xr0, $xr0 | ||
| ; FAULT-NEXT: xvst $xr0, $a0, 0 | ||
| ; FAULT-NEXT: ret | ||
| ; | ||
| ; CHECK-LABEL: one_fdiv_v8f32: | ||
| ; CHECK: # %bb.0: # %entry | ||
| ; CHECK-NEXT: xvld $xr0, $a1, 0 | ||
| ; CHECK-NEXT: xvfrecipe.s $xr1, $xr0 | ||
| ; CHECK-NEXT: lu12i.w $a1, -264192 | ||
| ; CHECK-NEXT: xvreplgr2vr.w $xr2, $a1 | ||
| ; CHECK-NEXT: xvfmadd.s $xr0, $xr0, $xr1, $xr2 | ||
| ; CHECK-NEXT: xvfnmsub.s $xr0, $xr0, $xr1, $xr1 | ||
| ; CHECK-NEXT: xvst $xr0, $a0, 0 | ||
| ; CHECK-NEXT: ret | ||
| entry: | ||
| %v0 = load <8 x float>, ptr %a0 | ||
| %div = fdiv fast <8 x float> <float 1.0, float 1.0, float 1.0, float 1.0, float 1.0, float 1.0, float 1.0, float 1.0>, %v0 | ||
| store <8 x float> %div, ptr %res | ||
| ret void | ||
| } | ||
|
|
||
| define void @one_fdiv_v4f64(ptr %res, ptr %a0) nounwind { | ||
| ; FAULT-LABEL: one_fdiv_v4f64: | ||
| ; FAULT: # %bb.0: | ||
| ; FAULT-NEXT: xvld $xr0, $a1, 0 | ||
| ; FAULT-NEXT: xvfrecip.d $xr0, $xr0 | ||
| ; FAULT-NEXT: xvst $xr0, $a0, 0 | ||
| ; FAULT-NEXT: ret | ||
| ; | ||
| ; CHECK-LABEL: one_fdiv_v4f64: | ||
| ; CHECK: # %bb.0: # %entry | ||
| ; CHECK-NEXT: xvld $xr0, $a1, 0 | ||
| ; CHECK-NEXT: xvfrecipe.d $xr1, $xr0 | ||
| ; CHECK-NEXT: lu52i.d $a1, $zero, 1023 | ||
| ; CHECK-NEXT: xvreplgr2vr.d $xr2, $a1 | ||
| ; CHECK-NEXT: xvfnmsub.d $xr3, $xr0, $xr1, $xr2 | ||
| ; CHECK-NEXT: xvfmadd.d $xr1, $xr1, $xr3, $xr1 | ||
| ; CHECK-NEXT: xvfnmsub.d $xr0, $xr0, $xr1, $xr2 | ||
| ; CHECK-NEXT: xvfmadd.d $xr0, $xr1, $xr0, $xr1 | ||
| ; CHECK-NEXT: xvst $xr0, $a0, 0 | ||
| ; CHECK-NEXT: ret | ||
| entry: | ||
| %v0 = load <4 x double>, ptr %a0 | ||
| %div = fdiv fast <4 x double> <double 1.0, double 1.0, double 1.0, double 1.0>, %v0 | ||
| store <4 x double> %div, ptr %res | ||
| ret void | ||
| } |
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,75 @@ | ||
| ; NOTE: Assertions have been autogenerated by utils/update_llc_test_checks.py | ||
| ; RUN: llc --mtriple=loongarch64 --mattr=+lasx,-frecipe < %s | FileCheck %s --check-prefix=FAULT | ||
| ; RUN: llc --mtriple=loongarch64 --mattr=+lasx,+frecipe < %s | FileCheck %s | ||
|
|
||
| ;; 1.0 / (fsqrt vec) | ||
| define void @one_div_sqrt_v8f32(ptr %res, ptr %a0) nounwind { | ||
| ; FAULT-LABEL: one_div_sqrt_v8f32: | ||
| ; FAULT: # %bb.0: # %entry | ||
| ; FAULT-NEXT: xvld $xr0, $a1, 0 | ||
| ; FAULT-NEXT: xvfrsqrt.s $xr0, $xr0 | ||
| ; FAULT-NEXT: xvst $xr0, $a0, 0 | ||
| ; FAULT-NEXT: ret | ||
| ; | ||
| ; CHECK-LABEL: one_div_sqrt_v8f32: | ||
| ; CHECK: # %bb.0: # %entry | ||
| ; CHECK-NEXT: xvld $xr0, $a1, 0 | ||
| ; CHECK-NEXT: xvfrsqrte.s $xr1, $xr0 | ||
| ; CHECK-NEXT: xvfmul.s $xr1, $xr0, $xr1 | ||
| ; CHECK-NEXT: xvfmul.s $xr0, $xr0, $xr1 | ||
| ; CHECK-NEXT: lu12i.w $a1, -261120 | ||
| ; CHECK-NEXT: xvreplgr2vr.w $xr2, $a1 | ||
| ; CHECK-NEXT: xvfmadd.s $xr0, $xr0, $xr1, $xr2 | ||
| ; CHECK-NEXT: lu12i.w $a1, -266240 | ||
| ; CHECK-NEXT: xvreplgr2vr.w $xr2, $a1 | ||
| ; CHECK-NEXT: xvfmul.s $xr1, $xr1, $xr2 | ||
| ; CHECK-NEXT: xvfmul.s $xr0, $xr1, $xr0 | ||
| ; CHECK-NEXT: xvst $xr0, $a0, 0 | ||
| ; CHECK-NEXT: ret | ||
| entry: | ||
| %v0 = load <8 x float>, ptr %a0, align 16 | ||
| %sqrt = call fast <8 x float> @llvm.sqrt.v8f32 (<8 x float> %v0) | ||
| %div = fdiv fast <8 x float> <float 1.0, float 1.0, float 1.0, float 1.0, float 1.0, float 1.0, float 1.0, float 1.0>, %sqrt | ||
| store <8 x float> %div, ptr %res, align 16 | ||
| ret void | ||
| } | ||
|
|
||
| define void @one_div_sqrt_v4f64(ptr %res, ptr %a0) nounwind { | ||
| ; FAULT-LABEL: one_div_sqrt_v4f64: | ||
| ; FAULT: # %bb.0: # %entry | ||
| ; FAULT-NEXT: xvld $xr0, $a1, 0 | ||
| ; FAULT-NEXT: xvfrsqrt.d $xr0, $xr0 | ||
| ; FAULT-NEXT: xvst $xr0, $a0, 0 | ||
| ; FAULT-NEXT: ret | ||
| ; | ||
| ; CHECK-LABEL: one_div_sqrt_v4f64: | ||
| ; CHECK: # %bb.0: # %entry | ||
| ; CHECK-NEXT: xvld $xr0, $a1, 0 | ||
| ; CHECK-NEXT: xvfrsqrte.d $xr1, $xr0 | ||
| ; CHECK-NEXT: xvfmul.d $xr1, $xr0, $xr1 | ||
| ; CHECK-NEXT: xvfmul.d $xr2, $xr0, $xr1 | ||
| ; CHECK-NEXT: ori $a1, $zero, 0 | ||
| ; CHECK-NEXT: lu32i.d $a1, -524288 | ||
| ; CHECK-NEXT: lu52i.d $a1, $a1, -1024 | ||
| ; CHECK-NEXT: xvreplgr2vr.d $xr3, $a1 | ||
| ; CHECK-NEXT: xvfmadd.d $xr2, $xr2, $xr1, $xr3 | ||
| ; CHECK-NEXT: lu52i.d $a1, $zero, -1026 | ||
| ; CHECK-NEXT: xvreplgr2vr.d $xr4, $a1 | ||
| ; CHECK-NEXT: xvfmul.d $xr1, $xr1, $xr4 | ||
| ; CHECK-NEXT: xvfmul.d $xr1, $xr1, $xr2 | ||
| ; CHECK-NEXT: xvfmul.d $xr0, $xr0, $xr1 | ||
| ; CHECK-NEXT: xvfmadd.d $xr0, $xr0, $xr1, $xr3 | ||
| ; CHECK-NEXT: xvfmul.d $xr1, $xr1, $xr4 | ||
| ; CHECK-NEXT: xvfmul.d $xr0, $xr1, $xr0 | ||
| ; CHECK-NEXT: xvst $xr0, $a0, 0 | ||
| ; CHECK-NEXT: ret | ||
| entry: | ||
| %v0 = load <4 x double>, ptr %a0, align 16 | ||
| %sqrt = call fast <4 x double> @llvm.sqrt.v4f64 (<4 x double> %v0) | ||
| %div = fdiv fast <4 x double> <double 1.0, double 1.0, double 1.0, double 1.0>, %sqrt | ||
| store <4 x double> %div, ptr %res, align 16 | ||
| ret void | ||
| } | ||
|
|
||
| declare <8 x float> @llvm.sqrt.v8f32(<8 x float>) | ||
| declare <4 x double> @llvm.sqrt.v4f64(<4 x double>) |
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,114 @@ | ||
| ; NOTE: Assertions have been autogenerated by utils/update_llc_test_checks.py UTC_ARGS: --version 4 | ||
| ; RUN: llc --mtriple=loongarch64 --mattr=+lsx,-frecipe < %s | FileCheck %s --check-prefix=FAULT | ||
| ; RUN: llc --mtriple=loongarch64 --mattr=+lsx,+frecipe < %s | FileCheck %s | ||
|
|
||
| define void @fdiv_v4f32(ptr %res, ptr %a0, ptr %a1) nounwind { | ||
| ; FAULT-LABEL: fdiv_v4f32: | ||
| ; FAULT: # %bb.0: # %entry | ||
| ; FAULT-NEXT: vld $vr0, $a1, 0 | ||
| ; FAULT-NEXT: vld $vr1, $a2, 0 | ||
| ; FAULT-NEXT: vfdiv.s $vr0, $vr0, $vr1 | ||
| ; FAULT-NEXT: vst $vr0, $a0, 0 | ||
| ; FAULT-NEXT: ret | ||
| ; | ||
| ; CHECK-LABEL: fdiv_v4f32: | ||
| ; CHECK: # %bb.0: # %entry | ||
| ; CHECK-NEXT: vld $vr0, $a2, 0 | ||
| ; CHECK-NEXT: vld $vr1, $a1, 0 | ||
| ; CHECK-NEXT: vfrecipe.s $vr2, $vr0 | ||
| ; CHECK-NEXT: vfmul.s $vr3, $vr1, $vr2 | ||
| ; CHECK-NEXT: vfnmsub.s $vr0, $vr0, $vr3, $vr1 | ||
| ; CHECK-NEXT: vfmadd.s $vr0, $vr2, $vr0, $vr3 | ||
| ; CHECK-NEXT: vst $vr0, $a0, 0 | ||
| ; CHECK-NEXT: ret | ||
| entry: | ||
| %v0 = load <4 x float>, ptr %a0 | ||
| %v1 = load <4 x float>, ptr %a1 | ||
| %v2 = fdiv fast <4 x float> %v0, %v1 | ||
| store <4 x float> %v2, ptr %res | ||
| ret void | ||
| } | ||
|
|
||
| define void @fdiv_v2f64(ptr %res, ptr %a0, ptr %a1) nounwind { | ||
| ; FAULT-LABEL: fdiv_v2f64: | ||
| ; FAULT: # %bb.0: # %entry | ||
| ; FAULT-NEXT: vld $vr0, $a1, 0 | ||
| ; FAULT-NEXT: vld $vr1, $a2, 0 | ||
| ; FAULT-NEXT: vfdiv.d $vr0, $vr0, $vr1 | ||
| ; FAULT-NEXT: vst $vr0, $a0, 0 | ||
| ; FAULT-NEXT: ret | ||
| ; | ||
| ; CHECK-LABEL: fdiv_v2f64: | ||
| ; CHECK: # %bb.0: # %entry | ||
| ; CHECK-NEXT: vld $vr0, $a2, 0 | ||
| ; CHECK-NEXT: vld $vr1, $a1, 0 | ||
| ; CHECK-NEXT: lu52i.d $a1, $zero, -1025 | ||
| ; CHECK-NEXT: vreplgr2vr.d $vr2, $a1 | ||
| ; CHECK-NEXT: vfrecipe.d $vr3, $vr0 | ||
| ; CHECK-NEXT: vfmadd.d $vr2, $vr0, $vr3, $vr2 | ||
| ; CHECK-NEXT: vfnmsub.d $vr2, $vr2, $vr3, $vr3 | ||
| ; CHECK-NEXT: vfmul.d $vr3, $vr1, $vr2 | ||
| ; CHECK-NEXT: vfnmsub.d $vr0, $vr0, $vr3, $vr1 | ||
| ; CHECK-NEXT: vfmadd.d $vr0, $vr2, $vr0, $vr3 | ||
| ; CHECK-NEXT: vst $vr0, $a0, 0 | ||
| ; CHECK-NEXT: ret | ||
| entry: | ||
| %v0 = load <2 x double>, ptr %a0 | ||
| %v1 = load <2 x double>, ptr %a1 | ||
| %v2 = fdiv fast <2 x double> %v0, %v1 | ||
| store <2 x double> %v2, ptr %res | ||
| ret void | ||
| } | ||
|
|
||
| ;; 1.0 / vec | ||
| define void @one_fdiv_v4f32(ptr %res, ptr %a0) nounwind { | ||
| ; FAULT-LABEL: one_fdiv_v4f32: | ||
| ; FAULT: # %bb.0: # %entry | ||
| ; FAULT-NEXT: vld $vr0, $a1, 0 | ||
| ; FAULT-NEXT: vfrecip.s $vr0, $vr0 | ||
| ; FAULT-NEXT: vst $vr0, $a0, 0 | ||
| ; FAULT-NEXT: ret | ||
| ; | ||
| ; CHECK-LABEL: one_fdiv_v4f32: | ||
| ; CHECK: # %bb.0: # %entry | ||
| ; CHECK-NEXT: vld $vr0, $a1, 0 | ||
| ; CHECK-NEXT: vfrecipe.s $vr1, $vr0 | ||
| ; CHECK-NEXT: lu12i.w $a1, -264192 | ||
| ; CHECK-NEXT: vreplgr2vr.w $vr2, $a1 | ||
| ; CHECK-NEXT: vfmadd.s $vr0, $vr0, $vr1, $vr2 | ||
| ; CHECK-NEXT: vfnmsub.s $vr0, $vr0, $vr1, $vr1 | ||
| ; CHECK-NEXT: vst $vr0, $a0, 0 | ||
| ; CHECK-NEXT: ret | ||
| entry: | ||
| %v0 = load <4 x float>, ptr %a0 | ||
| %div = fdiv fast <4 x float> <float 1.0, float 1.0, float 1.0, float 1.0>, %v0 | ||
| store <4 x float> %div, ptr %res | ||
| ret void | ||
| } | ||
|
|
||
| define void @one_fdiv_v2f64(ptr %res, ptr %a0) nounwind { | ||
| ; FAULT-LABEL: one_fdiv_v2f64: | ||
| ; FAULT: # %bb.0: # %entry | ||
| ; FAULT-NEXT: vld $vr0, $a1, 0 | ||
| ; FAULT-NEXT: vfrecip.d $vr0, $vr0 | ||
| ; FAULT-NEXT: vst $vr0, $a0, 0 | ||
| ; FAULT-NEXT: ret | ||
| ; | ||
| ; CHECK-LABEL: one_fdiv_v2f64: | ||
| ; CHECK: # %bb.0: # %entry | ||
| ; CHECK-NEXT: vld $vr0, $a1, 0 | ||
| ; CHECK-NEXT: vfrecipe.d $vr1, $vr0 | ||
| ; CHECK-NEXT: lu52i.d $a1, $zero, 1023 | ||
| ; CHECK-NEXT: vreplgr2vr.d $vr2, $a1 | ||
| ; CHECK-NEXT: vfnmsub.d $vr3, $vr0, $vr1, $vr2 | ||
| ; CHECK-NEXT: vfmadd.d $vr1, $vr1, $vr3, $vr1 | ||
| ; CHECK-NEXT: vfnmsub.d $vr0, $vr0, $vr1, $vr2 | ||
| ; CHECK-NEXT: vfmadd.d $vr0, $vr1, $vr0, $vr1 | ||
| ; CHECK-NEXT: vst $vr0, $a0, 0 | ||
| ; CHECK-NEXT: ret | ||
| entry: | ||
| %v0 = load <2 x double>, ptr %a0 | ||
| %div = fdiv fast <2 x double> <double 1.0, double 1.0>, %v0 | ||
| store <2 x double> %div, ptr %res | ||
| ret void | ||
| } |
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,75 @@ | ||
| ; NOTE: Assertions have been autogenerated by utils/update_llc_test_checks.py | ||
| ; RUN: llc --mtriple=loongarch64 --mattr=+lsx,-frecipe < %s | FileCheck %s --check-prefix=FAULT | ||
| ; RUN: llc --mtriple=loongarch64 --mattr=+lsx,+frecipe < %s | FileCheck %s | ||
|
|
||
| ;; 1.0 / (fsqrt vec) | ||
| define void @one_div_sqrt_v4f32(ptr %res, ptr %a0) nounwind { | ||
| ; FAULT-LABEL: one_div_sqrt_v4f32: | ||
| ; FAULT: # %bb.0: # %entry | ||
| ; FAULT-NEXT: vld $vr0, $a1, 0 | ||
| ; FAULT-NEXT: vfrsqrt.s $vr0, $vr0 | ||
| ; FAULT-NEXT: vst $vr0, $a0, 0 | ||
| ; FAULT-NEXT: ret | ||
| ; | ||
| ; CHECK-LABEL one_div_sqrt_v4f32: | ||
| ; CHECK: # %bb.0: # %entry | ||
| ; CHECK-NEXT: vld $vr0, $a1, 0 | ||
| ; CHECK-NEXT: vfrsqrte.s $vr1, $vr0 | ||
| ; CHECK-NEXT: vfmul.s $vr1, $vr0, $vr1 | ||
| ; CHECK-NEXT: vfmul.s $vr0, $vr0, $vr1 | ||
| ; CHECK-NEXT: lu12i.w $a1, -261120 | ||
| ; CHECK-NEXT: vreplgr2vr.w $vr2, $a1 | ||
| ; CHECK-NEXT: vfmadd.s $vr0, $vr0, $vr1, $vr2 | ||
| ; CHECK-NEXT: lu12i.w $a1, -266240 | ||
| ; CHECK-NEXT: vreplgr2vr.w $vr2, $a1 | ||
| ; CHECK-NEXT: vfmul.s $vr1, $vr1, $vr2 | ||
| ; CHECK-NEXT: vfmul.s $vr0, $vr1, $vr0 | ||
| ; CHECK-NEXT: vst $vr0, $a0, 0 | ||
| ; CHECK-NEXT: ret | ||
| entry: | ||
| %v0 = load <4 x float>, ptr %a0, align 16 | ||
| %sqrt = call fast <4 x float> @llvm.sqrt.v4f32 (<4 x float> %v0) | ||
| %div = fdiv fast <4 x float> <float 1.0, float 1.0, float 1.0, float 1.0>, %sqrt | ||
| store <4 x float> %div, ptr %res, align 16 | ||
| ret void | ||
| } | ||
|
|
||
| define void @one_div_sqrt_v2f64(ptr %res, ptr %a0) nounwind { | ||
| ; FAULT-LABEL: one_div_sqrt_v2f64: | ||
| ; FAULT: # %bb.0: # %entry | ||
| ; FAULT-NEXT: vld $vr0, $a1, 0 | ||
| ; FAULT-NEXT: vfrsqrt.d $vr0, $vr0 | ||
| ; FAULT-NEXT: vst $vr0, $a0, 0 | ||
| ; FAULT-NEXT: ret | ||
| ; | ||
| ; CHECK-LABEL one_div_sqrt_v2f64: | ||
| ; CHECK: # %bb.0: # %entry | ||
| ; CHECK-NEXT: vld $vr0, $a1, 0 | ||
| ; CHECK-NEXT: vfrsqrte.d $vr1, $vr0 | ||
| ; CHECK-NEXT: vfmul.d $vr1, $vr0, $vr1 | ||
| ; CHECK-NEXT: vfmul.d $vr2, $vr0, $vr1 | ||
| ; CHECK-NEXT: ori $a1, $zero, 0 | ||
| ; CHECK-NEXT: lu32i.d $a1, -524288 | ||
| ; CHECK-NEXT: lu52i.d $a1, $a1, -1024 | ||
| ; CHECK-NEXT: vreplgr2vr.d $vr3, $a1 | ||
| ; CHECK-NEXT: vfmadd.d $vr2, $vr2, $vr1, $vr3 | ||
| ; CHECK-NEXT: lu52i.d $a1, $zero, -1026 | ||
| ; CHECK-NEXT: vreplgr2vr.d $vr4, $a1 | ||
| ; CHECK-NEXT: vfmul.d $vr1, $vr1, $vr4 | ||
| ; CHECK-NEXT: vfmul.d $vr1, $vr1, $vr2 | ||
| ; CHECK-NEXT: vfmul.d $vr0, $vr0, $vr1 | ||
| ; CHECK-NEXT: vfmadd.d $vr0, $vr0, $vr1, $vr3 | ||
| ; CHECK-NEXT: vfmul.d $vr1, $vr1, $vr4 | ||
| ; CHECK-NEXT: vfmul.d $vr0, $vr1, $vr0 | ||
| ; CHECK-NEXT: vst $vr0, $a0, 0 | ||
| ; CHECK-NEXT: ret | ||
| entry: | ||
| %v0 = load <2 x double>, ptr %a0, align 16 | ||
| %sqrt = call fast <2 x double> @llvm.sqrt.v2f64 (<2 x double> %v0) | ||
| %div = fdiv fast <2 x double> <double 1.0, double 1.0>, %sqrt | ||
| store <2 x double> %div, ptr %res, align 16 | ||
| ret void | ||
| } | ||
|
|
||
| declare <4 x float> @llvm.sqrt.v4f32(<4 x float>) | ||
| declare <2 x double> @llvm.sqrt.v2f64(<2 x double>) |