[llvm] 3ed1223 - [VE] half fptrunc+store&load+fpext
Simon Moll via llvm-commits
llvm-commits at lists.llvm.org
Tue Feb 4 08:17:04 PST 2020
Author: Kazushi (Jam) Marukawa
Date: 2020-02-04T17:16:09+01:00
New Revision: 3ed12232b03721dd70ff6e88b10a016c7f2a915e
URL: https://github.com/llvm/llvm-project/commit/3ed12232b03721dd70ff6e88b10a016c7f2a915e
DIFF: https://github.com/llvm/llvm-project/commit/3ed12232b03721dd70ff6e88b10a016c7f2a915e.diff
LOG: [VE] half fptrunc+store&load+fpext
Summary:
fp16 (half) load+fpext and fptrunc+store isel legalization and tests.
Also, ExternalSymbolSDNode operand printing (tested by fp16 lowering).
Reviewed By: arsenm
Differential Revision: https://reviews.llvm.org/D73899
Added:
Modified:
llvm/lib/Target/VE/VEISelLowering.cpp
llvm/lib/Target/VE/VEInstrInfo.td
llvm/lib/Target/VE/VEMCInstLower.cpp
llvm/test/CodeGen/VE/fp_extload_truncstore.ll
Removed:
################################################################################
diff --git a/llvm/lib/Target/VE/VEISelLowering.cpp b/llvm/lib/Target/VE/VEISelLowering.cpp
index a82701ac4c07..92d0fc2419d4 100644
--- a/llvm/lib/Target/VE/VEISelLowering.cpp
+++ b/llvm/lib/Target/VE/VEISelLowering.cpp
@@ -523,10 +523,14 @@ VETargetLowering::VETargetLowering(const TargetMachine &TM,
addRegisterClass(MVT::f64, &VE::I64RegClass);
/// Load & Store {
- // Turn FP extload into load/fpextend
- for (MVT VT : MVT::fp_valuetypes()) {
- setLoadExtAction(ISD::EXTLOAD, VT, MVT::f32, Expand);
- setLoadExtAction(ISD::EXTLOAD, VT, MVT::f64, Expand);
+ for (MVT FPVT : MVT::fp_valuetypes()) {
+ for (MVT OtherFPVT : MVT::fp_valuetypes()) {
+ // Turn FP extload into load/fpextend
+ setLoadExtAction(ISD::EXTLOAD, FPVT, OtherFPVT, Expand);
+
+ // Turn FP truncstore into trunc + store.
+ setTruncStoreAction(FPVT, OtherFPVT, Expand);
+ }
}
// VE doesn't have i1 sign extending load
@@ -536,9 +540,6 @@ VETargetLowering::VETargetLowering(const TargetMachine &TM,
setLoadExtAction(ISD::EXTLOAD, VT, MVT::i1, Promote);
setTruncStoreAction(VT, MVT::i1, Expand);
}
-
- // Turn FP truncstore into trunc + store.
- setTruncStoreAction(MVT::f64, MVT::f32, Expand);
/// } Load & Store
// Custom legalize address nodes into LO/HI parts.
@@ -563,12 +564,20 @@ VETargetLowering::VETargetLowering(const TargetMachine &TM,
setOperationAction(ISD::UDIVREM, IntVT, Expand);
}
+ /// Conversion {
// VE doesn't have instructions for fp<->uint, so expand them by llvm
setOperationAction(ISD::FP_TO_UINT, MVT::i32, Promote); // use i64
setOperationAction(ISD::UINT_TO_FP, MVT::i32, Promote); // use i64
setOperationAction(ISD::FP_TO_UINT, MVT::i64, Expand);
setOperationAction(ISD::UINT_TO_FP, MVT::i64, Expand);
+ // fp16 not supported
+ for (MVT FPVT : MVT::fp_valuetypes()) {
+ setOperationAction(ISD::FP16_TO_FP, FPVT, Expand);
+ setOperationAction(ISD::FP_TO_FP16, FPVT, Expand);
+ }
+ /// } Conversion
+
setStackPointerRegisterToSaveRestore(VE::SX11);
// Set function alignment to 16 bytes
@@ -612,6 +621,10 @@ SDValue VETargetLowering::withTargetFlags(SDValue Op, unsigned TF,
return DAG.getTargetBlockAddress(BA->getBlockAddress(), Op.getValueType(),
0, TF);
+ if (const ExternalSymbolSDNode *ES = dyn_cast<ExternalSymbolSDNode>(Op))
+ return DAG.getTargetExternalSymbol(ES->getSymbol(), ES->getValueType(0),
+ TF);
+
llvm_unreachable("Unhandled address SDNode");
}
diff --git a/llvm/lib/Target/VE/VEInstrInfo.td b/llvm/lib/Target/VE/VEInstrInfo.td
index 1cee47d87d73..a64fa5f54547 100644
--- a/llvm/lib/Target/VE/VEInstrInfo.td
+++ b/llvm/lib/Target/VE/VEInstrInfo.td
@@ -1129,6 +1129,13 @@ def : Pat<(add (VEhi tglobaladdr:$in1), (VElo tglobaladdr:$in2)),
(LEASLrzi (ANDrm0 (LEAzzi tglobaladdr:$in2), 32),
(tglobaladdr:$in1))>;
+// Address calculation and its optimization
+def : Pat<(VEhi texternalsym:$in), (LEASLzzi texternalsym:$in)>;
+def : Pat<(VElo texternalsym:$in), (ANDrm0 (LEAzzi texternalsym:$in), 32)>;
+def : Pat<(add (VEhi texternalsym:$in1), (VElo texternalsym:$in2)),
+ (LEASLrzi (ANDrm0 (LEAzzi texternalsym:$in2), 32),
+ (texternalsym:$in1))>;
+
// Calls
def : Pat<(call tglobaladdr:$dst),
(CALL tglobaladdr:$dst)>;
diff --git a/llvm/lib/Target/VE/VEMCInstLower.cpp b/llvm/lib/Target/VE/VEMCInstLower.cpp
index 10bfb88ad009..389e77f913fe 100644
--- a/llvm/lib/Target/VE/VEMCInstLower.cpp
+++ b/llvm/lib/Target/VE/VEMCInstLower.cpp
@@ -46,6 +46,9 @@ static MCOperand LowerOperand(const MachineInstr *MI, const MachineOperand &MO,
break;
return MCOperand::createReg(MO.getReg());
+ case MachineOperand::MO_ExternalSymbol:
+ return LowerSymbolOperand(
+ MI, MO, AP.GetExternalSymbolSymbol(MO.getSymbolName()), AP);
case MachineOperand::MO_GlobalAddress:
return LowerSymbolOperand(MI, MO, AP.getSymbol(MO.getGlobal()), AP);
case MachineOperand::MO_Immediate:
diff --git a/llvm/test/CodeGen/VE/fp_extload_truncstore.ll b/llvm/test/CodeGen/VE/fp_extload_truncstore.ll
index cc6a6597b8ee..bedccef86bf7 100644
--- a/llvm/test/CodeGen/VE/fp_extload_truncstore.ll
+++ b/llvm/test/CodeGen/VE/fp_extload_truncstore.ll
@@ -1,5 +1,113 @@
; RUN: llc < %s -mtriple=ve-unknown-unknown | FileCheck %s
+declare i16 @llvm.convert.to.fp16.f32(float %a)
+declare i16 @llvm.convert.to.fp16.f64(double %a)
+
+declare float @llvm.convert.from.fp16.f32(i16 %a)
+declare double @llvm.convert.from.fp16.f64(i16 %a)
+
+define float @func_i16fp32(i16* %a) {
+; CHECK-LABEL: func_i16fp32:
+; CHECK: .LBB{{[0-9]+}}_2:
+; CHECK-NEXT: ld2b.zx %s0, (,%s0)
+; CHECK-NEXT: lea %s1, __gnu_h2f_ieee at lo
+; CHECK-NEXT: and %s1, %s1, (32)0
+; CHECK-NEXT: lea.sl %s12, __gnu_h2f_ieee at hi(%s1)
+; CHECK-NEXT: bsic %lr, (,%s12)
+; CHECK-NEXT: or %s11, 0, %s9
+ %a.val = load i16, i16* %a, align 4
+ %a.asd = call float @llvm.convert.from.fp16.f32(i16 %a.val)
+ ret float %a.asd
+}
+
+define double @func_i16fp64(i16* %a) {
+; CHECK-LABEL: func_i16fp64:
+; CHECK: .LBB{{[0-9]+}}_2:
+; CHECK-NEXT: ld2b.zx %s0, (,%s0)
+; CHECK-NEXT: lea %s1, __gnu_h2f_ieee at lo
+; CHECK-NEXT: and %s1, %s1, (32)0
+; CHECK-NEXT: lea.sl %s12, __gnu_h2f_ieee at hi(%s1)
+; CHECK-NEXT: bsic %lr, (,%s12)
+; CHECK-NEXT: cvt.d.s %s0, %s0
+; CHECK-NEXT: or %s11, 0, %s9
+ %a.val = load i16, i16* %a, align 4
+ %a.asd = call double @llvm.convert.from.fp16.f64(i16 %a.val)
+ ret double %a.asd
+}
+
+define float @func_fp16fp32(half* %a) {
+; CHECK-LABEL: func_fp16fp32:
+; CHECK: .LBB{{[0-9]+}}_2:
+; CHECK-NEXT: ld2b.zx %s0, (,%s0)
+; CHECK-NEXT: lea %s1, __gnu_h2f_ieee at lo
+; CHECK-NEXT: and %s1, %s1, (32)0
+; CHECK-NEXT: lea.sl %s12, __gnu_h2f_ieee at hi(%s1)
+; CHECK-NEXT: bsic %lr, (,%s12)
+; CHECK-NEXT: or %s11, 0, %s9
+ %a.val = load half, half* %a, align 4
+ %a.asd = fpext half %a.val to float
+ ret float %a.asd
+}
+
+define double @func_fp16fp64(half* %a) {
+; CHECK-LABEL: func_fp16fp64:
+; CHECK: .LBB{{[0-9]+}}_2:
+; CHECK-NEXT: ld2b.zx %s0, (,%s0)
+; CHECK-NEXT: lea %s1, __gnu_h2f_ieee at lo
+; CHECK-NEXT: and %s1, %s1, (32)0
+; CHECK-NEXT: lea.sl %s12, __gnu_h2f_ieee at hi(%s1)
+; CHECK-NEXT: bsic %lr, (,%s12)
+; CHECK-NEXT: cvt.d.s %s0, %s0
+; CHECK-NEXT: or %s11, 0, %s9
+ %a.val = load half, half* %a, align 4
+ %a.asd = fpext half %a.val to double
+ ret double %a.asd
+}
+
+define void @func_fp32i16(i16* %fl.ptr, float %val) {
+; CHECK-LABEL: func_fp32i16:
+; CHECK: .LBB{{[0-9]+}}_2:
+; CHECK-NEXT: st %s18, 48(,%s9) # 8-byte Folded Spill
+; CHECK-NEXT: or %s18, 0, %s0
+; CHECK-NEXT: lea %s0, __gnu_f2h_ieee at lo
+; CHECK-NEXT: and %s0, %s0, (32)0
+; CHECK-NEXT: lea.sl %s12, __gnu_f2h_ieee at hi(%s0)
+; CHECK-NEXT: or %s0, 0, %s1
+; CHECK-NEXT: bsic %lr, (,%s12)
+; CHECK-NEXT: st2b %s0, (,%s18)
+; CHECK-NEXT: ld %s18, 48(,%s9) # 8-byte Folded Reload
+; CHECK-NEXT: or %s11, 0, %s9
+ %val.asf = call i16 @llvm.convert.to.fp16.f32(float %val)
+ store i16 %val.asf, i16* %fl.ptr
+ ret void
+}
+
+define half @func_fp32fp16(half* %fl.ptr, float %a) {
+; CHECK-LABEL: func_fp32fp16:
+; CHECK: .LBB{{[0-9]+}}_2:
+; CHECK-NEXT: st %s18, 48(,%s9) # 8-byte Folded Spill
+; CHECK-NEXT: st %s19, 56(,%s9) # 8-byte Folded Spill
+; CHECK-NEXT: or %s18, 0, %s0
+; CHECK-NEXT: lea %s0, __gnu_f2h_ieee at lo
+; CHECK-NEXT: and %s0, %s0, (32)0
+; CHECK-NEXT: lea.sl %s12, __gnu_f2h_ieee at hi(%s0)
+; CHECK-NEXT: or %s0, 0, %s1
+; CHECK-NEXT: bsic %lr, (,%s12)
+; CHECK-NEXT: or %s19, 0, %s0
+; CHECK-NEXT: lea %s0, __gnu_h2f_ieee at lo
+; CHECK-NEXT: and %s0, %s0, (32)0
+; CHECK-NEXT: lea.sl %s12, __gnu_h2f_ieee at hi(%s0)
+; CHECK-NEXT: or %s0, 0, %s19
+; CHECK-NEXT: bsic %lr, (,%s12)
+; CHECK-NEXT: st2b %s19, (,%s18)
+; CHECK-NEXT: ld %s19, 56(,%s9) # 8-byte Folded Reload
+; CHECK-NEXT: ld %s18, 48(,%s9) # 8-byte Folded Reload
+; CHECK-NEXT: or %s11, 0, %s9
+ %a.asd = fptrunc float %a to half
+ store half %a.asd, half* %fl.ptr
+ ret half %a.asd
+}
+
define double @func_fp32fp64(float* %a) {
; CHECK-LABEL: func_fp32fp64:
; CHECK: .LBB{{[0-9]+}}_2:
@@ -11,6 +119,42 @@ define double @func_fp32fp64(float* %a) {
ret double %a.asd
}
+define void @func_fp64i16(i16* %fl.ptr, double %val) {
+; CHECK-LABEL: func_fp64i16:
+; CHECK: .LBB{{[0-9]+}}_2:
+; CHECK-NEXT: st %s18, 48(,%s9) # 8-byte Folded Spill
+; CHECK-NEXT: or %s18, 0, %s0
+; CHECK-NEXT: lea %s0, __truncdfhf2 at lo
+; CHECK-NEXT: and %s0, %s0, (32)0
+; CHECK-NEXT: lea.sl %s12, __truncdfhf2 at hi(%s0)
+; CHECK-NEXT: or %s0, 0, %s1
+; CHECK-NEXT: bsic %lr, (,%s12)
+; CHECK-NEXT: st2b %s0, (,%s18)
+; CHECK-NEXT: ld %s18, 48(,%s9) # 8-byte Folded Reload
+; CHECK-NEXT: or %s11, 0, %s9
+ %val.asf = call i16 @llvm.convert.to.fp16.f64(double %val)
+ store i16 %val.asf, i16* %fl.ptr
+ ret void
+}
+
+define void @func_fp64fp16(half* %fl.ptr, double %val) {
+; CHECK-LABEL: func_fp64fp16:
+; CHECK: .LBB{{[0-9]+}}_2:
+; CHECK-NEXT: st %s18, 48(,%s9) # 8-byte Folded Spill
+; CHECK-NEXT: or %s18, 0, %s0
+; CHECK-NEXT: lea %s0, __truncdfhf2 at lo
+; CHECK-NEXT: and %s0, %s0, (32)0
+; CHECK-NEXT: lea.sl %s12, __truncdfhf2 at hi(%s0)
+; CHECK-NEXT: or %s0, 0, %s1
+; CHECK-NEXT: bsic %lr, (,%s12)
+; CHECK-NEXT: st2b %s0, (,%s18)
+; CHECK-NEXT: ld %s18, 48(,%s9) # 8-byte Folded Reload
+; CHECK-NEXT: or %s11, 0, %s9
+ %val.asf = fptrunc double %val to half
+ store half %val.asf, half* %fl.ptr
+ ret void
+}
+
define void @func_fp64fp32(float* %fl.ptr, double %val) {
; CHECK-LABEL: func_fp64fp32:
; CHECK: .LBB{{[0-9]+}}_2:
More information about the llvm-commits
mailing list