[llvm] 0fca35c - [VE] global variable isel patterns

Simon Moll via llvm-commits llvm-commits at lists.llvm.org
Fri Jan 24 08:36:12 PST 2020


Author: Kazushi (Jam) Marukawa
Date: 2020-01-24T17:35:14+01:00
New Revision: 0fca35c652ff1eeaf77b782de52863f915d953a4

URL: https://github.com/llvm/llvm-project/commit/0fca35c652ff1eeaf77b782de52863f915d953a4
DIFF: https://github.com/llvm/llvm-project/commit/0fca35c652ff1eeaf77b782de52863f915d953a4.diff

LOG: [VE] global variable isel patterns

Summary: Asm expr fixups, isel patterns and tests for global variables addresses.

Reviewed By: arsenm

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

Added: 
    llvm/lib/Target/VE/MCTargetDesc/VEFixupKinds.h
    llvm/lib/Target/VE/MCTargetDesc/VEMCExpr.cpp
    llvm/lib/Target/VE/MCTargetDesc/VEMCExpr.h
    llvm/test/CodeGen/VE/load_gv.ll
    llvm/test/CodeGen/VE/store_gv.ll

Modified: 
    llvm/lib/Target/VE/MCTargetDesc/CMakeLists.txt
    llvm/lib/Target/VE/VEISelLowering.cpp
    llvm/lib/Target/VE/VEISelLowering.h
    llvm/lib/Target/VE/VEInstrInfo.td
    llvm/lib/Target/VE/VEMCInstLower.cpp
    llvm/test/CodeGen/VE/load.ll

Removed: 
    


################################################################################
diff  --git a/llvm/lib/Target/VE/MCTargetDesc/CMakeLists.txt b/llvm/lib/Target/VE/MCTargetDesc/CMakeLists.txt
index 6be295e05650..5ef74c18461c 100644
--- a/llvm/lib/Target/VE/MCTargetDesc/CMakeLists.txt
+++ b/llvm/lib/Target/VE/MCTargetDesc/CMakeLists.txt
@@ -1,5 +1,6 @@
 add_llvm_component_library(LLVMVEDesc
   VEMCAsmInfo.cpp
+  VEMCExpr.cpp
   VEMCTargetDesc.cpp
   VETargetStreamer.cpp
   )

diff  --git a/llvm/lib/Target/VE/MCTargetDesc/VEFixupKinds.h b/llvm/lib/Target/VE/MCTargetDesc/VEFixupKinds.h
new file mode 100644
index 000000000000..65d850c6a1de
--- /dev/null
+++ b/llvm/lib/Target/VE/MCTargetDesc/VEFixupKinds.h
@@ -0,0 +1,30 @@
+//===-- VEFixupKinds.h - VE Specific Fixup Entries --------------*- C++ -*-===//
+//
+// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
+// See https://llvm.org/LICENSE.txt for license information.
+// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
+//
+//===----------------------------------------------------------------------===//
+
+#ifndef LLVM_LIB_TARGET_VE_MCTARGETDESC_VEFIXUPKINDS_H
+#define LLVM_LIB_TARGET_VE_MCTARGETDESC_VEFIXUPKINDS_H
+
+#include "llvm/MC/MCFixup.h"
+
+namespace llvm {
+namespace VE {
+enum Fixups {
+  /// fixup_ve_hi32 - 32-bit fixup corresponding to foo at hi
+  fixup_ve_hi32 = FirstTargetFixupKind,
+
+  /// fixup_ve_lo32 - 32-bit fixup corresponding to foo at lo
+  fixup_ve_lo32,
+
+  // Marker
+  LastTargetFixupKind,
+  NumTargetFixupKinds = LastTargetFixupKind - FirstTargetFixupKind
+};
+} // namespace VE
+} // namespace llvm
+
+#endif

