-
Notifications
You must be signed in to change notification settings - Fork 14.3k
Reland "[PowerPC] Add error for incorrect use of memory operands (#114277)" #115958
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Merged
+84
−27
Conversation
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
If an instruction doesn't support memory operands, but one is provided, an error should be raised. And conversely, if an instruction requires a memory operand, but none is given, an error should be raised. (cherry picked from commit 9358905)
@llvm/pr-subscribers-mc @llvm/pr-subscribers-backend-powerpc Author: Jake Egan (jakeegan) ChangesCommit 9358905 was reverted, but caused a failure with test Full diff: https://github.com/llvm/llvm-project/pull/115958.diff 12 Files Affected:
diff --git a/lld/test/ELF/ppc64-local-exec-tls.s b/lld/test/ELF/ppc64-local-exec-tls.s
index 51dcb1a7395a1c..f5cb683b9fcfc0 100644
--- a/lld/test/ELF/ppc64-local-exec-tls.s
+++ b/lld/test/ELF/ppc64-local-exec-tls.s
@@ -62,7 +62,7 @@ test_ds:
addi 2, 2, .TOC.-.Lfunc_gep3@l
.Lfunc_lep3:
.localentry test_ds, .Lfunc_lep3-.Lfunc_gep3
- ld 3, b@tprel, 13
+ ld 3, b@tprel(13)
blr
test_lo_ds:
@@ -71,7 +71,7 @@ test_lo_ds:
addi 2, 2, .TOC.-.Lfunc_gep4@l
.Lfunc_lep4:
.localentry test_lo_ds, .Lfunc_lep4-.Lfunc_gep4
- ld 3, b@tprel@l, 13
+ ld 3, b@tprel@l(13)
blr
test_highest_a:
diff --git a/llvm/lib/Target/PowerPC/AsmParser/PPCAsmParser.cpp b/llvm/lib/Target/PowerPC/AsmParser/PPCAsmParser.cpp
index abb6bd31c9c599..52cc8f82f50b6e 100644
--- a/llvm/lib/Target/PowerPC/AsmParser/PPCAsmParser.cpp
+++ b/llvm/lib/Target/PowerPC/AsmParser/PPCAsmParser.cpp
@@ -8,6 +8,7 @@
#include "MCTargetDesc/PPCMCExpr.h"
#include "MCTargetDesc/PPCMCTargetDesc.h"
+#include "PPCInstrInfo.h"
#include "PPCTargetStreamer.h"
#include "TargetInfo/PowerPCTargetInfo.h"
#include "llvm/ADT/STLExtras.h"
@@ -182,6 +183,7 @@ struct PPCOperand : public MCParsedAsmOperand {
struct ImmOp {
int64_t Val;
+ bool IsMemOpBase;
};
struct ExprOp {
@@ -242,6 +244,9 @@ struct PPCOperand : public MCParsedAsmOperand {
/// isPPC64 - True if this operand is for an instruction in 64-bit mode.
bool isPPC64() const { return IsPPC64; }
+ /// isMemOpBase - True if this operand is the base of a memory operand.
+ bool isMemOpBase() const { return Kind == Immediate && Imm.IsMemOpBase; }
+
int64_t getImm() const {
assert(Kind == Immediate && "Invalid access!");
return Imm.Val;
@@ -694,9 +699,11 @@ struct PPCOperand : public MCParsedAsmOperand {
}
static std::unique_ptr<PPCOperand> CreateImm(int64_t Val, SMLoc S, SMLoc E,
- bool IsPPC64) {
+ bool IsPPC64,
+ bool IsMemOpBase = false) {
auto Op = std::make_unique<PPCOperand>(Immediate);
Op->Imm.Val = Val;
+ Op->Imm.IsMemOpBase = IsMemOpBase;
Op->StartLoc = S;
Op->EndLoc = E;
Op->IsPPC64 = IsPPC64;
@@ -1250,14 +1257,29 @@ void PPCAsmParser::processInstruction(MCInst &Inst,
static std::string PPCMnemonicSpellCheck(StringRef S, const FeatureBitset &FBS,
unsigned VariantID = 0);
+// Check that the register+immediate memory operand is in the right position and
+// is expected by the instruction. Returns true if the memory operand syntax is
+// valid; otherwise, returns false.
+static bool validateMemOp(const OperandVector &Operands, bool isMemriOp) {
+ for (size_t idx = 0; idx < Operands.size(); ++idx) {
+ const PPCOperand &Op = static_cast<const PPCOperand &>(*Operands[idx]);
+ if (Op.isMemOpBase() != (idx == 3 && isMemriOp))
+ return false;
+ }
+ return true;
+}
+
bool PPCAsmParser::matchAndEmitInstruction(SMLoc IDLoc, unsigned &Opcode,
OperandVector &Operands,
MCStreamer &Out, uint64_t &ErrorInfo,
bool MatchingInlineAsm) {
MCInst Inst;
+ const PPCInstrInfo *TII = static_cast<const PPCInstrInfo *>(&MII);
switch (MatchInstructionImpl(Operands, Inst, ErrorInfo, MatchingInlineAsm)) {
case Match_Success:
+ if (!validateMemOp(Operands, TII->isMemriOp(Inst.getOpcode())))
+ return Error(IDLoc, "invalid operand for instruction");
// Post-process instructions (typically extended mnemonics)
processInstruction(Inst, Operands);
Inst.setLoc(IDLoc);
@@ -1615,7 +1637,8 @@ bool PPCAsmParser::parseOperand(OperandVector &Operands) {
E = Parser.getTok().getLoc();
if (parseToken(AsmToken::RParen, "missing ')'"))
return true;
- Operands.push_back(PPCOperand::CreateImm(IntVal, S, E, isPPC64()));
+ Operands.push_back(
+ PPCOperand::CreateImm(IntVal, S, E, isPPC64(), /*IsMemOpBase=*/true));
}
return false;
diff --git a/llvm/lib/Target/PowerPC/MCTargetDesc/PPCMCTargetDesc.h b/llvm/lib/Target/PowerPC/MCTargetDesc/PPCMCTargetDesc.h
index 16777725990aa1..579ee5e8facb60 100644
--- a/llvm/lib/Target/PowerPC/MCTargetDesc/PPCMCTargetDesc.h
+++ b/llvm/lib/Target/PowerPC/MCTargetDesc/PPCMCTargetDesc.h
@@ -171,7 +171,9 @@ enum {
/// This instruction produced a sign extended result.
SExt32To64 = 0x1 << (NewDef_Shift + 2),
/// This instruction produced a zero extended result.
- ZExt32To64 = 0x1 << (NewDef_Shift + 3)
+ ZExt32To64 = 0x1 << (NewDef_Shift + 3),
+ /// This instruction takes a register+immediate memory operand.
+ MemriOp = 0x1 << (NewDef_Shift + 4)
};
} // end namespace PPCII
diff --git a/llvm/lib/Target/PowerPC/PPCInstr64Bit.td b/llvm/lib/Target/PowerPC/PPCInstr64Bit.td
index 68419068e52a64..bcac0de55d9d34 100644
--- a/llvm/lib/Target/PowerPC/PPCInstr64Bit.td
+++ b/llvm/lib/Target/PowerPC/PPCInstr64Bit.td
@@ -777,7 +777,7 @@ def ADDIS8 : DForm_2<15, (outs g8rc:$RST), (ins g8rc_nox0:$RA, s17imm64:$D),
def LA8 : DForm_2<14, (outs g8rc:$RST), (ins g8rc_nox0:$RA, s16imm64:$D),
"la $RST, $D($RA)", IIC_IntGeneral,
[(set i64:$RST, (add i64:$RA,
- (PPClo tglobaladdr:$D, 0)))]>;
+ (PPClo tglobaladdr:$D, 0)))]>, MemriOp;
let Defs = [CARRY] in {
def SUBFIC8: DForm_2< 8, (outs g8rc:$RST), (ins g8rc:$RA, s16imm64:$D),
diff --git a/llvm/lib/Target/PowerPC/PPCInstrFormats.td b/llvm/lib/Target/PowerPC/PPCInstrFormats.td
index 5389f42a325ce6..2ced3fe80ea991 100644
--- a/llvm/lib/Target/PowerPC/PPCInstrFormats.td
+++ b/llvm/lib/Target/PowerPC/PPCInstrFormats.td
@@ -55,6 +55,10 @@ class I<bits<6> opcode, dag OOL, dag IOL, string asmstr, InstrItinClass itin>
bits<1> ZExt32To64 = 0;
let TSFlags{9} = ZExt32To64;
+ // Indicate that this instruction takes a register+immediate memory operand.
+ bits<1> MemriOp = 0;
+ let TSFlags{10} = MemriOp;
+
// Fields used for relation models.
string BaseName = "";
@@ -82,6 +86,7 @@ class PPC970_Unit_BRU { bits<3> PPC970_Unit = 7; }
class XFormMemOp { bits<1> XFormMemOp = 1; }
class SExt32To64 { bits<1> SExt32To64 = 1; }
class ZExt32To64 { bits<1> ZExt32To64 = 1; }
+class MemriOp { bits<1> MemriOp = 1; }
// Two joined instructions; used to emit two adjacent instructions as one.
// The itinerary from the first instruction is used for scheduling and
@@ -250,7 +255,7 @@ class DForm_base<bits<6> opcode, dag OOL, dag IOL, string asmstr,
class DForm_1<bits<6> opcode, dag OOL, dag IOL, string asmstr,
InstrItinClass itin, list<dag> pattern>
- : DForm_base<opcode, OOL, IOL, asmstr, itin, pattern> {
+ : DForm_base<opcode, OOL, IOL, asmstr, itin, pattern>, MemriOp {
}
class DForm_2<bits<6> opcode, dag OOL, dag IOL, string asmstr,
@@ -295,6 +300,7 @@ class DForm_4_zero<bits<6> opcode, dag OOL, dag IOL, string asmstr,
let RST = 0;
let RA = 0;
let D = 0;
+ let MemriOp = 0;
}
class DForm_4_fixedreg_zero<bits<6> opcode, bits<5> R, dag OOL, dag IOL,
@@ -372,7 +378,7 @@ class DForm_6_ext<bits<6> opcode, dag OOL, dag IOL, string asmstr,
// 1.7.5 DS-Form
class DSForm_1<bits<6> opcode, bits<2> xo, dag OOL, dag IOL, string asmstr,
InstrItinClass itin, list<dag> pattern>
- : I<opcode, OOL, IOL, asmstr, itin> {
+ : I<opcode, OOL, IOL, asmstr, itin>, MemriOp {
bits<5> RST;
bits<5> RA;
bits<14> D;
@@ -404,7 +410,7 @@ class DXForm<bits<6> opcode, bits<5> xo, dag OOL, dag IOL, string asmstr,
// DQ-Form: [PO T RA DQ TX XO] or [PO S RA DQ SX XO]
class DQ_RD6_RS5_DQ12<bits<6> opcode, bits<3> xo, dag OOL, dag IOL,
string asmstr, InstrItinClass itin, list<dag> pattern>
- : I<opcode, OOL, IOL, asmstr, itin> {
+ : I<opcode, OOL, IOL, asmstr, itin>, MemriOp {
bits<6> XT;
bits<5> RA;
bits<12> DQ;
@@ -421,7 +427,7 @@ class DQ_RD6_RS5_DQ12<bits<6> opcode, bits<3> xo, dag OOL, dag IOL,
class DQForm_RTp5_RA17_MEM<bits<6> opcode, bits<4> xo, dag OOL, dag IOL,
string asmstr, InstrItinClass itin,
list<dag> pattern>
- : I<opcode, OOL, IOL, asmstr, itin> {
+ : I<opcode, OOL, IOL, asmstr, itin>, MemriOp {
bits<5> RTp;
bits<5> RA;
bits<12> DQ;
@@ -1246,7 +1252,7 @@ class XX2_RD6_DCMX7_RS6<bits<6> opcode, bits<4> xo1, bits<3> xo2,
class XForm_XD6_RA5_RB5<bits<6> opcode, bits<10> xo, dag OOL, dag IOL,
string asmstr, InstrItinClass itin, list<dag> pattern>
- : I<opcode, OOL, IOL, asmstr, itin> {
+ : I<opcode, OOL, IOL, asmstr, itin>, MemriOp {
bits<5> RA;
bits<6> D;
bits<5> RB;
diff --git a/llvm/lib/Target/PowerPC/PPCInstrInfo.h b/llvm/lib/Target/PowerPC/PPCInstrInfo.h
index c2abf2f9427463..cd8ecc2dcfac8e 100644
--- a/llvm/lib/Target/PowerPC/PPCInstrInfo.h
+++ b/llvm/lib/Target/PowerPC/PPCInstrInfo.h
@@ -286,6 +286,9 @@ class PPCInstrInfo : public PPCGenInstrInfo {
bool isZExt32To64(unsigned Opcode) const {
return get(Opcode).TSFlags & PPCII::ZExt32To64;
}
+ bool isMemriOp(unsigned Opcode) const {
+ return get(Opcode).TSFlags & PPCII::MemriOp;
+ }
static bool isSameClassPhysRegCopy(unsigned Opcode) {
unsigned CopyOpcodes[] = {PPC::OR, PPC::OR8, PPC::FMR,
diff --git a/llvm/lib/Target/PowerPC/PPCInstrInfo.td b/llvm/lib/Target/PowerPC/PPCInstrInfo.td
index b4a5e41c0107a3..1d8a372fe7632d 100644
--- a/llvm/lib/Target/PowerPC/PPCInstrInfo.td
+++ b/llvm/lib/Target/PowerPC/PPCInstrInfo.td
@@ -2303,7 +2303,7 @@ let isCodeGenOnly = 1 in
def LA : DForm_2<14, (outs gprc:$RST), (ins gprc_nor0:$RA, s16imm:$D),
"la $RST, $D($RA)", IIC_IntGeneral,
[(set i32:$RST, (add i32:$RA,
- (PPClo tglobaladdr:$D, 0)))]>;
+ (PPClo tglobaladdr:$D, 0)))]>, MemriOp;
def MULLI : DForm_2< 7, (outs gprc:$RST), (ins gprc:$RA, s16imm:$D),
"mulli $RST, $RA, $D", IIC_IntMulLI,
[(set i32:$RST, (mul i32:$RA, imm32SExt16:$D))]>;
@@ -3466,6 +3466,10 @@ class PPCAsmPseudo<string asm, dag iops>
let isAsmParserOnly = 1;
let isPseudo = 1;
let hasNoSchedulingInfo = 1;
+
+ // Indicate that this instruction takes a register+immediate memory operand.
+ bits<1> MemriOp = 0;
+ let TSFlags{10} = MemriOp;
}
// Prefixed instructions may require access to the above defs at a later
@@ -4714,7 +4718,7 @@ def : InstAlias<"tlbilxva $RA, $RB", (TLBILX 3, gprc:$RA, gprc:$RB)>,
Requires<[IsBookE]>;
def : InstAlias<"tlbilxva $RB", (TLBILX 3, R0, gprc:$RB)>, Requires<[IsBookE]>;
-def LAx : PPCAsmPseudo<"la $rA, $addr", (ins gprc:$rA, memri:$addr)>;
+def LAx : PPCAsmPseudo<"la $rA, $addr", (ins gprc:$rA, memri:$addr)>, MemriOp;
def SUBI : PPCAsmPseudo<"subi $rA, $rB, $imm",
(ins gprc:$rA, gprc:$rB, s16imm:$imm)>;
diff --git a/llvm/lib/Target/PowerPC/PPCInstrP10.td b/llvm/lib/Target/PowerPC/PPCInstrP10.td
index c4b8597b1df9ff..9e3b38fe02dd06 100644
--- a/llvm/lib/Target/PowerPC/PPCInstrP10.td
+++ b/llvm/lib/Target/PowerPC/PPCInstrP10.td
@@ -138,6 +138,10 @@ class PI<bits<6> pref, bits<6> opcode, dag OOL, dag IOL, string asmstr,
bits<1> Prefixed = 1; // This is a prefixed instruction.
let TSFlags{7} = Prefixed;
+ // Indicate that this instruction takes a register+immediate memory operand.
+ bits<1> MemriOp = 0;
+ let TSFlags{10} = MemriOp;
+
// For cases where multiple instruction definitions really represent the
// same underlying instruction but with one definition for 64-bit arguments
// and one for 32-bit arguments, this bit breaks the degeneracy between
@@ -183,7 +187,7 @@ multiclass VXForm_VTB5_RCr<bits<10> xo, bits<5> R, dag OOL, dag IOL,
class MLS_DForm_R_SI34_RTA5_MEM<bits<6> opcode, dag OOL, dag IOL, string asmstr,
InstrItinClass itin, list<dag> pattern>
- : PI<1, opcode, OOL, IOL, asmstr, itin> {
+ : PI<1, opcode, OOL, IOL, asmstr, itin>, MemriOp {
bits<5> RST;
bits<5> RA;
bits<34> D;
@@ -257,7 +261,7 @@ multiclass MLS_DForm_R_SI34_RTA5_p<bits<6> opcode, dag OOL, dag IOL,
class 8LS_DForm_R_SI34_RTA5_MEM<bits<6> opcode, dag OOL, dag IOL, string asmstr,
InstrItinClass itin, list<dag> pattern>
- : PI<1, opcode, OOL, IOL, asmstr, itin> {
+ : PI<1, opcode, OOL, IOL, asmstr, itin>, MemriOp {
bits<5> RST;
bits<5> RA;
bits<34> D;
@@ -281,7 +285,7 @@ class 8LS_DForm_R_SI34_RTA5_MEM<bits<6> opcode, dag OOL, dag IOL, string asmstr,
class 8LS_DForm_R_SI34_XT6_RA5_MEM<bits<5> opcode, dag OOL, dag IOL,
string asmstr, InstrItinClass itin,
list<dag> pattern>
- : PI<1, { opcode, ? }, OOL, IOL, asmstr, itin> {
+ : PI<1, { opcode, ? }, OOL, IOL, asmstr, itin>, MemriOp {
bits<6> XST;
bits<5> RA;
bits<34> D;
@@ -585,7 +589,7 @@ multiclass MLS_DForm_R_SI34_RTA5_MEM_p<bits<6> opcode, dag OOL, dag IOL,
isPCRel;
let isAsmParserOnly = 1, hasNoSchedulingInfo = 1 in {
def nopc : MLS_DForm_R_SI34_RTA5_MEM<opcode, OOL, IOL, asmstr, itin, []>;
- let RA = 0 in
+ let RA = 0, MemriOp = 0 in
def onlypc : MLS_DForm_R_SI34_RTA5_MEM<opcode, OOL, PCRelOnly_IOL,
asmstr_pcext, itin, []>, isPCRel;
}
@@ -602,7 +606,7 @@ multiclass 8LS_DForm_R_SI34_RTA5_MEM_p<bits<6> opcode, dag OOL, dag IOL,
isPCRel;
let isAsmParserOnly = 1, hasNoSchedulingInfo = 1 in {
def nopc : 8LS_DForm_R_SI34_RTA5_MEM<opcode, OOL, IOL, asmstr, itin, []>;
- let RA = 0 in
+ let RA = 0, MemriOp = 0 in
def onlypc : 8LS_DForm_R_SI34_RTA5_MEM<opcode, OOL, PCRelOnly_IOL,
asmstr_pcext, itin, []>, isPCRel;
}
@@ -619,7 +623,7 @@ multiclass 8LS_DForm_R_SI34_XT6_RA5_MEM_p<bits<5> opcode, dag OOL, dag IOL,
isPCRel;
let isAsmParserOnly = 1, hasNoSchedulingInfo = 1 in {
def nopc : 8LS_DForm_R_SI34_XT6_RA5_MEM<opcode, OOL, IOL, asmstr, itin, []>;
- let RA = 0 in
+ let RA = 0, MemriOp = 0 in
def onlypc : 8LS_DForm_R_SI34_XT6_RA5_MEM<opcode, OOL, PCRelOnly_IOL,
asmstr_pcext, itin, []>, isPCRel;
}
@@ -847,7 +851,7 @@ let Predicates = [PrefixInstrs, HasP10Vector] in {
class DQForm_XTp5_RA17_MEM<bits<6> opcode, bits<4> xo, dag OOL, dag IOL,
string asmstr, InstrItinClass itin, list<dag> pattern>
- : I<opcode, OOL, IOL, asmstr, itin> {
+ : I<opcode, OOL, IOL, asmstr, itin>, MemriOp {
bits<5> XTp;
bits<5> RA;
bits<12> DQ;
@@ -879,7 +883,7 @@ class XForm_XTp5_XAB5<bits<6> opcode, bits<10> xo, dag OOL, dag IOL,
class 8LS_DForm_R_XTp5_SI34_MEM<bits<6> opcode, dag OOL, dag IOL, string asmstr,
InstrItinClass itin, list<dag> pattern>
- : PI<1, opcode, OOL, IOL, asmstr, itin> {
+ : PI<1, opcode, OOL, IOL, asmstr, itin>, MemriOp {
bits<5> XTp;
bits<5> RA;
bits<34> D;
@@ -910,7 +914,7 @@ multiclass 8LS_DForm_R_XTp5_SI34_MEM_p<bits<6> opcode, dag OOL,
isPCRel;
let isAsmParserOnly = 1, hasNoSchedulingInfo = 1 in {
def nopc : 8LS_DForm_R_XTp5_SI34_MEM<opcode, OOL, IOL, asmstr, itin, []>;
- let RA = 0 in
+ let RA = 0, MemriOp = 0 in
def onlypc : 8LS_DForm_R_XTp5_SI34_MEM<opcode, OOL, PCRelOnly_IOL,
asmstr_pcext, itin, []>, isPCRel;
}
@@ -2506,7 +2510,7 @@ let Predicates = [IsISA3_1, PrefixInstrs], isAsmParserOnly = 1, hasNoSchedulingI
let Interpretation64Bit = 1 in {
def PLA8 : MLS_DForm_SI34_RT5<14, (outs g8rc:$RT),
(ins g8rc_nox0:$RA, s34imm:$SI),
- "pla $RT, ${SI} ${RA}", IIC_IntSimple, []>;
+ "pla $RT, ${SI} ${RA}", IIC_IntSimple, []>, MemriOp;
def PLA8pc : MLS_DForm_SI34_RT5<14, (outs g8rc:$RT),
(ins s34imm_pcrel:$SI),
"pla $RT, $SI", IIC_IntSimple, []>, isPCRel;
@@ -2517,7 +2521,7 @@ let Predicates = [IsISA3_1, PrefixInstrs], isAsmParserOnly = 1, hasNoSchedulingI
def PLA : MLS_DForm_SI34_RT5<14, (outs gprc:$RT),
(ins gprc_nor0:$RA, s34imm:$SI),
- "pla $RT, ${SI} ${RA}", IIC_IntSimple, []>;
+ "pla $RT, ${SI} ${RA}", IIC_IntSimple, []>, MemriOp;
def PLApc : MLS_DForm_SI34_RT5<14, (outs gprc:$RT),
(ins s34imm_pcrel:$SI),
"pla $RT, $SI", IIC_IntSimple, []>, isPCRel;
diff --git a/llvm/lib/Target/PowerPC/PPCInstrSPE.td b/llvm/lib/Target/PowerPC/PPCInstrSPE.td
index 5adfbad6ca1186..e91cae349e0826 100644
--- a/llvm/lib/Target/PowerPC/PPCInstrSPE.td
+++ b/llvm/lib/Target/PowerPC/PPCInstrSPE.td
@@ -114,7 +114,7 @@ class EVXForm_4<bits<8> xo, dag OOL, dag IOL, string asmstr,
class EVXForm_D<bits<11> xo, dag OOL, dag IOL, string asmstr,
InstrItinClass itin, list<dag> pattern> :
- I<4, OOL, IOL, asmstr, itin> {
+ I<4, OOL, IOL, asmstr, itin>, MemriOp {
bits<5> RT;
bits<5> RA;
bits<5> D;
diff --git a/llvm/test/CodeGen/PowerPC/2007-01-31-InlineAsmAddrMode.ll b/llvm/test/CodeGen/PowerPC/2007-01-31-InlineAsmAddrMode.ll
index 24db84c0fb86e6..8dff7c9ecd1e37 100644
--- a/llvm/test/CodeGen/PowerPC/2007-01-31-InlineAsmAddrMode.ll
+++ b/llvm/test/CodeGen/PowerPC/2007-01-31-InlineAsmAddrMode.ll
@@ -11,7 +11,7 @@ define void @test1() {
entry:
%Out = alloca %struct.A, align 4 ; <ptr> [#uses=1]
%tmp2 = getelementptr %struct.A, ptr %Out, i32 0, i32 1
- %tmp5 = call i32 asm "lwbrx $0, $1", "=r,m"(ptr %tmp2 )
+ %tmp5 = call i32 asm "lbz $0, $1", "=r,m"(ptr %tmp2 )
ret void
}
diff --git a/llvm/test/CodeGen/PowerPC/2009-07-16-InlineAsm-M-Operand.ll b/llvm/test/CodeGen/PowerPC/2009-07-16-InlineAsm-M-Operand.ll
index 76468f63ee741c..537a7ae78a5a2f 100644
--- a/llvm/test/CodeGen/PowerPC/2009-07-16-InlineAsm-M-Operand.ll
+++ b/llvm/test/CodeGen/PowerPC/2009-07-16-InlineAsm-M-Operand.ll
@@ -10,7 +10,7 @@ define void @memory_asm_operand(i32 %a) {
; "m" operand will be represented as:
; INLINEASM fake $0, 10, %R2, 20, -4, %R1
; It is difficult to find the flag operand (20) when starting from %R1
- call i32 asm "lbzx $0, $1", "=r,m" (i32 %a)
+ call i32 asm "lbz $0, $1", "=r,m" (i32 %a)
ret void
}
diff --git a/llvm/test/MC/PowerPC/ppc64-errors.s b/llvm/test/MC/PowerPC/ppc64-errors.s
index 1c03dc084acdff..17905a396885a0 100644
--- a/llvm/test/MC/PowerPC/ppc64-errors.s
+++ b/llvm/test/MC/PowerPC/ppc64-errors.s
@@ -143,3 +143,18 @@
# CHECK: error: invalid operand for instruction
# CHECK-NEXT: lwarx 1, 2, 3, a
lwarx 1, 2, 3, a
+
+# Instruction requires memory operand
+# CHECK: error: invalid operand for instruction
+# CHECK-NEXT: la 3, 3, 10
+ la 3, 3, 10
+
+# Instruction doesn't support memory operands
+# CHECK: error: invalid operand for instruction
+# CHECK-NEXT: addi 3, 10(3)
+ addi 3, 10(3)
+
+# Invalid memory operand position
+# CHECK: error: invalid operand for instruction
+# CHECK-NEXT: la 0(3), 3
+ la 0(3), 3
|
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.
This suggestion is invalid because no changes were made to the code.
Suggestions cannot be applied while the pull request is closed.
Suggestions cannot be applied while viewing a subset of changes.
Only one suggestion per line can be applied in a batch.
Add this suggestion to a batch that can be applied as a single commit.
Applying suggestions on deleted lines is not supported.
You must change the existing code in this line in order to create a valid suggestion.
Outdated suggestions cannot be applied.
This suggestion has been applied or marked resolved.
Suggestions cannot be applied from pending reviews.
Suggestions cannot be applied on multi-line comments.
Suggestions cannot be applied while the pull request is queued to merge.
Suggestion cannot be applied right now. Please check back later.
Commit 9358905 was reverted because it caused a failure with test
lld :: ELF/ppc64-local-exec-tls.s
. This relands the commit with a fix for the test.