From: Jyotsna Verma Date: Wed, 20 Feb 2013 16:13:27 +0000 (+0000) Subject: Hexagon: Move HexagonMCInst.h to MCTargetDesc/HexagonMCInst.h. X-Git-Url: http://plrg.eecs.uci.edu/git/?a=commitdiff_plain;h=d6c98ae63824854ea2175b362a10985cac7cfb32;p=oota-llvm.git Hexagon: Move HexagonMCInst.h to MCTargetDesc/HexagonMCInst.h. Add HexagonMCInst class which adds various Hexagon VLIW annotations. In addition, this class also includes some APIs related to the constant extenders. git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@175634 91177308-0d34-0410-b5e6-96231b3b80d8 --- diff --git a/lib/Target/Hexagon/Hexagon.h b/lib/Target/Hexagon/Hexagon.h index 7e7f756309e..dfbefc86428 100644 --- a/lib/Target/Hexagon/Hexagon.h +++ b/lib/Target/Hexagon/Hexagon.h @@ -21,9 +21,10 @@ namespace llvm { class FunctionPass; + class ModulePass; class TargetMachine; class MachineInstr; - class MCInst; + class HexagonMCInst; class HexagonAsmPrinter; class HexagonTargetMachine; class raw_ostream; @@ -54,7 +55,7 @@ namespace llvm { TargetAsmBackend *createHexagonAsmBackend(const Target &, const std::string &); */ - void HexagonLowerToMC(const MachineInstr *MI, MCInst &MCI, + void HexagonLowerToMC(const MachineInstr *MI, HexagonMCInst &MCI, HexagonAsmPrinter &AP); } // end namespace llvm; diff --git a/lib/Target/Hexagon/HexagonAsmPrinter.cpp b/lib/Target/Hexagon/HexagonAsmPrinter.cpp index 58b89d12832..88cd3fbacea 100644 --- a/lib/Target/Hexagon/HexagonAsmPrinter.cpp +++ b/lib/Target/Hexagon/HexagonAsmPrinter.cpp @@ -14,12 +14,12 @@ //===----------------------------------------------------------------------===// #define DEBUG_TYPE "asm-printer" -#include "HexagonAsmPrinter.h" #include "Hexagon.h" -#include "HexagonMCInst.h" +#include "HexagonAsmPrinter.h" #include "HexagonMachineFunctionInfo.h" -#include "HexagonSubtarget.h" #include "HexagonTargetMachine.h" +#include "HexagonSubtarget.h" +#include "MCTargetDesc/HexagonMCInst.h" #include "InstPrinter/HexagonInstPrinter.h" #include "llvm/ADT/SmallString.h" #include "llvm/ADT/SmallVector.h" @@ -220,8 +220,8 @@ void HexagonAsmPrinter::EmitInstruction(const MachineInstr *MI) { assert((Size+IgnoreCount) == MI->getBundleSize() && "Corrupt Bundle!"); for (unsigned Index = 0; Index < Size; Index++) { HexagonMCInst MCI; - MCI.setStartPacket(Index == 0); - MCI.setEndPacket(Index == (Size-1)); + MCI.setPacketStart(Index == 0); + MCI.setPacketEnd(Index == (Size-1)); HexagonLowerToMC(BundleMIs[Index], MCI, *this); OutStreamer.EmitInstruction(MCI); @@ -230,8 +230,8 @@ void HexagonAsmPrinter::EmitInstruction(const MachineInstr *MI) { else { HexagonMCInst MCI; if (MI->getOpcode() == Hexagon::ENDLOOP0) { - MCI.setStartPacket(true); - MCI.setEndPacket(true); + MCI.setPacketStart(true); + MCI.setPacketEnd(true); } HexagonLowerToMC(MI, MCI, *this); OutStreamer.EmitInstruction(MCI); diff --git a/lib/Target/Hexagon/HexagonMCInstLower.cpp b/lib/Target/Hexagon/HexagonMCInstLower.cpp index db36ac01105..f011d51bd61 100644 --- a/lib/Target/Hexagon/HexagonMCInstLower.cpp +++ b/lib/Target/Hexagon/HexagonMCInstLower.cpp @@ -15,6 +15,7 @@ #include "Hexagon.h" #include "HexagonAsmPrinter.h" #include "HexagonMachineFunctionInfo.h" +#include "MCTargetDesc/HexagonMCInst.h" #include "llvm/CodeGen/MachineBasicBlock.h" #include "llvm/IR/Constants.h" #include "llvm/MC/MCExpr.h" @@ -38,9 +39,10 @@ static MCOperand GetSymbolRef(const MachineOperand& MO, const MCSymbol* Symbol, } // Create an MCInst from a MachineInstr -void llvm::HexagonLowerToMC(const MachineInstr* MI, MCInst& MCI, +void llvm::HexagonLowerToMC(const MachineInstr* MI, HexagonMCInst& MCI, HexagonAsmPrinter& AP) { MCI.setOpcode(MI->getOpcode()); + MCI.setDesc(MI->getDesc()); for (unsigned i = 0, e = MI->getNumOperands(); i < e; i++) { const MachineOperand &MO = MI->getOperand(i); diff --git a/lib/Target/Hexagon/InstPrinter/HexagonInstPrinter.cpp b/lib/Target/Hexagon/InstPrinter/HexagonInstPrinter.cpp index c700354bda5..36da6dfcc3d 100644 --- a/lib/Target/Hexagon/InstPrinter/HexagonInstPrinter.cpp +++ b/lib/Target/Hexagon/InstPrinter/HexagonInstPrinter.cpp @@ -12,14 +12,14 @@ //===----------------------------------------------------------------------===// #define DEBUG_TYPE "asm-printer" -#include "HexagonInstPrinter.h" -#include "Hexagon.h" #include "HexagonAsmPrinter.h" -#include "HexagonMCInst.h" +#include "Hexagon.h" +#include "HexagonInstPrinter.h" +#include "MCTargetDesc/HexagonMCInst.h" +#include "llvm/MC/MCInst.h" #include "llvm/ADT/StringExtras.h" #include "llvm/MC/MCAsmInfo.h" #include "llvm/MC/MCExpr.h" -#include "llvm/MC/MCInst.h" #include "llvm/Support/raw_ostream.h" #include @@ -28,6 +28,8 @@ using namespace llvm; #define GET_INSTRUCTION_NAME #include "HexagonGenAsmWriter.inc" +const char HexagonInstPrinter::PacketPadding = '\t'; + StringRef HexagonInstPrinter::getOpcodeName(unsigned Opcode) const { return MII.getName(Opcode); } @@ -43,43 +45,42 @@ void HexagonInstPrinter::printInst(const MCInst *MI, raw_ostream &O, void HexagonInstPrinter::printInst(const HexagonMCInst *MI, raw_ostream &O, StringRef Annot) { - const char packetPadding[] = " "; const char startPacket = '{', endPacket = '}'; // TODO: add outer HW loop when it's supported too. if (MI->getOpcode() == Hexagon::ENDLOOP0) { // Ending a harware loop is different from ending an regular packet. - assert(MI->isEndPacket() && "Loop end must also end the packet"); + assert(MI->isPacketEnd() && "Loop-end must also end the packet"); - if (MI->isStartPacket()) { + if (MI->isPacketStart()) { // There must be a packet to end a loop. // FIXME: when shuffling is always run, this shouldn't be needed. HexagonMCInst Nop; StringRef NoAnnot; Nop.setOpcode (Hexagon::NOP); - Nop.setStartPacket (MI->isStartPacket()); + Nop.setPacketStart (MI->isPacketStart()); printInst (&Nop, O, NoAnnot); } // Close the packet. - if (MI->isEndPacket()) - O << packetPadding << endPacket; + if (MI->isPacketEnd()) + O << PacketPadding << endPacket; printInstruction(MI, O); } else { // Prefix the insn opening the packet. - if (MI->isStartPacket()) - O << packetPadding << startPacket << '\n'; + if (MI->isPacketStart()) + O << PacketPadding << startPacket << '\n'; printInstruction(MI, O); // Suffix the insn closing the packet. - if (MI->isEndPacket()) + if (MI->isPacketEnd()) // Suffix the packet in a new line always, since the GNU assembler has // issues with a closing brace on the same line as CONST{32,64}. - O << '\n' << packetPadding << endPacket; + O << '\n' << PacketPadding << endPacket; } printAnnotation(O, Annot); @@ -102,12 +103,23 @@ void HexagonInstPrinter::printOperand(const MCInst *MI, unsigned OpNo, void HexagonInstPrinter::printImmOperand(const MCInst *MI, unsigned OpNo, raw_ostream &O) const { - O << MI->getOperand(OpNo).getImm(); + const MCOperand& MO = MI->getOperand(OpNo); + + if(MO.isExpr()) { + O << *MO.getExpr(); + } else if(MO.isImm()) { + O << MI->getOperand(OpNo).getImm(); + } else { + llvm_unreachable("Unknown operand"); + } } void HexagonInstPrinter::printExtOperand(const MCInst *MI, unsigned OpNo, raw_ostream &O) const { - O << MI->getOperand(OpNo).getImm(); + const HexagonMCInst *HMCI = static_cast(MI); + if (HMCI->isConstExtended()) + O << "#"; + printOperand(MI, OpNo, O); } void HexagonInstPrinter::printUnsignedImmOperand(const MCInst *MI, diff --git a/lib/Target/Hexagon/InstPrinter/HexagonInstPrinter.h b/lib/Target/Hexagon/InstPrinter/HexagonInstPrinter.h index 902a32352f1..d0cef683da9 100644 --- a/lib/Target/Hexagon/InstPrinter/HexagonInstPrinter.h +++ b/lib/Target/Hexagon/InstPrinter/HexagonInstPrinter.h @@ -14,16 +14,18 @@ #ifndef HEXAGONINSTPRINTER_H #define HEXAGONINSTPRINTER_H -#include "HexagonMCInst.h" #include "llvm/MC/MCInstPrinter.h" +#include "llvm/MC/MCInstrInfo.h" namespace llvm { + class HexagonMCInst; + class HexagonInstPrinter : public MCInstPrinter { public: explicit HexagonInstPrinter(const MCAsmInfo &MAI, const MCInstrInfo &MII, const MCRegisterInfo &MRI) - : MCInstPrinter(MAI, MII, MRI) {} + : MCInstPrinter(MAI, MII, MRI), MII(MII) {} virtual void printInst(const MCInst *MI, raw_ostream &O, StringRef Annot); void printInst(const HexagonMCInst *MI, raw_ostream &O, StringRef Annot); @@ -65,10 +67,19 @@ namespace llvm { void printSymbolLo(const MCInst *MI, unsigned OpNo, raw_ostream &O) const { printSymbol(MI, OpNo, O, false); } - bool isConstExtended(const MCInst *MI) const; + const MCInstrInfo &getMII() const { + return MII; + } + protected: void printSymbol(const MCInst *MI, unsigned OpNo, raw_ostream &O, bool hi) const; + + static const char PacketPadding; + + private: + const MCInstrInfo &MII; + }; } // end namespace llvm diff --git a/lib/Target/Hexagon/InstPrinter/LLVMBuild.txt b/lib/Target/Hexagon/InstPrinter/LLVMBuild.txt index 8678401feee..59849aa7e1c 100644 --- a/lib/Target/Hexagon/InstPrinter/LLVMBuild.txt +++ b/lib/Target/Hexagon/InstPrinter/LLVMBuild.txt @@ -19,5 +19,5 @@ type = Library name = HexagonAsmPrinter parent = Hexagon -required_libraries = MC Support +required_libraries = HexagonDesc MC Support add_to_library_groups = Hexagon diff --git a/lib/Target/Hexagon/MCTargetDesc/CMakeLists.txt b/lib/Target/Hexagon/MCTargetDesc/CMakeLists.txt index 8e3da99404e..62b9b600ce8 100644 --- a/lib/Target/Hexagon/MCTargetDesc/CMakeLists.txt +++ b/lib/Target/Hexagon/MCTargetDesc/CMakeLists.txt @@ -1,6 +1,7 @@ add_llvm_library(LLVMHexagonDesc - HexagonMCTargetDesc.cpp HexagonMCAsmInfo.cpp + HexagonMCInst.cpp + HexagonMCTargetDesc.cpp ) add_dependencies(LLVMHexagonDesc HexagonCommonTableGen) diff --git a/lib/Target/Hexagon/MCTargetDesc/HexagonMCInst.cpp b/lib/Target/Hexagon/MCTargetDesc/HexagonMCInst.cpp new file mode 100644 index 00000000000..9260b4a2766 --- /dev/null +++ b/lib/Target/Hexagon/MCTargetDesc/HexagonMCInst.cpp @@ -0,0 +1,175 @@ +//===- HexagonMCInst.cpp - Hexagon sub-class of MCInst --------------------===// +// +// The LLVM Compiler Infrastructure +// +// This file is distributed under the University of Illinois Open Source +// License. See LICENSE.TXT for details. +// +//===----------------------------------------------------------------------===// +// +// This class extends MCInst to allow some Hexagon VLIW annotations. +// +//===----------------------------------------------------------------------===// + +#include "HexagonInstrInfo.h" +#include "MCTargetDesc/HexagonBaseInfo.h" +#include "MCTargetDesc/HexagonMCInst.h" +#include "MCTargetDesc/HexagonMCTargetDesc.h" + +using namespace llvm; + +// Return the slots used by the insn. +unsigned HexagonMCInst::getUnits(const HexagonTargetMachine* TM) const { + const HexagonInstrInfo* QII = TM->getInstrInfo(); + const InstrItineraryData* II = TM->getInstrItineraryData(); + const InstrStage* + IS = II->beginStage(QII->get(this->getOpcode()).getSchedClass()); + + return (IS->getUnits()); +} + +// Return the Hexagon ISA class for the insn. +unsigned HexagonMCInst::getType() const { + const uint64_t F = MCID->TSFlags; + + return ((F >> HexagonII::TypePos) & HexagonII::TypeMask); +} + +// Return whether the insn is an actual insn. +bool HexagonMCInst::isCanon() const { + return (!MCID->isPseudo() && + !isPrefix() && + getType() != HexagonII::TypeENDLOOP); +} + +// Return whether the insn is a prefix. +bool HexagonMCInst::isPrefix() const { + return (getType() == HexagonII::TypePREFIX); +} + +// Return whether the insn is solo, i.e., cannot be in a packet. +bool HexagonMCInst::isSolo() const { + const uint64_t F = MCID->TSFlags; + return ((F >> HexagonII::SoloPos) & HexagonII::SoloMask); +} + +// Return whether the insn is a new-value consumer. +bool HexagonMCInst::isNewValue() const { + const uint64_t F = MCID->TSFlags; + return ((F >> HexagonII::NewValuePos) & HexagonII::NewValueMask); +} + +// Return whether the instruction is a legal new-value producer. +bool HexagonMCInst::hasNewValue() const { + const uint64_t F = MCID->TSFlags; + return ((F >> HexagonII::hasNewValuePos) & HexagonII::hasNewValueMask); +} + +// Return the operand that consumes or produces a new value. +const MCOperand& HexagonMCInst::getNewValue() const { + const uint64_t F = MCID->TSFlags; + const unsigned O = (F >> HexagonII::NewValueOpPos) & + HexagonII::NewValueOpMask; + const MCOperand& MCO = getOperand(O); + + assert ((isNewValue() || hasNewValue()) && MCO.isReg()); + return (MCO); +} + +// Return whether the instruction needs to be constant extended. +// 1) Always return true if the instruction has 'isExtended' flag set. +// +// isExtendable: +// 2) For immediate extended operands, return true only if the value is +// out-of-range. +// 3) For global address, always return true. + +bool HexagonMCInst::isConstExtended(void) const { + if (isExtended()) + return true; + + if (!isExtendable()) + return false; + + short ExtOpNum = getCExtOpNum(); + int MinValue = getMinValue(); + int MaxValue = getMaxValue(); + const MCOperand& MO = getOperand(ExtOpNum); + + // We could be using an instruction with an extendable immediate and shoehorn + // a global address into it. If it is a global address it will be constant + // extended. We do this for COMBINE. + // We currently only handle isGlobal() because it is the only kind of + // object we are going to end up with here for now. + // In the future we probably should add isSymbol(), etc. + if (MO.isExpr()) + return true; + + // If the extendable operand is not 'Immediate' type, the instruction should + // have 'isExtended' flag set. + assert(MO.isImm() && "Extendable operand must be Immediate type"); + + int ImmValue = MO.getImm(); + return (ImmValue < MinValue || ImmValue > MaxValue); +} + +// Return whether the instruction must be always extended. +bool HexagonMCInst::isExtended(void) const { + const uint64_t F = MCID->TSFlags; + return (F >> HexagonII::ExtendedPos) & HexagonII::ExtendedMask; +} + +// Return true if the instruction may be extended based on the operand value. +bool HexagonMCInst::isExtendable(void) const { + const uint64_t F = MCID->TSFlags; + return (F >> HexagonII::ExtendablePos) & HexagonII::ExtendableMask; +} + +// Return number of bits in the constant extended operand. +unsigned HexagonMCInst::getBitCount(void) const { + const uint64_t F = MCID->TSFlags; + return ((F >> HexagonII::ExtentBitsPos) & HexagonII::ExtentBitsMask); +} + +// Return constant extended operand number. +unsigned short HexagonMCInst::getCExtOpNum(void) const { + const uint64_t F = MCID->TSFlags; + return ((F >> HexagonII::ExtendableOpPos) & HexagonII::ExtendableOpMask); +} + +// Return whether the operand can be constant extended. +bool HexagonMCInst::isOperandExtended(const unsigned short OperandNum) const { + const uint64_t F = MCID->TSFlags; + return ((F >> HexagonII::ExtendableOpPos) & HexagonII::ExtendableOpMask) + == OperandNum; +} + +// Return the min value that a constant extendable operand can have +// without being extended. +int HexagonMCInst::getMinValue(void) const { + const uint64_t F = MCID->TSFlags; + unsigned isSigned = (F >> HexagonII::ExtentSignedPos) + & HexagonII::ExtentSignedMask; + unsigned bits = (F >> HexagonII::ExtentBitsPos) + & HexagonII::ExtentBitsMask; + + if (isSigned) // if value is signed + return -1 << (bits - 1); + else + return 0; +} + +// Return the max value that a constant extendable operand can have +// without being extended. +int HexagonMCInst::getMaxValue(void) const { + const uint64_t F = MCID->TSFlags; + unsigned isSigned = (F >> HexagonII::ExtentSignedPos) + & HexagonII::ExtentSignedMask; + unsigned bits = (F >> HexagonII::ExtentBitsPos) + & HexagonII::ExtentBitsMask; + + if (isSigned) // if value is signed + return ~(-1 << (bits - 1)); + else + return ~(-1 << bits); +} diff --git a/lib/Target/Hexagon/MCTargetDesc/HexagonMCInst.h b/lib/Target/Hexagon/MCTargetDesc/HexagonMCInst.h new file mode 100644 index 00000000000..3ca71f00b24 --- /dev/null +++ b/lib/Target/Hexagon/MCTargetDesc/HexagonMCInst.h @@ -0,0 +1,100 @@ +//===- HexagonMCInst.h - Hexagon sub-class of MCInst ----------------------===// +// +// The LLVM Compiler Infrastructure +// +// This file is distributed under the University of Illinois Open Source +// License. See LICENSE.TXT for details. +// +//===----------------------------------------------------------------------===// +// +// This class extends MCInst to allow some VLIW annotations. +// +//===----------------------------------------------------------------------===// + +#ifndef HEXAGONMCINST_H +#define HEXAGONMCINST_H + +#include "HexagonTargetMachine.h" +#include "llvm/MC/MCInst.h" + +namespace llvm { + class MCOperand; + + class HexagonMCInst: public MCInst { + // MCID is set during instruction lowering. + // It is needed in order to access TSFlags for + // use in checking MC instruction properties. + const MCInstrDesc *MCID; + + // Packet start and end markers + unsigned packetStart: 1, packetEnd: 1; + + public: + explicit HexagonMCInst(): + MCInst(), MCID(0), packetStart(0), packetEnd(0) {}; + HexagonMCInst(const MCInstrDesc& mcid): + MCInst(), MCID(&mcid), packetStart(0), packetEnd(0) {}; + + bool isPacketStart() const { return (packetStart); }; + bool isPacketEnd() const { return (packetEnd); }; + void setPacketStart(bool Y) { packetStart = Y; }; + void setPacketEnd(bool Y) { packetEnd = Y; }; + void resetPacket() { setPacketStart(false); setPacketEnd(false); }; + + // Return the slots used by the insn. + unsigned getUnits(const HexagonTargetMachine* TM) const; + + // Return the Hexagon ISA class for the insn. + unsigned getType() const; + + void setDesc(const MCInstrDesc& mcid) { MCID = &mcid; }; + const MCInstrDesc& getDesc(void) const { return *MCID; }; + + // Return whether the insn is an actual insn. + bool isCanon() const; + + // Return whether the insn is a prefix. + bool isPrefix() const; + + // Return whether the insn is solo, i.e., cannot be in a packet. + bool isSolo() const; + + // Return whether the instruction needs to be constant extended. + bool isConstExtended() const; + + // Return constant extended operand number. + unsigned short getCExtOpNum(void) const; + + // Return whether the insn is a new-value consumer. + bool isNewValue() const; + + // Return whether the instruction is a legal new-value producer. + bool hasNewValue() const; + + // Return the operand that consumes or produces a new value. + const MCOperand& getNewValue() const; + + // Return number of bits in the constant extended operand. + unsigned getBitCount(void) const; + + private: + // Return whether the instruction must be always extended. + bool isExtended() const; + + // Return true if the insn may be extended based on the operand value. + bool isExtendable() const; + + // Return true if the operand can be constant extended. + bool isOperandExtended(const unsigned short OperandNum) const; + + // Return the min value that a constant extendable operand can have + // without being extended. + int getMinValue() const; + + // Return the max value that a constant extendable operand can have + // without being extended. + int getMaxValue() const; + }; +} + +#endif diff --git a/lib/Target/Hexagon/MCTargetDesc/HexagonMCTargetDesc.cpp b/lib/Target/Hexagon/MCTargetDesc/HexagonMCTargetDesc.cpp index 737789bbb55..6b1d2d16195 100644 --- a/lib/Target/Hexagon/MCTargetDesc/HexagonMCTargetDesc.cpp +++ b/lib/Target/Hexagon/MCTargetDesc/HexagonMCTargetDesc.cpp @@ -13,11 +13,13 @@ #include "HexagonMCTargetDesc.h" #include "HexagonMCAsmInfo.h" +#include "InstPrinter/HexagonInstPrinter.h" +#include "llvm/MC/MachineLocation.h" #include "llvm/MC/MCCodeGenInfo.h" #include "llvm/MC/MCInstrInfo.h" #include "llvm/MC/MCRegisterInfo.h" +#include "llvm/MC/MCStreamer.h" #include "llvm/MC/MCSubtargetInfo.h" -#include "llvm/MC/MachineLocation.h" #include "llvm/Support/ErrorHandling.h" #include "llvm/Support/TargetRegistry.h" diff --git a/test/CodeGen/Hexagon/cext-check.ll b/test/CodeGen/Hexagon/cext-check.ll new file mode 100644 index 00000000000..7c4b19e5a40 --- /dev/null +++ b/test/CodeGen/Hexagon/cext-check.ll @@ -0,0 +1,57 @@ +; RUN: llc -march=hexagon -mcpu=hexagonv4 < %s | FileCheck %s +; Check that we constant extended instructions only when necessary. + +define i32 @cext_test1(i32* %a) nounwind { +; CHECK: r{{[0-9]+}}{{ *}}={{ *}}memw(r{{[0-9]+}}+##8000) +; CHECK: r{{[0-9]+}}{{ *}}={{ *}}add(r{{[0-9]+}}{{ *}},{{ *}}##300000) +; CHECK-NOT: r{{[0-9]+}}{{ *}}={{ *}}memw(r{{[0-9]+}}+##4092) +; CHECK-NOT: r{{[0-9]+}}{{ *}}={{ *}}add(r{{[0-9]+}}{{ *}},{{ *}}##300) +entry: + %0 = load i32* %a, align 4 + %tobool = icmp ne i32 %0, 0 + br i1 %tobool, label %if.then, label %if.end + +if.then: + %arrayidx1 = getelementptr inbounds i32* %a, i32 2000 + %1 = load i32* %arrayidx1, align 4 + %add = add nsw i32 %1, 300000 + br label %return + +if.end: + %arrayidx2 = getelementptr inbounds i32* %a, i32 1023 + %2 = load i32* %arrayidx2, align 4 + %add3 = add nsw i32 %2, 300 + br label %return + +return: + %retval.0 = phi i32 [ %add, %if.then ], [ %add3, %if.end ] + ret i32 %retval.0 +} + +define i32 @cext_test2(i8* %a) nounwind { +; CHECK-NOT: r{{[0-9]+}}{{ *}}={{ *}}memub(r{{[0-9]+}}+##1023) +; CHECK: r{{[0-9]+}}{{ *}}={{ *}}add(r{{[0-9]+}}{{ *}},{{ *}}##300000) +; CHECK: r{{[0-9]+}}{{ *}}={{ *}}memub(r{{[0-9]+}}+##1024) +; CHECK-NOT: r{{[0-9]+}}{{ *}}={{ *}}add(r{{[0-9]+}}{{ *}},{{ *}}##6000) +entry: + %tobool = icmp ne i8* %a, null + br i1 %tobool, label %if.then, label %if.end + +if.then: + %arrayidx = getelementptr inbounds i8* %a, i32 1023 + %0 = load i8* %arrayidx, align 1 + %conv = zext i8 %0 to i32 + %add = add nsw i32 %conv, 300000 + br label %return + +if.end: + %arrayidx1 = getelementptr inbounds i8* %a, i32 1024 + %1 = load i8* %arrayidx1, align 1 + %conv2 = zext i8 %1 to i32 + %add3 = add nsw i32 %conv2, 6000 + br label %return + +return: + %retval.0 = phi i32 [ %add, %if.then ], [ %add3, %if.end ] + ret i32 %retval.0 +} diff --git a/test/CodeGen/Hexagon/dualstore.ll b/test/CodeGen/Hexagon/dualstore.ll index 067499530fb..3bf60193a25 100644 --- a/test/CodeGen/Hexagon/dualstore.ll +++ b/test/CodeGen/Hexagon/dualstore.ll @@ -1,8 +1,8 @@ ; RUN: llc -march=hexagon -mcpu=hexagonv4 < %s | FileCheck %s ; Check that we generate dual stores in one packet in V4 -; CHECK: memw(r{{[0-9]+}}{{ *}}+{{ *}}#{{[0-9]+}}){{ *}}={{ *}}#100000 -; CHECK-NEXT: memw(r{{[0-9]+}}{{ *}}+{{ *}}#{{[0-9]+}}){{ *}}={{ *}}#500000 +; CHECK: memw(r{{[0-9]+}}{{ *}}+{{ *}}#{{[0-9]+}}){{ *}}={{ *}}##100000 +; CHECK-NEXT: memw(r{{[0-9]+}}{{ *}}+{{ *}}#{{[0-9]+}}){{ *}}={{ *}}##500000 ; CHECK-NEXT: } @Reg = global i32 0, align 4