diff  --git a/llvm/lib/Target/VE/MCTargetDesc/VEMCExpr.cpp b/llvm/lib/Target/VE/MCTargetDesc/VEMCExpr.cpp
new file mode 100644
index 000000000000..678232383293
--- /dev/null
+++ b/llvm/lib/Target/VE/MCTargetDesc/VEMCExpr.cpp
@@ -0,0 +1,97 @@
+//===-- VEMCExpr.cpp - VE specific MC expression classes ------------------===//
+//
+// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
+// See https://llvm.org/LICENSE.txt for license information.
+// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
+//
+//===----------------------------------------------------------------------===//
+//
+// This file contains the implementation of the assembly expression modifiers
+// accepted by the VE architecture (e.g. "%hi", "%lo", ...).
+//
+//===----------------------------------------------------------------------===//
+
+#include "VEMCExpr.h"
+#include "llvm/MC/MCAssembler.h"
+#include "llvm/MC/MCContext.h"
+#include "llvm/MC/MCObjectStreamer.h"
+#include "llvm/MC/MCSymbolELF.h"
+#include "llvm/Object/ELF.h"
+
+using namespace llvm;
+
+#define DEBUG_TYPE "vemcexpr"
+
+const VEMCExpr *VEMCExpr::create(VariantKind Kind, const MCExpr *Expr,
+                                 MCContext &Ctx) {
+  return new (Ctx) VEMCExpr(Kind, Expr);
+}
+
+void VEMCExpr::printImpl(raw_ostream &OS, const MCAsmInfo *MAI) const {
+
+  bool closeParen = printVariantKind(OS, Kind);
+
+  const MCExpr *Expr = getSubExpr();
+  Expr->print(OS, MAI);
+
+  if (closeParen)
+    OS << ')';
+  printVariantKindSuffix(OS, Kind);
+}
+
+bool VEMCExpr::printVariantKind(raw_ostream &OS, VariantKind Kind) {
+  switch (Kind) {
+  case VK_VE_None:
+    return false;
+
+  case VK_VE_HI32:
+  case VK_VE_LO32:
+    return false; // OS << "@<text>(";  break;
+  }
+  return true;
+}
+
+void VEMCExpr::printVariantKindSuffix(raw_ostream &OS, VariantKind Kind) {
+  switch (Kind) {
+  case VK_VE_None:
+    break;
+  case VK_VE_HI32:
+    OS << "@hi";
+    break;
+  case VK_VE_LO32:
+    OS << "@lo";
+    break;
+  }
+}
+
+VEMCExpr::VariantKind VEMCExpr::parseVariantKind(StringRef name) {
+  return StringSwitch<VEMCExpr::VariantKind>(name)
+      .Case("hi", VK_VE_HI32)
+      .Case("lo", VK_VE_LO32)
+      .Default(VK_VE_None);
+}
+
+VE::Fixups VEMCExpr::getFixupKind(VEMCExpr::VariantKind Kind) {
+  switch (Kind) {
+  default:
+    llvm_unreachable("Unhandled VEMCExpr::VariantKind");
+  case VK_VE_HI32:
+    return VE::fixup_ve_hi32;
+  case VK_VE_LO32:
+    return VE::fixup_ve_lo32;
+  }
+}
+
+bool VEMCExpr::evaluateAsRelocatableImpl(MCValue &Res,
+                                         const MCAsmLayout *Layout,
+                                         const MCFixup *Fixup) const {
+  return getSubExpr()->evaluateAsRelocatable(Res, Layout, Fixup);
+}
+
+void VEMCExpr::visitUsedExpr(MCStreamer &Streamer) const {
+  Streamer.visitUsedExpr(*getSubExpr());
+}
+
+void VEMCExpr::fixELFSymbolsInTLSFixups(MCAssembler &Asm) const {
+  llvm_unreachable("TODO implement");
+}

