diff --git a/llvm/lib/Target/VE/MCTargetDesc/CMakeLists.txt b/llvm/lib/Target/VE/MCTargetDesc/CMakeLists.txt --- 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 --- /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@hi + fixup_ve_hi32 = FirstTargetFixupKind, + + /// fixup_ve_lo32 - 32-bit fixup corresponding to foo@lo + fixup_ve_lo32, + + // Marker + LastTargetFixupKind, + NumTargetFixupKinds = LastTargetFixupKind - FirstTargetFixupKind +}; +} // namespace VE +} // namespace llvm + +#endif diff --git a/llvm/lib/Target/VE/MCTargetDesc/VEMCExpr.h b/llvm/lib/Target/VE/MCTargetDesc/VEMCExpr.h new file mode 100644 --- /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/MCTargetDesc/VEMCExpr.cpp b/llvm/lib/Target/VE/MCTargetDesc/VEMCExpr.cpp new file mode 100644 --- /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 << "@("; 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(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/VEISelLowering.h b/llvm/lib/Target/VE/VEISelLowering.h --- a/llvm/lib/Target/VE/VEISelLowering.h +++ b/llvm/lib/Target/VE/VEISelLowering.h @@ -23,6 +23,10 @@ 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 @@ const SmallVectorImpl &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/VEISelLowering.cpp b/llvm/lib/Target/VE/VEISelLowering.cpp --- 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 @@ 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 @@ } 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 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(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/VEInstrInfo.td b/llvm/lib/Target/VE/VEInstrInfo.td --- a/llvm/lib/Target/VE/VEInstrInfo.td +++ b/llvm/lib/Target/VE/VEInstrInfo.td @@ -178,6 +178,9 @@ let PrintMethod = "printCCOperand" in def CCOp : Operand; +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<(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 --- 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,12 @@ 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 +47,8 @@ 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 --- a/llvm/test/CodeGen/VE/load.ll +++ b/llvm/test/CodeGen/VE/load.ll @@ -191,4 +191,3 @@ %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 --- /dev/null +++ b/llvm/test/CodeGen/VE/load_gv.ll @@ -0,0 +1,86 @@ +; RUN: llc < %s -mtriple=ve-unknown-unknown | FileCheck %s + +@vi8 = common dso_local local_unnamed_addr global i8 0, align 1 +@vi16 = common dso_local local_unnamed_addr global i16 0, align 2 +@vi32 = common dso_local local_unnamed_addr global i32 0, align 4 +@vi64 = common dso_local local_unnamed_addr global i64 0, align 8 +@vf32 = common dso_local local_unnamed_addr global float 0.000000e+00, align 4 +@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@lo +; CHECK-NEXT: and %s0, %s0, (32)0 +; CHECK-NEXT: lea.sl %s0, vf64@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@lo +; CHECK-NEXT: and %s0, %s0, (32)0 +; CHECK-NEXT: lea.sl %s0, vf32@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@lo +; CHECK-NEXT: and %s0, %s0, (32)0 +; CHECK-NEXT: lea.sl %s0, vi64@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@lo +; CHECK-NEXT: and %s0, %s0, (32)0 +; CHECK-NEXT: lea.sl %s0, vi32@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@lo +; CHECK-NEXT: and %s0, %s0, (32)0 +; CHECK-NEXT: lea.sl %s0, vi16@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@lo +; CHECK-NEXT: and %s0, %s0, (32)0 +; CHECK-NEXT: lea.sl %s0, vi8@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 --- /dev/null +++ b/llvm/test/CodeGen/VE/store_gv.ll @@ -0,0 +1,87 @@ +; RUN: llc < %s -mtriple=ve-unknown-unknown | FileCheck %s + +@vi8 = common dso_local local_unnamed_addr global i8 0, align 1 +@vi16 = common dso_local local_unnamed_addr global i16 0, align 2 +@vi32 = common dso_local local_unnamed_addr global i32 0, align 4 +@vi64 = common dso_local local_unnamed_addr global i64 0, align 8 +@vf32 = common dso_local local_unnamed_addr global float 0.000000e+00, align 4 +@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@lo +; CHECK-NEXT: and %s1, %s1, (32)0 +; CHECK-NEXT: lea.sl %s1, vf64@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@lo +; CHECK-NEXT: and %s1, %s1, (32)0 +; CHECK-NEXT: lea.sl %s1, vf32@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@lo +; CHECK-NEXT: and %s1, %s1, (32)0 +; CHECK-NEXT: lea.sl %s1, vi64@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@lo +; CHECK-NEXT: and %s1, %s1, (32)0 +; CHECK-NEXT: lea.sl %s1, vi32@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@lo +; CHECK-NEXT: and %s1, %s1, (32)0 +; CHECK-NEXT: lea.sl %s1, vi16@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@lo +; CHECK-NEXT: and %s1, %s1, (32)0 +; CHECK-NEXT: lea.sl %s1, vi8@hi(%s1) +; CHECK-NEXT: st1b %s0, (,%s1) +; CHECK-NEXT: or %s11, 0, %s9 + store i8 %0, i8* @vi8, align 1 + ret void +} +