khchen updated this revision to Diff 237114.
khchen added a comment.

remote LTO related code.
this PoC include D70837 <https://reviews.llvm.org/D70837> patch for generate 
correct code.


CHANGES SINCE LAST ACTION
  https://reviews.llvm.org/D72245/new/

https://reviews.llvm.org/D72245

Files:
  clang/lib/CodeGen/CodeGenModule.cpp
  clang/test/CodeGen/riscv-metadata.c
  llvm/include/llvm/Target/TargetMachine.h
  llvm/lib/LTO/LTOBackend.cpp
  llvm/lib/Target/RISCV/AsmParser/RISCVAsmParser.cpp
  llvm/lib/Target/RISCV/RISCVISelLowering.cpp
  llvm/lib/Target/RISCV/Utils/RISCVBaseInfo.cpp
  llvm/lib/Target/TargetMachine.cpp
  llvm/test/CodeGen/RISCV/module-target-abi.ll
  llvm/test/CodeGen/RISCV/subtarget-features-std-ext.ll
  llvm/test/CodeGen/RISCV/subtarget-features-target-abi.ll
  llvm/tools/llc/llc.cpp

Index: llvm/tools/llc/llc.cpp
===================================================================
--- llvm/tools/llc/llc.cpp
+++ llvm/tools/llc/llc.cpp
@@ -455,6 +455,7 @@
   Options.MCOptions.PreserveAsmComments = PreserveComments;
   Options.MCOptions.IASSearchPaths = IncludeDirs;
   Options.MCOptions.SplitDwarfFile = SplitDwarfFile;
+  TargetMachine::initTargetOptions(*M, Options);
 
   std::unique_ptr<TargetMachine> Target(TheTarget->createTargetMachine(
       TheTriple.getTriple(), CPUStr, FeaturesStr, Options, getRelocModel(),
Index: llvm/test/CodeGen/RISCV/subtarget-features-target-abi.ll
===================================================================
--- /dev/null
+++ llvm/test/CodeGen/RISCV/subtarget-features-target-abi.ll
@@ -0,0 +1,26 @@
+; RUN: llc -mtriple=riscv32 < %s 2>&1 \
+; RUN:   | FileCheck -check-prefix=DEFAULT %s
+; RUN: llc -mtriple=riscv32 -target-abi ilp32 < %s 2>&1 \
+; RUN:   | FileCheck -check-prefix=RV32IF-ILP32 %s
+; RUN: llc -mtriple=riscv32 -target-abi ilp32f < %s 2>&1 \
+; RUN:   | FileCheck -check-prefix=RV32IF-ILP32F %s
+; RUN: llc -mtriple=riscv32 -filetype=obj < %s | llvm-readelf -h - | FileCheck -check-prefixes=FLAGS %s
+
+; RV32IF-ILP32: -target-abi option != target-abi module flag(ignoring target-abi option)
+
+; FLAGS: Flags: 0x2, single-float ABI
+
+define float @foo(i32 %a) nounwind #0 {
+; DEFAULT: # %bb.0:
+; DEFAULT-NEXT: fcvt.s.w  fa0, a0
+; DEFAULT-NEXT: ret
+; RV32IF-ILP32F: # %bb.0:
+; RV32IF-ILP32F-NEXT: fcvt.s.w  fa0, a0
+; RV32IF-ILP32F-NEXT: ret
+  %conv = sitofp i32 %a to float
+  ret float %conv
+}
+
+attributes #0 = { "target-features"="+f"}
+!llvm.module.flags = !{!0}
+!0 = !{i32 1, !"target-abi", !"ilp32f"}
Index: llvm/test/CodeGen/RISCV/subtarget-features-std-ext.ll
===================================================================
--- llvm/test/CodeGen/RISCV/subtarget-features-std-ext.ll
+++ llvm/test/CodeGen/RISCV/subtarget-features-std-ext.ll
@@ -2,12 +2,17 @@
 ; RUN:   | FileCheck -check-prefix=RV32IF-ILP32 %s
 ; RUN: llc -mtriple=riscv32 -target-abi ilp32f < %s 2>&1 \
 ; RUN:   | FileCheck -check-prefix=RV32IF-ILP32F %s
+; RUN: llc -mtriple=riscv32 -mattr=-f -target-abi ilp32f <%s 2>&1 \
+; RUN:   | FileCheck -check-prefix=RV32I-ILP32F-FAILED %s
+
+; RV32I-ILP32F-FAILED: Hard-float 'f' ABI can't be used for a target that doesn't support the F instruction set extension
 
-; RV32IF-ILP32F: Hard-float 'f' ABI can't be used for a target that doesn't support the F instruction set extension (ignoring target-abi)
 
 define float @foo(i32 %a) nounwind #0 {
-; RV32IF-ILP32: # %bb.0:
-; RV32IF-ILP32-NEXT: fcvt.s.w  ft0, a0
+; RV32IF-ILP32: fcvt.s.w  ft0, a0
+; RV32IF-ILP32-NEXT: fmv.x.w a0, ft0
+; RV32IF-ILP32F: fcvt.s.w fa0, a0
+; RV32IF-ILP32F-NEXT: ret
   %conv = sitofp i32 %a to float
   ret float %conv
 }