diff  --git a/llvm/lib/Target/VE/MCTargetDesc/VEMCExpr.h b/llvm/lib/Target/VE/MCTargetDesc/VEMCExpr.h
new file mode 100644
index 000000000000..d8515608d7b7
--- /dev/null
+++ b/llvm/lib/Target/VE/MCTargetDesc/VEMCExpr.h
@@ -0,0 +1,82 @@
+//====- VEMCExpr.h - VE specific MC expression classes --------*- C++ -*-=====//
+//
+// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
+// See https://llvm.org/LICENSE.txt for license information.
+// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
+//
+//===----------------------------------------------------------------------===//
+//
+// This file describes VE-specific MCExprs, used for modifiers like
+// "%hi" or "%lo" etc.,
+//
+//===----------------------------------------------------------------------===//
+
+#ifndef LLVM_LIB_TARGET_VE_MCTARGETDESC_VEMCEXPR_H
+#define LLVM_LIB_TARGET_VE_MCTARGETDESC_VEMCEXPR_H
+
+#include "VEFixupKinds.h"
+#include "llvm/MC/MCExpr.h"
+
+namespace llvm {
+
+class StringRef;
+class VEMCExpr : public MCTargetExpr {
+public:
+  enum VariantKind {
+    VK_VE_None,
+    VK_VE_HI32,
+    VK_VE_LO32,
+  };
+
+private:
+  const VariantKind Kind;
+  const MCExpr *Expr;
+
+  explicit VEMCExpr(VariantKind Kind, const MCExpr *Expr)
+      : Kind(Kind), Expr(Expr) {}
+
+public:
+  /// @name Construction
+  /// @{
+
+  static const VEMCExpr *create(VariantKind Kind, const MCExpr *Expr,
+                                MCContext &Ctx);
+  /// @}
+  /// @name Accessors
+  /// @{
+
+  /// getOpcode - Get the kind of this expression.
+  VariantKind getKind() const { return Kind; }
+
+  /// getSubExpr - Get the child of this expression.
+  const MCExpr *getSubExpr() const { return Expr; }
+
+  /// getFixupKind - Get the fixup kind of this expression.
+  VE::Fixups getFixupKind() const { return getFixupKind(Kind); }
+
+  /// @}
+  void printImpl(raw_ostream &OS, const MCAsmInfo *MAI) const override;
+  bool evaluateAsRelocatableImpl(MCValue &Res, const MCAsmLayout *Layout,
+                                 const MCFixup *Fixup) const override;
+  void visitUsedExpr(MCStreamer &Streamer) const override;
+  MCFragment *findAssociatedFragment() const override {
+    return getSubExpr()->findAssociatedFragment();
+  }
+
+  void fixELFSymbolsInTLSFixups(MCAssembler &Asm) const override;
+
+  static bool classof(const MCExpr *E) {
+    return E->getKind() == MCExpr::Target;
+  }
+
+  static bool classof(const VEMCExpr *) { return true; }
+
+  static VariantKind parseVariantKind(StringRef name);
+  static bool printVariantKind(raw_ostream &OS, VariantKind Kind);
+  static void printVariantKindSuffix(raw_ostream &OS, VariantKind Kind);
+  static VE::Fixups getFixupKind(VariantKind Kind);
+};
+
+} // namespace llvm
+
+#endif

diff  --git a/llvm/lib/Target/VE/VEISelLowering.cpp b/llvm/lib/Target/VE/VEISelLowering.cpp
index 46cbf57eb746..5872dfd06dc0 100644
--- a/llvm/lib/Target/VE/VEISelLowering.cpp
+++ b/llvm/lib/Target/VE/VEISelLowering.cpp
@@ -12,6 +12,7 @@
 //===----------------------------------------------------------------------===//
 
 #include "VEISelLowering.h"
+#include "MCTargetDesc/VEMCExpr.h"
 #include "VERegisterInfo.h"
 #include "VETargetMachine.h"
 #include "llvm/ADT/StringSwitch.h"
