[clang] LoongArch fp16,fp128 basic support (PR #68851)

via cfe-commits cfe-commits at lists.llvm.org
Sun Oct 15 22:39:57 PDT 2023


https://github.com/Xinmudotmoe updated https://github.com/llvm/llvm-project/pull/68851

>From 2ef1ddfb977da35f31f1f351ac4daf0478fff166 Mon Sep 17 00:00:00 2001
From: xinmu <xinmu at xinmu.moe>
Date: Thu, 12 Oct 2023 13:36:34 +0800
Subject: [PATCH 1/3] LoongArch fp16,fp128 basic support

---
 clang/lib/Basic/Targets/LoongArch.h                 | 2 ++
 clang/test/CodeGen/fp16-ops.c                       | 1 +
 llvm/lib/Target/LoongArch/LoongArchISelLowering.cpp | 7 +++++++
 3 files changed, 10 insertions(+)

diff --git a/clang/lib/Basic/Targets/LoongArch.h b/clang/lib/Basic/Targets/LoongArch.h
index ba7fb78ab94cd23..b25857207acdedd 100644
--- a/clang/lib/Basic/Targets/LoongArch.h
+++ b/clang/lib/Basic/Targets/LoongArch.h
@@ -40,6 +40,8 @@ class LLVM_LIBRARY_VISIBILITY LoongArchTargetInfo : public TargetInfo {
     SuitableAlign = 128;
     WCharType = SignedInt;
     WIntType = UnsignedInt;
+    HasFloat128 = true;
+    HasFloat16 = true;
   }
 
   bool setCPU(const std::string &Name) override {
diff --git a/clang/test/CodeGen/fp16-ops.c b/clang/test/CodeGen/fp16-ops.c
index 0626e0aaed9d0c0..e230011a59402d4 100644
--- a/clang/test/CodeGen/fp16-ops.c
+++ b/clang/test/CodeGen/fp16-ops.c
@@ -2,6 +2,7 @@
 // RUN: %clang_cc1 -emit-llvm -o - -triple arm-none-linux-gnueabi %s | FileCheck %s --check-prefix=NOTNATIVE --check-prefix=CHECK
 // RUN: %clang_cc1 -emit-llvm -o - -triple aarch64-none-linux-gnueabi %s | FileCheck %s --check-prefix=NOTNATIVE --check-prefix=CHECK
 // RUN: %clang_cc1 -emit-llvm -o - -triple x86_64-linux-gnu %s | FileCheck %s --check-prefix=NOTNATIVE --check-prefix=CHECK
+// RUN: %clang_cc1 -emit-llvm -o - -triple loongarch64-linux-gnu %s | FileCheck %s --check-prefix=NOTNATIVE --check-prefix=CHECK
 // RUN: %clang_cc1 -emit-llvm -o - -triple arm-none-linux-gnueabi -fnative-half-type %s \
 // RUN:   | FileCheck %s --check-prefix=NATIVE-HALF
 // RUN: %clang_cc1 -emit-llvm -o - -triple aarch64-none-linux-gnueabi -fnative-half-type %s \
diff --git a/llvm/lib/Target/LoongArch/LoongArchISelLowering.cpp b/llvm/lib/Target/LoongArch/LoongArchISelLowering.cpp
index 7d01887f24c1597..0295389e1a92e4c 100644
--- a/llvm/lib/Target/LoongArch/LoongArchISelLowering.cpp
+++ b/llvm/lib/Target/LoongArch/LoongArchISelLowering.cpp
@@ -214,6 +214,13 @@ LoongArchTargetLowering::LoongArchTargetLowering(const TargetMachine &TM,
       setOperationAction(ISD::FRINT, MVT::f64, Legal);
   }
 
+  setOperationAction(ISD::FP16_TO_FP,        MVT::f32,   Expand);
+  setOperationAction(ISD::FP_TO_FP16,        MVT::f32,   Expand);
+  setTruncStoreAction(MVT::f32, MVT::f16, Expand);
+  setLoadExtAction(ISD::EXTLOAD, MVT::f32, MVT::f16, Expand);
+  setLibcallName(RTLIB::FPEXT_F16_F32, "__extendhfsf2");
+  setLibcallName(RTLIB::FPROUND_F32_F16, "__truncsfhf2");
+
   // Set operations for 'LSX' feature.
 
   if (Subtarget.hasExtLSX())

>From d198dc7d6086fdd918529d6349b33169cbf59624 Mon Sep 17 00:00:00 2001
From: xinmu <xinmu at xinmu.moe>
Date: Thu, 12 Oct 2023 18:02:53 +0800
Subject: [PATCH 2/3] fix whitespaces lint

---
 llvm/lib/Target/LoongArch/LoongArchISelLowering.cpp | 4 ++--
 1 file changed, 2 insertions(+), 2 deletions(-)

diff --git a/llvm/lib/Target/LoongArch/LoongArchISelLowering.cpp b/llvm/lib/Target/LoongArch/LoongArchISelLowering.cpp
index 0295389e1a92e4c..f03f09127866483 100644
--- a/llvm/lib/Target/LoongArch/LoongArchISelLowering.cpp
+++ b/llvm/lib/Target/LoongArch/LoongArchISelLowering.cpp
@@ -214,8 +214,8 @@ LoongArchTargetLowering::LoongArchTargetLowering(const TargetMachine &TM,
       setOperationAction(ISD::FRINT, MVT::f64, Legal);
   }
 
-  setOperationAction(ISD::FP16_TO_FP,        MVT::f32,   Expand);
-  setOperationAction(ISD::FP_TO_FP16,        MVT::f32,   Expand);
+  setOperationAction(ISD::FP16_TO_FP, MVT::f32, Expand);
+  setOperationAction(ISD::FP_TO_FP16, MVT::f32, Expand);
   setTruncStoreAction(MVT::f32, MVT::f16, Expand);
   setLoadExtAction(ISD::EXTLOAD, MVT::f32, MVT::f16, Expand);
   setLibcallName(RTLIB::FPEXT_F16_F32, "__extendhfsf2");

>From a1739914f8d2017bb6a0141a02ae6c5cf6e9c164 Mon Sep 17 00:00:00 2001
From: xinmu <xinmu at xinmu.moe>
Date: Mon, 16 Oct 2023 13:38:43 +0800
Subject: [PATCH 3/3] [Loongarch] add test unit

---
 clang/test/CodeGen/LoongArch/fp16-fp128-ops.c | 93 +++++++++++++++++++
 clang/test/CodeGen/fp16-ops.c                 |  1 -
 2 files changed, 93 insertions(+), 1 deletion(-)
 create mode 100644 clang/test/CodeGen/LoongArch/fp16-fp128-ops.c

diff --git a/clang/test/CodeGen/LoongArch/fp16-fp128-ops.c b/clang/test/CodeGen/LoongArch/fp16-fp128-ops.c
new file mode 100644
index 000000000000000..678a0cf059342c1
--- /dev/null
+++ b/clang/test/CodeGen/LoongArch/fp16-fp128-ops.c
@@ -0,0 +1,93 @@
+// REQUIRES: loongarch-registered-target
+// RUN: %clang_cc1 -emit-llvm -o - -triple loongarch64-linux-gnu %s  \
+// RUN:    | FileCheck %s --check-prefix=CHECK
+_Float16 ha1 = 0;
+_Float16 ha2 = 1;
+__float128 qa1 = 0;
+__float128 qa2 = 1;
+__float128 qresult = 0;
+_Float16 hresult;
+float fresult;
+double dresult;
+int status;
+
+void fp16_test() {
+  // CHECK-LABEL: @fp16_test
+  // CHECK: [[TMP0:%.*]] = load half, ptr @ha1, align 2
+  // CHECK-NEXT: store half [[TMP0]], ptr @hresult, align 2
+  hresult = ha1;
+  // CHECK: [[TMP1:%.*]] = load half, ptr @ha1, align 2
+  // CHECK-NEXT: [[UP_RESULT:%.*]] = fpext half [[TMP1]] to float
+  // CHECK-NEXT: [[NEG_RESULT:%.*]] = fneg float [[UP_RESULT]]
+  // CHECK-NEXT: [[DOWN_RESULTNEG:%.*]] = fptrunc float [[NEG_RESULT]] to half
+  // CHECK-NEXT: store half [[DOWN_RESULTNEG]], ptr @hresult, align 2
+  hresult = -ha1;
+  // CHECK: [[TMP0:%.*]] = load half, ptr @ha1, align 2
+  // CHECK-NEXT: [[UP1_RESULT:%.*]] = fpext half [[TMP0]] to float
+  // CHECK-NEXT: [[TMP1:%.*]] = load half, ptr @ha2, align 2
+  // CHECK-NEXT: [[UP2_RESULT:%.*]] = fpext half [[TMP1]] to float
+  // CHECK-NEXT: [[RESULT_ADD:%.*]] = fadd float [[UP1_RESULT]], [[UP2_RESULT]]
+  // CHECK-NEXT: [[DOWN_RESULT_ADD:%.*]] = fptrunc float [[RESULT_ADD]] to half
+  // CHECK-NEXT: store half [[DOWN_RESULT_ADD]], ptr @hresult, align 2
+  hresult = ha1 + ha2;
+  // CHECK: [[UP1_RESULT:%.*]] = fpext half {{%.*}} to float
+  // CHECK: [[UP2_RESULT:%.*]] = fpext half {{%.*}} to float
+  // CHECK: {{%.*}} = fsub float [[UP1_RESULT]], [[UP2_RESULT]]
+  hresult = ha1 - ha2;
+  // CHECK: [[UP1_RESULT:%.*]] = fpext half {{%.*}} to float
+  // CHECK: [[UP2_RESULT:%.*]] = fpext half {{%.*}} to float
+  // CHECK: {{%.*}} = fmul float [[UP1_RESULT]], [[UP2_RESULT]]
+  hresult = ha1 * ha2;
+  // CHECK: [[UP1_RESULT:%.*]] = fpext half {{%.*}} to float
+  // CHECK: [[UP2_RESULT:%.*]] = fpext half {{%.*}} to float
+  // CHECK: {{%.*}} = fdiv float [[UP1_RESULT]], [[UP2_RESULT]]
+  hresult = ha1 / ha2;
+  int status = 0;
+  // CHECK: [[TMP:%.*]] = fpext half {{%.*}} to float
+  // CHECK-NEXT: store float [[TMP]], ptr @fresult, align 4
+  fresult = (float)ha1;
+  // CHECK: [[TMP:%.*]] = fpext half {{%.*}} to double
+  // CHECK-NEXT: store double [[TMP]], ptr @dresult, align 8
+  dresult = (double)ha1;
+}
+
+void fp128_test() {
+  // CHECK-LABEL: @fp128_test
+  // CHECK: [[TMPQ0:%.*]] = load fp128, ptr {{@.*}}, align 16
+  // CHECK-NEXT: store fp128 [[TMPQ0]], ptr {{@.*}}, align 16
+  qresult = qa1;
+  // CHECK: [[TMPQ0:%.*]] = load fp128, ptr {{@.*}}, align 16
+  // CHECK-NEXT: [[NEG_RESULT:%.*]] = fneg fp128 [[TMPQ0]]
+  // CHECK-NEXT: store fp128 [[NEG_RESULT]], ptr {{@.*}}, align 16
+  qresult = -qa1;
+  // CHECK: [[TMPQ0:%.*]] = load fp128, ptr {{@.*}}, align 16
+  // CHECK-NEXT: [[TMPQ1:%.*]] = load fp128, ptr {{@.*}}, align 16
+  // CHECK-NEXT: [[ADD_RESULT:%.*]] = fadd fp128 [[TMPQ0]], [[TMPQ1]]
+  // CHECK-NEXT: store fp128 [[ADD_RESULT]], ptr {{@.*}}, align 16
+  qresult = qa1 + qa2;
+  // CHECK: [[TMPQ0:%.*]] = load fp128, ptr {{@.*}}, align 16
+  // CHECK-NEXT: [[TMPQ1:%.*]] = load fp128, ptr {{@.*}}, align 16
+  // CHECK-NEXT: [[SUB_RESULT:%.*]] = fsub fp128 [[TMPQ0]], [[TMPQ1]]
+  // CHECK-NEXT: store fp128 [[SUB_RESULT]], ptr {{@.*}}, align 16
+  qresult = qa1 - qa2;
+  // CHECK: [[TMPQ0:%.*]] = load fp128, ptr {{@.*}}, align 16
+  // CHECK-NEXT: [[TMPQ1:%.*]] = load fp128, ptr {{@.*}}, align 16
+  // CHECK-NEXT: [[MUL_RESULT:%.*]] = fmul fp128 [[TMPQ0]], [[TMPQ1]]
+  // CHECK-NEXT: store fp128 [[MUL_RESULT]], ptr {{@.*}}, align 16
+  qresult = qa1 * qa2;
+  // CHECK: [[TMPQ0:%.*]] = load fp128, ptr {{@.*}}, align 16
+  // CHECK-NEXT: [[TMPQ1:%.*]] = load fp128, ptr {{@.*}}, align 16
+  // CHECK-NEXT: [[DIV_RESULT:%.*]] = fdiv fp128 [[TMPQ0]], [[TMPQ1]]
+  // CHECK-NEXT: store fp128 [[DIV_RESULT]], ptr {{@.*}}, align 16
+  qresult = qa1 / qa2;
+  // CHECK: [[TMPQ0:%.*]] = load fp128, ptr {{@.*}}, align 16
+  // CHECK-NEXT: [[RESULT:%.*]] = fptrunc fp128 [[TMPQ0]] to float
+  // CHECK-NEXT: store float [[RESULT]], ptr {{@.*}}, align 4
+
+  fresult = (float)qa1;
+  // CHECK: [[TMPQ0:%.*]] = load fp128, ptr {{@.*}}, align 16
+  // CHECK-NEXT: [[RESULT:%.*]] = fptrunc fp128 [[TMPQ0]] to double
+  // CHECK-NEXT: store double [[RESULT]], ptr {{@.*}}, align 8
+  dresult = (double)qa1;
+}
+
diff --git a/clang/test/CodeGen/fp16-ops.c b/clang/test/CodeGen/fp16-ops.c
index e230011a59402d4..0626e0aaed9d0c0 100644
--- a/clang/test/CodeGen/fp16-ops.c
+++ b/clang/test/CodeGen/fp16-ops.c
@@ -2,7 +2,6 @@
 // RUN: %clang_cc1 -emit-llvm -o - -triple arm-none-linux-gnueabi %s | FileCheck %s --check-prefix=NOTNATIVE --check-prefix=CHECK
 // RUN: %clang_cc1 -emit-llvm -o - -triple aarch64-none-linux-gnueabi %s | FileCheck %s --check-prefix=NOTNATIVE --check-prefix=CHECK
 // RUN: %clang_cc1 -emit-llvm -o - -triple x86_64-linux-gnu %s | FileCheck %s --check-prefix=NOTNATIVE --check-prefix=CHECK
-// RUN: %clang_cc1 -emit-llvm -o - -triple loongarch64-linux-gnu %s | FileCheck %s --check-prefix=NOTNATIVE --check-prefix=CHECK
 // RUN: %clang_cc1 -emit-llvm -o - -triple arm-none-linux-gnueabi -fnative-half-type %s \
 // RUN:   | FileCheck %s --check-prefix=NATIVE-HALF
 // RUN: %clang_cc1 -emit-llvm -o - -triple aarch64-none-linux-gnueabi -fnative-half-type %s \



More information about the cfe-commits mailing list