Index: llvm/test/CodeGen/RISCV/module-target-abi.ll
===================================================================
--- /dev/null
+++ llvm/test/CodeGen/RISCV/module-target-abi.ll
@@ -0,0 +1,24 @@
+; RUN: llc -mtriple=riscv32 < %s 2>&1 \
+; RUN:   | FileCheck -check-prefix=DEFAULT %s
+; RUN: llc -mtriple=riscv32 -target-abi ilp32 < %s 2>&1 \
+; RUN:   | FileCheck -check-prefix=RV32IF-ILP32 %s
+; RUN: llc -mtriple=riscv32 -target-abi ilp32f < %s 2>&1 \
+; RUN:   | FileCheck -check-prefix=RV32IF-ILP32F %s
+; RUN: llc -mtriple=riscv32 -filetype=obj < %s | llvm-readelf -h - | FileCheck -check-prefixes=FLAGS %s
+
+; RV32IF-ILP32F: -target-abi option != target-abi module flag(ignoring target-abi option)
+
+; FLAGS: Flags: 0x0
+
+define float @foo(i32 %a) nounwind #0 {
+; DEFAULT: # %bb.0:
+; DEFAULT: fmv.x.w a0, ft0
+; RV32IF-ILP32: # %bb.0:
+; RV32IF-ILP32: fmv.x.w a0, ft0
+  %conv = sitofp i32 %a to float
+  ret float %conv
+}
+
+attributes #0 = { "target-features"="+f"}
+!llvm.module.flags = !{!0}
+!0 = !{i32 1, !"target-abi", !"ilp32"}
Index: llvm/lib/Target/TargetMachine.cpp
===================================================================
--- llvm/lib/Target/TargetMachine.cpp
+++ llvm/lib/Target/TargetMachine.cpp
@@ -63,6 +63,19 @@
   RESET_OPTION(NoInfsFPMath, "no-infs-fp-math");
   RESET_OPTION(NoNaNsFPMath, "no-nans-fp-math");
   RESET_OPTION(NoSignedZerosFPMath, "no-signed-zeros-fp-math");
+  TargetMachine::initTargetOptions(*F.getParent(), Options);
+}
+
+void TargetMachine::initTargetOptions(const Module &M, TargetOptions &Options) {
+  if (const MDString *ModuleTargetABI =
+          dyn_cast_or_null<MDString>(M.getModuleFlag("target-abi"))) {
+    if (Options.MCOptions.ABIName != "" &&
+        Options.MCOptions.ABIName != ModuleTargetABI->getString()) {
+      errs() << "warning: -target-abi option != target-abi module "
+                      "flag(ignoring target-abi option)\n";
+    }
+    Options.MCOptions.ABIName = ModuleTargetABI->getString();
+  }
 }
 
 /// Returns the code generation relocation model. The choices are static, PIC,