@@ -222,6 +223,10 @@ VETargetLowering::VETargetLowering(const TargetMachine &TM,
   addRegisterClass(MVT::f32, &VE::F32RegClass);
   addRegisterClass(MVT::f64, &VE::I64RegClass);
 
+  // Custom legalize GlobalAddress nodes into LO/HI parts.
+  MVT PtrVT = MVT::getIntegerVT(TM.getPointerSizeInBits(0));
+  setOperationAction(ISD::GlobalAddress, PtrVT, Custom);
+
   setStackPointerRegisterToSaveRestore(VE::SX11);
 
   // Set function alignment to 16 bytes
@@ -234,12 +239,17 @@ VETargetLowering::VETargetLowering(const TargetMachine &TM,
 }
 
 const char *VETargetLowering::getTargetNodeName(unsigned Opcode) const {
+#define TARGET_NODE_CASE(NAME)                                                 \
+  case VEISD::NAME:                                                            \
+    return "VEISD::" #NAME;
   switch ((VEISD::NodeType)Opcode) {
   case VEISD::FIRST_NUMBER:
     break;
-  case VEISD::RET_FLAG:
-    return "VEISD::RET_FLAG";
+    TARGET_NODE_CASE(Lo)
+    TARGET_NODE_CASE(Hi)
+    TARGET_NODE_CASE(RET_FLAG)
   }
+#undef TARGET_NODE_CASE
   return nullptr;
 }
 
@@ -247,3 +257,59 @@ EVT VETargetLowering::getSetCCResultType(const DataLayout &, LLVMContext &,
                                          EVT VT) const {
   return MVT::i32;
 }
+
+// Convert to a target node and set target flags.
+SDValue VETargetLowering::withTargetFlags(SDValue Op, unsigned TF,
+                                          SelectionDAG &DAG) const {
+  if (const GlobalAddressSDNode *GA = dyn_cast<GlobalAddressSDNode>(Op))
+    return DAG.getTargetGlobalAddress(GA->getGlobal(), SDLoc(GA),
+                                      GA->getValueType(0), GA->getOffset(), TF);
+
+  llvm_unreachable("Unhandled address SDNode");
+}
+
+// Split Op into high and low parts according to HiTF and LoTF.
+// Return an ADD node combining the parts.
+SDValue VETargetLowering::makeHiLoPair(SDValue Op, unsigned HiTF, unsigned LoTF,
+                                       SelectionDAG &DAG) const {
+  SDLoc DL(Op);
+  EVT VT = Op.getValueType();
+  SDValue Hi = DAG.getNode(VEISD::Hi, DL, VT, withTargetFlags(Op, HiTF, DAG));
+  SDValue Lo = DAG.getNode(VEISD::Lo, DL, VT, withTargetFlags(Op, LoTF, DAG));
+  return DAG.getNode(ISD::ADD, DL, VT, Hi, Lo);
+}
+
+// Build SDNodes for producing an address from a GlobalAddress, ConstantPool,
+// or ExternalSymbol SDNode.
+SDValue VETargetLowering::makeAddress(SDValue Op, SelectionDAG &DAG) const {
+  SDLoc DL(Op);
+
+  assert(!isPositionIndependent() && "TODO implement PIC");
+
+  // This is one of the absolute code models.
+  switch (getTargetMachine().getCodeModel()) {
+  default:
+    llvm_unreachable("Unsupported absolute code model");
+  case CodeModel::Small:
+  case CodeModel::Medium:
+  case CodeModel::Large:
+    // abs64.
+    return makeHiLoPair(Op, VEMCExpr::VK_VE_HI32, VEMCExpr::VK_VE_LO32, DAG);
+  }
+}
+
+/// Custom Lower {
+SDValue VETargetLowering::LowerGlobalAddress(SDValue Op,
+                                             SelectionDAG &DAG) const {
+  return makeAddress(Op, DAG);
+}
+
+SDValue VETargetLowering::LowerOperation(SDValue Op, SelectionDAG &DAG) const {
+  switch (Op.getOpcode()) {
+  default:
+    llvm_unreachable("Should not custom lower this!");
+  case ISD::GlobalAddress:
+    return LowerGlobalAddress(Op, DAG);
+  }
+}
+/// } Custom Lower

diff  --git a/llvm/lib/Target/VE/VEISelLowering.h b/llvm/lib/Target/VE/VEISelLowering.h
index 1aec71d379a3..c01212e5cc63 100644
--- a/llvm/lib/Target/VE/VEISelLowering.h
+++ b/llvm/lib/Target/VE/VEISelLowering.h
@@ -23,6 +23,10 @@ class VESubtarget;
 namespace VEISD {
 enum NodeType : unsigned {
   FIRST_NUMBER = ISD::BUILTIN_OP_END,
+
+  Hi,
+  Lo, // Hi/Lo operations, typically on a global address.
+
   RET_FLAG, // Return with a flag operand.
 };
 }
@@ -60,6 +64,17 @@ class VETargetLowering : public TargetLowering {
                       const SmallVectorImpl<SDValue> &OutVals, const SDLoc &dl,
                       SelectionDAG &DAG) const override;
 
+  /// Custom Lower {
+  SDValue LowerOperation(SDValue Op, SelectionDAG &DAG) const override;
+
+  SDValue LowerGlobalAddress(SDValue Op, SelectionDAG &DAG) const;
+  /// } Custom Lower
+
+  SDValue withTargetFlags(SDValue Op, unsigned TF, SelectionDAG &DAG) const;
+  SDValue makeHiLoPair(SDValue Op, unsigned HiTF, unsigned LoTF,
+                       SelectionDAG &DAG) const;
+  SDValue makeAddress(SDValue Op, SelectionDAG &DAG) const;
+
   bool isFPImmLegal(const APFloat &Imm, EVT VT,
                     bool ForCodeSize) const override;
 };

