[llvm] r336171 - [llvm-exegesis] ExegisX86Target::setRegToConstant() should depend on the subtarget features.

Clement Courbet via llvm-commits llvm-commits at lists.llvm.org
Mon Jul 2 23:17:05 PDT 2018


Author: courbet
Date: Mon Jul  2 23:17:05 2018
New Revision: 336171

URL: http://llvm.org/viewvc/llvm-project?rev=336171&view=rev
Log:
[llvm-exegesis] ExegisX86Target::setRegToConstant() should depend on the subtarget features.

Summary: This fixes PR38008.

Reviewers: gchatelet, RKSimon

Subscribers: tschuett, craig.topper, llvm-commits

Differential Revision: https://reviews.llvm.org/D48820

Modified:
    llvm/trunk/tools/llvm-exegesis/lib/Assembler.cpp
    llvm/trunk/tools/llvm-exegesis/lib/Target.h
    llvm/trunk/tools/llvm-exegesis/lib/X86/Target.cpp
    llvm/trunk/unittests/tools/llvm-exegesis/X86/TargetTest.cpp

Modified: llvm/trunk/tools/llvm-exegesis/lib/Assembler.cpp
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/tools/llvm-exegesis/lib/Assembler.cpp?rev=336171&r1=336170&r2=336171&view=diff
==============================================================================
--- llvm/trunk/tools/llvm-exegesis/lib/Assembler.cpp (original)
+++ llvm/trunk/tools/llvm-exegesis/lib/Assembler.cpp Mon Jul  2 23:17:05 2018
@@ -30,12 +30,13 @@ static constexpr const char FunctionID[]
 
 static std::vector<llvm::MCInst>
 generateSnippetSetupCode(const llvm::ArrayRef<unsigned> RegsToDef,
-                         const ExegesisTarget &ET, bool &IsComplete) {
+                         const ExegesisTarget &ET,
+                         const llvm::LLVMTargetMachine &TM, bool &IsComplete) {
   IsComplete = true;
   std::vector<llvm::MCInst> Result;
   for (const unsigned Reg : RegsToDef) {
     // Load a constant in the register.
-    const auto Code = ET.setRegToConstant(Reg);
+    const auto Code = ET.setRegToConstant(*TM.getMCSubtargetInfo(), Reg);
     if (Code.empty())
       IsComplete = false;
     Result.insert(Result.end(), Code.begin(), Code.end());
@@ -159,7 +160,7 @@ void assembleToStream(const ExegesisTarg
   Properties.reset(llvm::MachineFunctionProperties::Property::IsSSA);
   bool IsSnippetSetupComplete = false;
   std::vector<llvm::MCInst> SnippetWithSetup =
-      generateSnippetSetupCode(RegsToDef, ET, IsSnippetSetupComplete);
+      generateSnippetSetupCode(RegsToDef, ET, *TM, IsSnippetSetupComplete);
   if (!SnippetWithSetup.empty()) {
     SnippetWithSetup.insert(SnippetWithSetup.end(), Instructions.begin(),
                             Instructions.end());

Modified: llvm/trunk/tools/llvm-exegesis/lib/Target.h
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/tools/llvm-exegesis/lib/Target.h?rev=336171&r1=336170&r2=336171&view=diff
==============================================================================
--- llvm/trunk/tools/llvm-exegesis/lib/Target.h (original)
+++ llvm/trunk/tools/llvm-exegesis/lib/Target.h Mon Jul  2 23:17:05 2018
@@ -34,7 +34,8 @@ public:
   virtual void addTargetSpecificPasses(llvm::PassManagerBase &PM) const {}
 
   // Generates code to move a constant into a the given register.
-  virtual std::vector<llvm::MCInst> setRegToConstant(unsigned Reg) const {
+  virtual std::vector<llvm::MCInst>
+  setRegToConstant(const llvm::MCSubtargetInfo &STI, unsigned Reg) const {
     return {};
   }
 

Modified: llvm/trunk/tools/llvm-exegesis/lib/X86/Target.cpp
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/tools/llvm-exegesis/lib/X86/Target.cpp?rev=336171&r1=336170&r2=336171&view=diff
==============================================================================
--- llvm/trunk/tools/llvm-exegesis/lib/X86/Target.cpp (original)
+++ llvm/trunk/tools/llvm-exegesis/lib/X86/Target.cpp Mon Jul  2 23:17:05 2018
@@ -14,6 +14,7 @@
 #include "MCTargetDesc/X86MCTargetDesc.h"
 #include "X86.h"
 #include "X86RegisterInfo.h"
+#include "X86Subtarget.h"
 #include "llvm/MC/MCInstBuilder.h"
 
 namespace exegesis {
@@ -130,8 +131,9 @@ class ExegesisX86Target : public Exegesi
     PM.add(llvm::createX86FloatingPointStackifierPass());
   }
 
-  std::vector<llvm::MCInst>
-  setRegToConstant(unsigned Reg) const override {
+  std::vector<llvm::MCInst> setRegToConstant(const llvm::MCSubtargetInfo &STI,
+                                             unsigned Reg) const override {
+    // GPR.
     if (llvm::X86::GR8RegClass.contains(Reg))
       return {llvm::MCInstBuilder(llvm::X86::MOV8ri).addReg(Reg).addImm(1)};
     if (llvm::X86::GR16RegClass.contains(Reg))
@@ -140,12 +142,25 @@ class ExegesisX86Target : public Exegesi
       return {llvm::MCInstBuilder(llvm::X86::MOV32ri).addReg(Reg).addImm(1)};
     if (llvm::X86::GR64RegClass.contains(Reg))
       return {llvm::MCInstBuilder(llvm::X86::MOV64ri32).addReg(Reg).addImm(1)};
-    if (llvm::X86::VR128XRegClass.contains(Reg))
-      return setVectorRegToConstant(Reg, 16, llvm::X86::VMOVDQUrm);
-    if (llvm::X86::VR256XRegClass.contains(Reg))
+    // MMX.
+    if (llvm::X86::VR64RegClass.contains(Reg))
+      return setVectorRegToConstant(Reg, 8, llvm::X86::MMX_MOVQ64rm);
+    // {X,Y,Z}MM.
+    if (llvm::X86::VR128XRegClass.contains(Reg)) {
+      if (STI.getFeatureBits()[llvm::X86::FeatureAVX512])
+        return setVectorRegToConstant(Reg, 16, llvm::X86::VMOVDQU32Z128rm);
+      if (STI.getFeatureBits()[llvm::X86::FeatureAVX])
+        return setVectorRegToConstant(Reg, 16, llvm::X86::VMOVDQUrm);
+      return setVectorRegToConstant(Reg, 16, llvm::X86::MOVDQUrm);
+    }
+    if (llvm::X86::VR256XRegClass.contains(Reg)) {
+      if (STI.getFeatureBits()[llvm::X86::FeatureAVX512])
+        return setVectorRegToConstant(Reg, 32, llvm::X86::VMOVDQU32Z256rm);
       return setVectorRegToConstant(Reg, 32, llvm::X86::VMOVDQUYrm);
+    }
     if (llvm::X86::VR512RegClass.contains(Reg))
-      return setVectorRegToConstant(Reg, 64, llvm::X86::VMOVDQU64Zrm);
+      return setVectorRegToConstant(Reg, 64, llvm::X86::VMOVDQU32Zrm);
+    // X87.
     if (llvm::X86::RFP32RegClass.contains(Reg) ||
         llvm::X86::RFP64RegClass.contains(Reg) ||
         llvm::X86::RFP80RegClass.contains(Reg))
@@ -155,8 +170,7 @@ class ExegesisX86Target : public Exegesi
 
   std::unique_ptr<BenchmarkRunner>
   createLatencyBenchmarkRunner(const LLVMState &State) const override {
-    return llvm::make_unique<X86BenchmarkRunner<X86LatencyImpl>>(
-        State);
+    return llvm::make_unique<X86BenchmarkRunner<X86LatencyImpl>>(State);
   }
 
   std::unique_ptr<BenchmarkRunner>

Modified: llvm/trunk/unittests/tools/llvm-exegesis/X86/TargetTest.cpp
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/unittests/tools/llvm-exegesis/X86/TargetTest.cpp?rev=336171&r1=336170&r2=336171&view=diff
==============================================================================
--- llvm/trunk/unittests/tools/llvm-exegesis/X86/TargetTest.cpp (original)
+++ llvm/trunk/unittests/tools/llvm-exegesis/X86/TargetTest.cpp Mon Jul  2 23:17:05 2018
@@ -4,6 +4,8 @@
 #include <memory>
 
 #include "MCTargetDesc/X86MCTargetDesc.h"
+#include "llvm/Support/TargetRegistry.h"
+#include "llvm/Support/TargetSelect.h"
 #include "gmock/gmock.h"
 #include "gtest/gtest.h"
 
@@ -17,27 +19,151 @@ using testing::Gt;
 using testing::NotNull;
 using testing::SizeIs;
 
+constexpr const char kTriple[] = "x86_64-unknown-linux";
+
 class X86TargetTest : public ::testing::Test {
 protected:
   X86TargetTest()
-      : Target_(ExegesisTarget::lookup(llvm::Triple("x86_64-unknown-linux"))) {
+      : ExegesisTarget_(ExegesisTarget::lookup(llvm::Triple(kTriple))) {
+    EXPECT_THAT(ExegesisTarget_, NotNull());
+    std::string error;
+    Target_ = llvm::TargetRegistry::lookupTarget(kTriple, error);
     EXPECT_THAT(Target_, NotNull());
   }
-  static void SetUpTestCase() { InitializeX86ExegesisTarget(); }
+  static void SetUpTestCase() {
+    LLVMInitializeX86TargetInfo();
+    LLVMInitializeX86Target();
+    LLVMInitializeX86TargetMC();
+    InitializeX86ExegesisTarget();
+  }
 
-  const ExegesisTarget *const Target_;
+  const llvm::Target *Target_;
+  const ExegesisTarget *const ExegesisTarget_;
 };
 
 TEST_F(X86TargetTest, SetRegToConstantGPR) {
-  const auto Insts = Target_->setRegToConstant(llvm::X86::EAX);
+  const std::unique_ptr<llvm::MCSubtargetInfo> STI(
+      Target_->createMCSubtargetInfo(kTriple, "core2", ""));
+  const auto Insts = ExegesisTarget_->setRegToConstant(*STI, llvm::X86::EAX);
   EXPECT_THAT(Insts, SizeIs(1));
   EXPECT_EQ(Insts[0].getOpcode(), llvm::X86::MOV32ri);
   EXPECT_EQ(Insts[0].getOperand(0).getReg(), llvm::X86::EAX);
 }
 
-TEST_F(X86TargetTest, SetRegToConstantXMM) {
-  const auto Insts = Target_->setRegToConstant(llvm::X86::XMM1);
-  EXPECT_THAT(Insts, SizeIs(Gt(0U)));
+TEST_F(X86TargetTest, SetRegToConstantXMM_SSE2) {
+  const std::unique_ptr<llvm::MCSubtargetInfo> STI(
+      Target_->createMCSubtargetInfo(kTriple, "core2", ""));
+  const auto Insts = ExegesisTarget_->setRegToConstant(*STI, llvm::X86::XMM1);
+  EXPECT_THAT(Insts, SizeIs(7U));
+  EXPECT_EQ(Insts[0].getOpcode(), llvm::X86::SUB64ri8);
+  EXPECT_EQ(Insts[1].getOpcode(), llvm::X86::MOV32mi);
+  EXPECT_EQ(Insts[2].getOpcode(), llvm::X86::MOV32mi);
+  EXPECT_EQ(Insts[3].getOpcode(), llvm::X86::MOV32mi);
+  EXPECT_EQ(Insts[4].getOpcode(), llvm::X86::MOV32mi);
+  EXPECT_EQ(Insts[5].getOpcode(), llvm::X86::MOVDQUrm);
+  EXPECT_EQ(Insts[6].getOpcode(), llvm::X86::ADD64ri8);
+}
+
+TEST_F(X86TargetTest, SetRegToConstantXMM_AVX) {
+  const std::unique_ptr<llvm::MCSubtargetInfo> STI(
+      Target_->createMCSubtargetInfo(kTriple, "core2", "+avx"));
+  const auto Insts = ExegesisTarget_->setRegToConstant(*STI, llvm::X86::XMM1);
+  EXPECT_THAT(Insts, SizeIs(7U));
+  EXPECT_EQ(Insts[0].getOpcode(), llvm::X86::SUB64ri8);
+  EXPECT_EQ(Insts[1].getOpcode(), llvm::X86::MOV32mi);
+  EXPECT_EQ(Insts[2].getOpcode(), llvm::X86::MOV32mi);
+  EXPECT_EQ(Insts[3].getOpcode(), llvm::X86::MOV32mi);
+  EXPECT_EQ(Insts[4].getOpcode(), llvm::X86::MOV32mi);
+  EXPECT_EQ(Insts[5].getOpcode(), llvm::X86::VMOVDQUrm);
+  EXPECT_EQ(Insts[6].getOpcode(), llvm::X86::ADD64ri8);
+}
+
+TEST_F(X86TargetTest, SetRegToConstantXMM_AVX512) {
+  const std::unique_ptr<llvm::MCSubtargetInfo> STI(
+      Target_->createMCSubtargetInfo(kTriple, "core2", "+avx512vl"));
+  const auto Insts = ExegesisTarget_->setRegToConstant(*STI, llvm::X86::XMM1);
+  EXPECT_THAT(Insts, SizeIs(7U));
+  EXPECT_EQ(Insts[0].getOpcode(), llvm::X86::SUB64ri8);
+  EXPECT_EQ(Insts[1].getOpcode(), llvm::X86::MOV32mi);
+  EXPECT_EQ(Insts[2].getOpcode(), llvm::X86::MOV32mi);
+  EXPECT_EQ(Insts[3].getOpcode(), llvm::X86::MOV32mi);
+  EXPECT_EQ(Insts[4].getOpcode(), llvm::X86::MOV32mi);
+  EXPECT_EQ(Insts[5].getOpcode(), llvm::X86::VMOVDQU32Z128rm);
+  EXPECT_EQ(Insts[6].getOpcode(), llvm::X86::ADD64ri8);
+}
+
+TEST_F(X86TargetTest, SetRegToConstantMMX) {
+  const std::unique_ptr<llvm::MCSubtargetInfo> STI(
+      Target_->createMCSubtargetInfo(kTriple, "core2", ""));
+  const auto Insts = ExegesisTarget_->setRegToConstant(*STI, llvm::X86::MM1);
+  EXPECT_THAT(Insts, SizeIs(5U));
+  EXPECT_EQ(Insts[0].getOpcode(), llvm::X86::SUB64ri8);
+  EXPECT_EQ(Insts[1].getOpcode(), llvm::X86::MOV32mi);
+  EXPECT_EQ(Insts[2].getOpcode(), llvm::X86::MOV32mi);
+  EXPECT_EQ(Insts[3].getOpcode(), llvm::X86::MMX_MOVQ64rm);
+  EXPECT_EQ(Insts[4].getOpcode(), llvm::X86::ADD64ri8);
+}
+
+TEST_F(X86TargetTest, SetRegToConstantYMM_AVX) {
+  const std::unique_ptr<llvm::MCSubtargetInfo> STI(
+      Target_->createMCSubtargetInfo(kTriple, "core2", "+avx"));
+  const auto Insts = ExegesisTarget_->setRegToConstant(*STI, llvm::X86::YMM1);
+  EXPECT_THAT(Insts, SizeIs(11U));
+  EXPECT_EQ(Insts[0].getOpcode(), llvm::X86::SUB64ri8);
+  EXPECT_EQ(Insts[1].getOpcode(), llvm::X86::MOV32mi);
+  EXPECT_EQ(Insts[2].getOpcode(), llvm::X86::MOV32mi);
+  EXPECT_EQ(Insts[3].getOpcode(), llvm::X86::MOV32mi);
+  EXPECT_EQ(Insts[4].getOpcode(), llvm::X86::MOV32mi);
+  EXPECT_EQ(Insts[5].getOpcode(), llvm::X86::MOV32mi);
+  EXPECT_EQ(Insts[6].getOpcode(), llvm::X86::MOV32mi);
+  EXPECT_EQ(Insts[7].getOpcode(), llvm::X86::MOV32mi);
+  EXPECT_EQ(Insts[8].getOpcode(), llvm::X86::MOV32mi);
+  EXPECT_EQ(Insts[9].getOpcode(), llvm::X86::VMOVDQUYrm);
+  EXPECT_EQ(Insts[10].getOpcode(), llvm::X86::ADD64ri8);
+}
+
+TEST_F(X86TargetTest, SetRegToConstantYMM_AVX512) {
+  const std::unique_ptr<llvm::MCSubtargetInfo> STI(
+      Target_->createMCSubtargetInfo(kTriple, "core2", "+avx512vl"));
+  const auto Insts = ExegesisTarget_->setRegToConstant(*STI, llvm::X86::YMM1);
+  EXPECT_THAT(Insts, SizeIs(11U));
+  EXPECT_EQ(Insts[0].getOpcode(), llvm::X86::SUB64ri8);
+  EXPECT_EQ(Insts[1].getOpcode(), llvm::X86::MOV32mi);
+  EXPECT_EQ(Insts[2].getOpcode(), llvm::X86::MOV32mi);
+  EXPECT_EQ(Insts[3].getOpcode(), llvm::X86::MOV32mi);
+  EXPECT_EQ(Insts[4].getOpcode(), llvm::X86::MOV32mi);
+  EXPECT_EQ(Insts[5].getOpcode(), llvm::X86::MOV32mi);
+  EXPECT_EQ(Insts[6].getOpcode(), llvm::X86::MOV32mi);
+  EXPECT_EQ(Insts[7].getOpcode(), llvm::X86::MOV32mi);
+  EXPECT_EQ(Insts[8].getOpcode(), llvm::X86::MOV32mi);
+  EXPECT_EQ(Insts[9].getOpcode(), llvm::X86::VMOVDQU32Z256rm);
+  EXPECT_EQ(Insts[10].getOpcode(), llvm::X86::ADD64ri8);
+}
+
+TEST_F(X86TargetTest, SetRegToConstantZMM_AVX512) {
+  const std::unique_ptr<llvm::MCSubtargetInfo> STI(
+      Target_->createMCSubtargetInfo(kTriple, "core2", "+avx512vl"));
+  const auto Insts = ExegesisTarget_->setRegToConstant(*STI, llvm::X86::ZMM1);
+  EXPECT_THAT(Insts, SizeIs(19U));
+  EXPECT_EQ(Insts[0].getOpcode(), llvm::X86::SUB64ri8);
+  EXPECT_EQ(Insts[1].getOpcode(), llvm::X86::MOV32mi);
+  EXPECT_EQ(Insts[2].getOpcode(), llvm::X86::MOV32mi);
+  EXPECT_EQ(Insts[3].getOpcode(), llvm::X86::MOV32mi);
+  EXPECT_EQ(Insts[4].getOpcode(), llvm::X86::MOV32mi);
+  EXPECT_EQ(Insts[5].getOpcode(), llvm::X86::MOV32mi);
+  EXPECT_EQ(Insts[6].getOpcode(), llvm::X86::MOV32mi);
+  EXPECT_EQ(Insts[7].getOpcode(), llvm::X86::MOV32mi);
+  EXPECT_EQ(Insts[8].getOpcode(), llvm::X86::MOV32mi);
+  EXPECT_EQ(Insts[9].getOpcode(), llvm::X86::MOV32mi);
+  EXPECT_EQ(Insts[10].getOpcode(), llvm::X86::MOV32mi);
+  EXPECT_EQ(Insts[11].getOpcode(), llvm::X86::MOV32mi);
+  EXPECT_EQ(Insts[12].getOpcode(), llvm::X86::MOV32mi);
+  EXPECT_EQ(Insts[13].getOpcode(), llvm::X86::MOV32mi);
+  EXPECT_EQ(Insts[14].getOpcode(), llvm::X86::MOV32mi);
+  EXPECT_EQ(Insts[15].getOpcode(), llvm::X86::MOV32mi);
+  EXPECT_EQ(Insts[16].getOpcode(), llvm::X86::MOV32mi);
+  EXPECT_EQ(Insts[17].getOpcode(), llvm::X86::VMOVDQU32Zrm);
+  EXPECT_EQ(Insts[18].getOpcode(), llvm::X86::ADD64ri8);
 }
 
 } // namespace




More information about the llvm-commits mailing list