Index: llvm/lib/Target/RISCV/Utils/RISCVBaseInfo.cpp
===================================================================
--- llvm/lib/Target/RISCV/Utils/RISCVBaseInfo.cpp
+++ llvm/lib/Target/RISCV/Utils/RISCVBaseInfo.cpp
@@ -37,17 +37,8 @@
     errs() << "64-bit ABIs are not supported for 32-bit targets (ignoring "
               "target-abi)\n";
     TargetABI = ABI_Unknown;
-  } else if (ABIName.endswith("f") && !FeatureBits[RISCV::FeatureStdExtF]) {
-    errs() << "Hard-float 'f' ABI can't be used for a target that "
-              "doesn't support the F instruction set extension (ignoring "
-              "target-abi)\n";
-    TargetABI = ABI_Unknown;
-  } else if (ABIName.endswith("d") && !FeatureBits[RISCV::FeatureStdExtD]) {
-    errs() << "Hard-float 'd' ABI can't be used for a target that "
-              "doesn't support the D instruction set extension (ignoring "
-              "target-abi)\n";
-    TargetABI = ABI_Unknown;
   } else if (IsRV32E && TargetABI != ABI_ILP32E && TargetABI != ABI_Unknown) {
+    // TODO: move this checking to RISCVTargetLowering and RISCVAsmParser
     errs()
         << "Only the ilp32e ABI is supported for RV32E (ignoring target-abi)\n";
     TargetABI = ABI_Unknown;
Index: llvm/lib/Target/RISCV/RISCVISelLowering.cpp
===================================================================
--- llvm/lib/Target/RISCV/RISCVISelLowering.cpp
+++ llvm/lib/Target/RISCV/RISCVISelLowering.cpp
@@ -51,6 +51,20 @@
   RISCVABI::ABI ABI = Subtarget.getTargetABI();
   assert(ABI != RISCVABI::ABI_Unknown && "Improperly initialised target ABI");
 
+  if ((ABI == RISCVABI::ABI_ILP32F || ABI == RISCVABI::ABI_LP64F) &&
+      !Subtarget.hasStdExtF()) {
+    errs() << "Hard-float 'f' ABI can't be used for a target that "
+                "doesn't support the F instruction set extension (ignoring "
+                          "target-abi)\n";
+    ABI = Subtarget.is64Bit() ? RISCVABI::ABI_LP64 : RISCVABI::ABI_ILP32;
+  } else if ((ABI == RISCVABI::ABI_ILP32D || ABI == RISCVABI::ABI_LP64D) &&
+             !Subtarget.hasStdExtD()) {
+    errs() << "Hard-float 'd' ABI can't be used for a target that "
+              "doesn't support the D instruction set extension (ignoring "
+              "target-abi)\n";
+    ABI = Subtarget.is64Bit() ? RISCVABI::ABI_LP64 : RISCVABI::ABI_ILP32;
+  }
+
   switch (ABI) {
   default:
     report_fatal_error("Don't know how to lower this ABI");
Index: llvm/lib/Target/RISCV/AsmParser/RISCVAsmParser.cpp
===================================================================
--- llvm/lib/Target/RISCV/AsmParser/RISCVAsmParser.cpp
+++ llvm/lib/Target/RISCV/AsmParser/RISCVAsmParser.cpp
@@ -188,6 +188,18 @@
     Parser.addAliasForDirective(".word", ".4byte");
     Parser.addAliasForDirective(".dword", ".8byte");
     setAvailableFeatures(ComputeAvailableFeatures(STI.getFeatureBits()));
+
+    if (Options.ABIName.back() == 'f' &&
+        !getSTI().getFeatureBits()[RISCV::FeatureStdExtF]) {
+      errs() << "Hard-float 'f' ABI can't be used for a target that "
+                "doesn't support the F instruction set extension (ignoring "
+                "target-abi)\n";
+    } else if (Options.ABIName.back() == 'd' &&
+               !getSTI().getFeatureBits()[RISCV::FeatureStdExtD]) {
+      errs() << "Hard-float 'd' ABI can't be used for a target that "
+                "doesn't support the D instruction set extension (ignoring "
+                "target-abi)\n";
+    }
   }
 };
 