diff  --git a/llvm/lib/Target/VE/VEInstrInfo.td b/llvm/lib/Target/VE/VEInstrInfo.td
index 412d73f461a8..0c5fd29e1e89 100644
--- a/llvm/lib/Target/VE/VEInstrInfo.td
+++ b/llvm/lib/Target/VE/VEInstrInfo.td
@@ -178,6 +178,9 @@ def uimm6Op64 : Operand<i64> {
 let PrintMethod = "printCCOperand" in
   def CCOp : Operand<i32>;
 
+def VEhi    : SDNode<"VEISD::Hi", SDTIntUnaryOp>;
+def VElo    : SDNode<"VEISD::Lo", SDTIntUnaryOp>;
+
 //  These are target-independent nodes, but have target-specific formats.
 def SDT_SPCallSeqStart : SDCallSeqStart<[ SDTCisVT<0, i64>,
                                           SDTCisVT<1, i64> ]>;
@@ -883,6 +886,13 @@ def : Pat<(truncstorei16 i64:$src, ADDRri:$addr),
 def : Pat<(truncstorei32 i64:$src, ADDRri:$addr),
           (STLri MEMri:$addr, (EXTRACT_SUBREG $src, sub_i32))>;
 
+// Address calculation and its optimization
+def : Pat<(VEhi tglobaladdr:$in), (LEASLzzi tglobaladdr:$in)>;
+def : Pat<(VElo tglobaladdr:$in), (ANDrm0 (LEAzzi tglobaladdr:$in), 32)>;
+def : Pat<(add (VEhi tglobaladdr:$in1), (VElo tglobaladdr:$in2)),
+          (LEASLrzi (ANDrm0 (LEAzzi tglobaladdr:$in2), 32),
+                    (tglobaladdr:$in1))>;
+
 //===----------------------------------------------------------------------===//
 // Pseudo Instructions
 //===----------------------------------------------------------------------===//

diff  --git a/llvm/lib/Target/VE/VEMCInstLower.cpp b/llvm/lib/Target/VE/VEMCInstLower.cpp
index 6c8fc3536c34..10bfb88ad009 100644
--- a/llvm/lib/Target/VE/VEMCInstLower.cpp
+++ b/llvm/lib/Target/VE/VEMCInstLower.cpp
@@ -11,6 +11,7 @@
 //
 //===----------------------------------------------------------------------===//
 
+#include "MCTargetDesc/VEMCExpr.h"
 #include "VE.h"
 #include "llvm/CodeGen/AsmPrinter.h"
 #include "llvm/CodeGen/MachineFunction.h"
@@ -27,9 +28,11 @@ using namespace llvm;
 static MCOperand LowerSymbolOperand(const MachineInstr *MI,
                                     const MachineOperand &MO,
                                     const MCSymbol *Symbol, AsmPrinter &AP) {
+  VEMCExpr::VariantKind Kind = (VEMCExpr::VariantKind)MO.getTargetFlags();
 
   const MCSymbolRefExpr *MCSym = MCSymbolRefExpr::create(Symbol, AP.OutContext);
-  return MCOperand::createExpr(MCSym);
+  const VEMCExpr *expr = VEMCExpr::create(Kind, MCSym, AP.OutContext);
+  return MCOperand::createExpr(expr);
 }
 
 static MCOperand LowerOperand(const MachineInstr *MI, const MachineOperand &MO,
@@ -43,6 +46,8 @@ static MCOperand LowerOperand(const MachineInstr *MI, const MachineOperand &MO,
       break;
     return MCOperand::createReg(MO.getReg());
 
+  case MachineOperand::MO_GlobalAddress:
+    return LowerSymbolOperand(MI, MO, AP.getSymbol(MO.getGlobal()), AP);
   case MachineOperand::MO_Immediate:
     return MCOperand::createImm(MO.getImm());
 

diff  --git a/llvm/test/CodeGen/VE/load.ll b/llvm/test/CodeGen/VE/load.ll
index 6532a8e0e0ad..96e8762cee19 100644
--- a/llvm/test/CodeGen/VE/load.ll
+++ b/llvm/test/CodeGen/VE/load.ll
@@ -191,4 +191,3 @@ define i8 @loadi8stk() {
   %1 = load i8, i8* %addr, align 16
   ret i8 %1
 }
-

diff  --git a/llvm/test/CodeGen/VE/load_gv.ll b/llvm/test/CodeGen/VE/load_gv.ll
new file mode 100644
index 000000000000..b90dd86e7ad9
--- /dev/null
+++ b/llvm/test/CodeGen/VE/load_gv.ll
@@ -0,0 +1,86 @@
+; RUN: llc < %s -mtriple=ve-unknown-unknown | FileCheck %s
+
+ at vi8 = common dso_local local_unnamed_addr global i8 0, align 1
+ at vi16 = common dso_local local_unnamed_addr global i16 0, align 2
+ at vi32 = common dso_local local_unnamed_addr global i32 0, align 4
+ at vi64 = common dso_local local_unnamed_addr global i64 0, align 8
+ at vf32 = common dso_local local_unnamed_addr global float 0.000000e+00, align 4
+ at vf64 = common dso_local local_unnamed_addr global double 0.000000e+00, align 8
+
+; Function Attrs: norecurse nounwind readonly
+define double @loadf64com() {
+; CHECK-LABEL: loadf64com:
+; CHECK:       .LBB{{[0-9]+}}_2:
+; CHECK-NEXT:    lea %s0, vf64 at lo
+; CHECK-NEXT:    and %s0, %s0, (32)0
+; CHECK-NEXT:    lea.sl %s0, vf64 at hi(%s0)
+; CHECK-NEXT:    ld %s0, (,%s0)
+; CHECK-NEXT:    or %s11, 0, %s9
+  %1 = load double, double* @vf64, align 8
+  ret double %1
+}
+
+; Function Attrs: norecurse nounwind readonly
+define float @loadf32com() {
+; CHECK-LABEL: loadf32com:
+; CHECK:       .LBB{{[0-9]+}}_2:
+; CHECK-NEXT:    lea %s0, vf32 at lo
+; CHECK-NEXT:    and %s0, %s0, (32)0
+; CHECK-NEXT:    lea.sl %s0, vf32 at hi(%s0)
+; CHECK-NEXT:    ldu %s0, (,%s0)
+; CHECK-NEXT:    or %s11, 0, %s9
+  %1 = load float, float* @vf32, align 4
+  ret float %1
+}
+
+; Function Attrs: norecurse nounwind readonly
+define i64 @loadi64com() {
+; CHECK-LABEL: loadi64com:
+; CHECK:       .LBB{{[0-9]+}}_2:
+; CHECK-NEXT:    lea %s0, vi64 at lo
+; CHECK-NEXT:    and %s0, %s0, (32)0
+; CHECK-NEXT:    lea.sl %s0, vi64 at hi(%s0)
+; CHECK-NEXT:    ld %s0, (,%s0)
+; CHECK-NEXT:    or %s11, 0, %s9
+  %1 = load i64, i64* @vi64, align 8
+  ret i64 %1
+}
+
+; Function Attrs: norecurse nounwind readonly
+define i32 @loadi32com() {
+; CHECK-LABEL: loadi32com:
+; CHECK:       .LBB{{[0-9]+}}_2:
+; CHECK-NEXT:    lea %s0, vi32 at lo
+; CHECK-NEXT:    and %s0, %s0, (32)0
+; CHECK-NEXT:    lea.sl %s0, vi32 at hi(%s0)
+; CHECK-NEXT:    ldl.sx %s0, (,%s0)
+; CHECK-NEXT:    or %s11, 0, %s9
+  %1 = load i32, i32* @vi32, align 4
+  ret i32 %1
+}
+
+; Function Attrs: norecurse nounwind readonly
+define i16 @loadi16com() {
+; CHECK-LABEL: loadi16com:
+; CHECK:       .LBB{{[0-9]+}}_2:
+; CHECK-NEXT:    lea %s0, vi16 at lo
+; CHECK-NEXT:    and %s0, %s0, (32)0
+; CHECK-NEXT:    lea.sl %s0, vi16 at hi(%s0)
+; CHECK-NEXT:    ld2b.zx %s0, (,%s0)
+; CHECK-NEXT:    or %s11, 0, %s9
+  %1 = load i16, i16* @vi16, align 2
+  ret i16 %1
+}
+
+; Function Attrs: norecurse nounwind readonly
+define i8 @loadi8com() {
+; CHECK-LABEL: loadi8com:
+; CHECK:       .LBB{{[0-9]+}}_2:
+; CHECK-NEXT:    lea %s0, vi8 at lo
+; CHECK-NEXT:    and %s0, %s0, (32)0
+; CHECK-NEXT:    lea.sl %s0, vi8 at hi(%s0)
+; CHECK-NEXT:    ld1b.zx %s0, (,%s0)
+; CHECK-NEXT:    or %s11, 0, %s9
+  %1 = load i8, i8* @vi8, align 1
+  ret i8 %1
+}

diff  --git a/llvm/test/CodeGen/VE/store_gv.ll b/llvm/test/CodeGen/VE/store_gv.ll
new file mode 100644
index 000000000000..033b44c02099
--- /dev/null
+++ b/llvm/test/CodeGen/VE/store_gv.ll
@@ -0,0 +1,87 @@
+; RUN: llc < %s -mtriple=ve-unknown-unknown | FileCheck %s
+
+ at vi8 = common dso_local local_unnamed_addr global i8 0, align 1
+ at vi16 = common dso_local local_unnamed_addr global i16 0, align 2
+ at vi32 = common dso_local local_unnamed_addr global i32 0, align 4
+ at vi64 = common dso_local local_unnamed_addr global i64 0, align 8
+ at vf32 = common dso_local local_unnamed_addr global float 0.000000e+00, align 4
+ at vf64 = common dso_local local_unnamed_addr global double 0.000000e+00, align 8
+
+; Function Attrs: norecurse nounwind readonly
+define void @storef64com(double %0) {
+; CHECK-LABEL: storef64com:
+; CHECK:       .LBB{{[0-9]+}}_2:
+; CHECK-NEXT:    lea %s1, vf64 at lo
+; CHECK-NEXT:    and %s1, %s1, (32)0
+; CHECK-NEXT:    lea.sl %s1, vf64 at hi(%s1)
+; CHECK-NEXT:    st %s0, (,%s1)
+; CHECK-NEXT:    or %s11, 0, %s9
+  store double %0, double* @vf64, align 8
+  ret void
+}
+
+; Function Attrs: norecurse nounwind readonly
+define void @storef32com(float %0) {
+; CHECK-LABEL: storef32com:
+; CHECK:       .LBB{{[0-9]+}}_2:
+; CHECK-NEXT:    lea %s1, vf32 at lo
+; CHECK-NEXT:    and %s1, %s1, (32)0
+; CHECK-NEXT:    lea.sl %s1, vf32 at hi(%s1)
+; CHECK-NEXT:    stu %s0, (,%s1)
+; CHECK-NEXT:    or %s11, 0, %s9
+  store float %0, float* @vf32, align 4
+  ret void
+}
+
+; Function Attrs: norecurse nounwind readonly
+define void @storei64com(i64 %0) {
+; CHECK-LABEL: storei64com:
+; CHECK:       .LBB{{[0-9]+}}_2:
+; CHECK-NEXT:    lea %s1, vi64 at lo
+; CHECK-NEXT:    and %s1, %s1, (32)0
+; CHECK-NEXT:    lea.sl %s1, vi64 at hi(%s1)
+; CHECK-NEXT:    st %s0, (,%s1)
+; CHECK-NEXT:    or %s11, 0, %s9
+  store i64 %0, i64* @vi64, align 8
+  ret void
+}
+
+; Function Attrs: norecurse nounwind readonly
+define void @storei32com(i32 %0) {
+; CHECK-LABEL: storei32com:
+; CHECK:       .LBB{{[0-9]+}}_2:
+; CHECK-NEXT:    lea %s1, vi32 at lo
+; CHECK-NEXT:    and %s1, %s1, (32)0
+; CHECK-NEXT:    lea.sl %s1, vi32 at hi(%s1)
+; CHECK-NEXT:    stl %s0, (,%s1)
+; CHECK-NEXT:    or %s11, 0, %s9
+  store i32 %0, i32* @vi32, align 4
+  ret void
+}
+
+; Function Attrs: norecurse nounwind readonly
+define void @storei16com(i16 %0) {
+; CHECK-LABEL: storei16com:
+; CHECK:       .LBB{{[0-9]+}}_2:
+; CHECK-NEXT:    lea %s1, vi16 at lo
+; CHECK-NEXT:    and %s1, %s1, (32)0
+; CHECK-NEXT:    lea.sl %s1, vi16 at hi(%s1)
+; CHECK-NEXT:    st2b %s0, (,%s1)
+; CHECK-NEXT:    or %s11, 0, %s9
+  store i16 %0, i16* @vi16, align 2
+  ret void
+}
+
+; Function Attrs: norecurse nounwind readonly
+define void @storei8com(i8 %0) {
+; CHECK-LABEL: storei8com:
+; CHECK:       .LBB{{[0-9]+}}_2:
+; CHECK-NEXT:    lea %s1, vi8 at lo
+; CHECK-NEXT:    and %s1, %s1, (32)0
+; CHECK-NEXT:    lea.sl %s1, vi8 at hi(%s1)
+; CHECK-NEXT:    st1b %s0, (,%s1)
+; CHECK-NEXT:    or %s11, 0, %s9
+  store i8 %0, i8* @vi8, align 1
+  ret void
+}
+


        


More information about the llvm-commits mailing list