Index: llvm/lib/LTO/LTOBackend.cpp
===================================================================
--- llvm/lib/LTO/LTOBackend.cpp
+++ llvm/lib/LTO/LTOBackend.cpp
@@ -148,6 +148,8 @@
   else
     CodeModel = M.getCodeModel();
 
+  TargetMachine::initTargetOptions(M, Conf.Options);
+
   return std::unique_ptr<TargetMachine>(TheTarget->createTargetMachine(
       TheTriple, Conf.CPU, Features.getString(), Conf.Options, RelocModel,
       CodeModel, Conf.CGOptLevel));
Index: llvm/include/llvm/Target/TargetMachine.h
===================================================================
--- llvm/include/llvm/Target/TargetMachine.h
+++ llvm/include/llvm/Target/TargetMachine.h
@@ -185,6 +185,8 @@
   // from TargetMachine.
   void resetTargetOptions(const Function &F) const;
 
+  static void initTargetOptions(const Module &M, TargetOptions &Options);
+
   /// Return target specific asm information.
   const MCAsmInfo *getMCAsmInfo() const { return AsmInfo.get(); }
 
Index: clang/test/CodeGen/riscv-metadata.c
===================================================================
--- /dev/null
+++ clang/test/CodeGen/riscv-metadata.c
@@ -0,0 +1,14 @@
+// RUN: %clang_cc1 -triple riscv32 -target-abi ilp32 -emit-llvm -o - %s | FileCheck -check-prefix=ILP32 %s
+// RUN: %clang_cc1 -triple riscv32 -target-feature +f -target-abi ilp32f -emit-llvm -o - %s | FileCheck -check-prefix=ILP32F %s
+// RUN: %clang_cc1 -triple riscv32 -target-feature +d -target-abi ilp32d -emit-llvm -o - %s | FileCheck -check-prefix=ILP32D %s
+// RUN: %clang_cc1 -triple riscv64 -target-abi lp64 -emit-llvm -o - %s | FileCheck -check-prefix=LP64 %s
+// RUN: %clang_cc1 -triple riscv64 -target-feature +f -target-abi lp64f -emit-llvm -o - %s | FileCheck -check-prefix=LP64F %s
+// RUN: %clang_cc1 -triple riscv64 -target-feature +d -target-abi lp64d -emit-llvm -o - %s | FileCheck -check-prefix=LP64D %s
+
+// ILP32: !{{[0-9]+}} = !{i32 1, !"target-abi", !"ilp32"}
+// ILP32F: !{{[0-9]+}} = !{i32 1, !"target-abi", !"ilp32f"}
+// ILP32D: !{{[0-9]+}} = !{i32 1, !"target-abi", !"ilp32d"}
+
+// LP64: !{{[0-9]+}} = !{i32 1, !"target-abi", !"lp64"}
+// LP64F: !{{[0-9]+}} = !{i32 1, !"target-abi", !"lp64f"}
+// LP64D: !{{[0-9]+}} = !{i32 1, !"target-abi", !"lp64d"}
Index: clang/lib/CodeGen/CodeGenModule.cpp
===================================================================
--- clang/lib/CodeGen/CodeGenModule.cpp
+++ clang/lib/CodeGen/CodeGenModule.cpp
@@ -537,6 +537,13 @@
     getModule().addModuleFlag(llvm::Module::Error, "min_enum_size", EnumWidth);
   }
 
+  if (Arch == llvm::Triple::riscv32 || Arch == llvm::Triple::riscv64) {
+    StringRef ABIStr = Target.getABI();
+    llvm::LLVMContext &Ctx = TheModule.getContext();
+    getModule().addModuleFlag(llvm::Module::Error, "target-abi",
+                              llvm::MDString::get(Ctx, ABIStr));
+  }
+
   if (CodeGenOpts.SanitizeCfiCrossDso) {
     // Indicate that we want cross-DSO control flow integrity checks.
     getModule().addModuleFlag(llvm::Module::Override, "Cross-DSO CFI", 1);
_______________________________________________
cfe-commits mailing list
cfe-commits@lists.llvm.org
https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits

Reply via email to