Skip to content

[PowerPC] Add error for incorrect use of memory operands #114277

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
merged 7 commits into from
Nov 12, 2024

Conversation

jakeegan
Copy link
Member

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.

@llvmbot
Copy link
Member

llvmbot commented Oct 30, 2024

@llvm/pr-subscribers-backend-powerpc

@llvm/pr-subscribers-mc

Author: Jake Egan (jakeegan)

Changes

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.


Full diff: https://github.com/llvm/llvm-project/pull/114277.diff

11 Files Affected:

  • (modified) llvm/lib/Target/PowerPC/AsmParser/PPCAsmParser.cpp (+11-1)
  • (modified) llvm/lib/Target/PowerPC/MCTargetDesc/PPCMCTargetDesc.h (+3-1)
  • (modified) llvm/lib/Target/PowerPC/PPCInstr64Bit.td (+4-4)
  • (modified) llvm/lib/Target/PowerPC/PPCInstrFormats.td (+10-4)
  • (modified) llvm/lib/Target/PowerPC/PPCInstrInfo.h (+3)
  • (modified) llvm/lib/Target/PowerPC/PPCInstrInfo.td (+8-4)
  • (modified) llvm/lib/Target/PowerPC/PPCInstrP10.td (+16-12)
  • (modified) llvm/lib/Target/PowerPC/PPCInstrSPE.td (+1-1)
  • (modified) llvm/test/CodeGen/PowerPC/2007-01-31-InlineAsmAddrMode.ll (+1-1)
  • (modified) llvm/test/CodeGen/PowerPC/2009-07-16-InlineAsm-M-Operand.ll (+1-1)
  • (modified) llvm/test/MC/PowerPC/ppc64-errors.s (+10)
diff --git a/llvm/lib/Target/PowerPC/AsmParser/PPCAsmParser.cpp b/llvm/lib/Target/PowerPC/AsmParser/PPCAsmParser.cpp
index bf512481cf6460..5ed41844bfbf9b 100644
--- a/llvm/lib/Target/PowerPC/AsmParser/PPCAsmParser.cpp
+++ b/llvm/lib/Target/PowerPC/AsmParser/PPCAsmParser.cpp
@@ -9,6 +9,7 @@
 #include "MCTargetDesc/PPCMCExpr.h"
 #include "MCTargetDesc/PPCMCTargetDesc.h"
 #include "PPCTargetStreamer.h"
+#include "PPCInstrInfo.h"
 #include "TargetInfo/PowerPCTargetInfo.h"
 #include "llvm/ADT/STLExtras.h"
 #include "llvm/ADT/Twine.h"
@@ -99,10 +100,14 @@ struct PPCOperand;
 class PPCAsmParser : public MCTargetAsmParser {
   bool IsPPC64;
 
+  bool UsesMemOp;
+
   void Warning(SMLoc L, const Twine &Msg) { getParser().Warning(L, Msg); }
 
   bool isPPC64() const { return IsPPC64; }
 
+  bool usesMemOp() const { return UsesMemOp; }
+
   MCRegister matchRegisterName(int64_t &IntVal);
 
   bool parseRegister(MCRegister &Reg, SMLoc &StartLoc, SMLoc &EndLoc) override;
@@ -146,6 +151,7 @@ class PPCAsmParser : public MCTargetAsmParser {
     // Check for 64-bit vs. 32-bit pointer mode.
     const Triple &TheTriple = STI.getTargetTriple();
     IsPPC64 = TheTriple.isPPC64();
+    UsesMemOp = false;
     // Initialize the set of available features.
     setAvailableFeatures(ComputeAvailableFeatures(STI.getFeatureBits()));
   }
@@ -1257,9 +1263,11 @@ bool PPCAsmParser::matchAndEmitInstruction(SMLoc IDLoc, unsigned &Opcode,
                                            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 (usesMemOp() != TII->isMemOp(Inst.getOpcode()))
+      return Error(IDLoc, "invalid operand for instruction");
     // Post-process instructions (typically extended mnemonics)
     processInstruction(Inst, Operands);
     Inst.setLoc(IDLoc);
@@ -1595,6 +1603,7 @@ bool PPCAsmParser::parseOperand(OperandVector &Operands) {
 
   // Otherwise, check for D-form memory operands
   if (!TlsCall && parseOptionalToken(AsmToken::LParen)) {
+    UsesMemOp = true;
     S = Parser.getTok().getLoc();
 
     int64_t IntVal;
@@ -1626,6 +1635,7 @@ bool PPCAsmParser::parseOperand(OperandVector &Operands) {
 /// Parse an instruction mnemonic followed by its operands.
 bool PPCAsmParser::parseInstruction(ParseInstructionInfo &Info, StringRef Name,
                                     SMLoc NameLoc, OperandVector &Operands) {
+  UsesMemOp = false;
   // The first operand is the token for the instruction name.
   // If the next character is a '+' or '-', we need to add it to the
   // instruction name, to match what TableGen is doing.
diff --git a/llvm/lib/Target/PowerPC/MCTargetDesc/PPCMCTargetDesc.h b/llvm/lib/Target/PowerPC/MCTargetDesc/PPCMCTargetDesc.h
index 16777725990aa1..caa3ad0d22e3bd 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 uses a memory operand.
+  MemOp = 0x1 << (NewDef_Shift + 4)
 };
 } // end namespace PPCII
 
diff --git a/llvm/lib/Target/PowerPC/PPCInstr64Bit.td b/llvm/lib/Target/PowerPC/PPCInstr64Bit.td
index ae25f5c78a0e2d..99f945a92b5cf5 100644
--- a/llvm/lib/Target/PowerPC/PPCInstr64Bit.td
+++ b/llvm/lib/Target/PowerPC/PPCInstr64Bit.td
@@ -218,7 +218,7 @@ let isCall = 1, PPC970_Unit = 7, isCodeGenOnly = 1,
                               (ins (memrix $D, $RA):$src),
                               "bctrl\n\tld 2, $src", IIC_BrB,
                               [(PPCbctrl_load_toc iaddrX4:$src)]>,
-    Requires<[In64BitMode]>;
+    Requires<[In64BitMode]>, MemOp;
 }
 
 let isCall = 1, PPC970_Unit = 7, isCodeGenOnly = 1,
@@ -228,7 +228,7 @@ let isCall = 1, PPC970_Unit = 7, isCodeGenOnly = 1,
                               (ins (memrix $D, $RA):$src),
                               "bctrl\n\tld 2, $src", IIC_BrB,
                               [(PPCbctrl_load_toc_rm iaddrX4:$src)]>,
-    Requires<[In64BitMode]>;
+    Requires<[In64BitMode]>, MemOp;
 }
 
 } // Interpretation64Bit
@@ -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)))]>, MemOp;
 
 let Defs = [CARRY] in {
 def SUBFIC8: DForm_2< 8, (outs g8rc:$RST), (ins g8rc:$RA, s16imm64:$D),
@@ -1457,7 +1457,7 @@ def LQ   : DQForm_RTp5_RA17_MEM<56, 0,
                                 "lq $RTp, $addr", IIC_LdStLQ,
                                 []>,
                                 RegConstraint<"@earlyclobber $RTp">,
-                                isPPC64;
+                                isPPC64, MemOp;
 // We don't really have LQX in the ISA, make a pseudo one so that we can
 // handle x-form during isel. Make it pre-ra may expose
 // oppotunities to some opts(CSE, LICM and etc.) for the result of adding
diff --git a/llvm/lib/Target/PowerPC/PPCInstrFormats.td b/llvm/lib/Target/PowerPC/PPCInstrFormats.td
index 5389f42a325ce6..45fd0112b2bfdf 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 uses a memory operand.
+  bits<1> MemOp = 0;
+  let TSFlags{10} = MemOp;
+
   // 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 MemOp      { bits<1> MemOp = 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>, MemOp {
 }
 
 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 MemOp = 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>, MemOp {
   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>, MemOp {
   bits<6>  XT;
   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>, MemOp {
   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 40996f6fbb75e1..0c9b9207f5fe75 100644
--- a/llvm/lib/Target/PowerPC/PPCInstrInfo.h
+++ b/llvm/lib/Target/PowerPC/PPCInstrInfo.h
@@ -285,6 +285,9 @@ class PPCInstrInfo : public PPCGenInstrInfo {
   bool isZExt32To64(unsigned Opcode) const {
     return get(Opcode).TSFlags & PPCII::ZExt32To64;
   }
+  bool isMemOp(unsigned Opcode) const {
+    return get(Opcode).TSFlags & PPCII::MemOp;
+  }
 
   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..b79c5f79efeb1c 100644
--- a/llvm/lib/Target/PowerPC/PPCInstrInfo.td
+++ b/llvm/lib/Target/PowerPC/PPCInstrInfo.td
@@ -1584,7 +1584,7 @@ let isCall = 1, PPC970_Unit = 7, isCodeGenOnly = 1,
   def BCTRL_LWZinto_toc:
     XLForm_2_ext_and_DForm_1<19, 528, 20, 0, 1, 32, (outs),
      (ins (memri $D, $RA):$addr), "bctrl\n\tlwz 2, $addr", IIC_BrB,
-     [(PPCbctrl_load_toc iaddr:$addr)]>, Requires<[In32BitMode]>;
+     [(PPCbctrl_load_toc iaddr:$addr)]>, Requires<[In32BitMode]>, MemOp;
 
 }
 
@@ -1593,7 +1593,7 @@ let isCall = 1, PPC970_Unit = 7, isCodeGenOnly = 1,
   def BCTRL_LWZinto_toc_RM:
     XLForm_2_ext_and_DForm_1<19, 528, 20, 0, 1, 32, (outs),
      (ins (memri $D, $RA):$addr), "bctrl\n\tlwz 2, $addr", IIC_BrB,
-     [(PPCbctrl_load_toc_rm iaddr:$addr)]>, Requires<[In32BitMode]>;
+     [(PPCbctrl_load_toc_rm iaddr:$addr)]>, Requires<[In32BitMode]>, MemOp;
 
 }
 
@@ -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)))]>, MemOp;
 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 uses a memory operand.
+  bits<1> MemOp = 0;
+  let TSFlags{10} = MemOp;
 }
 
 // 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)>, MemOp;
 
 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..1dd9a44f9e0b32 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 uses a memory operand.
+  bits<1> MemOp = 0;
+  let TSFlags{10} = MemOp;
+
   // 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>, MemOp {
   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>, MemOp {
   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>, MemOp {
   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, MemOp = 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, MemOp = 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, MemOp = 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>, MemOp {
   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>, MemOp {
   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, MemOp = 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, []>, MemOp;
     def PLA8pc : MLS_DForm_SI34_RT5<14, (outs g8rc:$RT),
                                     (ins s34imm_pcrel:$SI),
                                     "pla $RT, $SI", IIC_IntSimple, []>, isPCRel;
@@ -2514,10 +2518,10 @@ let Predicates = [IsISA3_1, PrefixInstrs], isAsmParserOnly = 1, hasNoSchedulingI
 
   def PSUBI : PPCAsmPseudo<"psubi $RT, $RA, $SI",
                            (ins g8rc:$RT, g8rc_nox0:$RA, s34imm:$SI)>;
-
   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, []>, MemOp;
+  
   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..b7e670413d4ff2 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>, MemOp {
   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..85b98d07540a47 100644
--- a/llvm/test/MC/PowerPC/ppc64-errors.s
+++ b/llvm/test/MC/PowerPC/ppc64-errors.s
@@ -143,3 +143,13 @@
 # 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)

Copy link

github-actions bot commented Oct 30, 2024

✅ With the latest revision this PR passed the C/C++ code formatter.

@jakeegan
Copy link
Member Author

jakeegan commented Nov 2, 2024

Addressed review comments

Copy link
Collaborator

@hubert-reinterpretcast hubert-reinterpretcast left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

It seems we still don't catch cases where the memory operand is in the wrong position, e.g.:

        la 0(3),3

Would trying to enforce that the memory operand is the last one work?

@jakeegan
Copy link
Member Author

jakeegan commented Nov 6, 2024

Would trying to enforce that the memory operand is the last one work?

There are cases where the memory operand isn't the last one, for example:

I think I could enforce that the memory operand is the second one though.

Copy link
Collaborator

@hubert-reinterpretcast hubert-reinterpretcast left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I think this is basically ready. Not sure if other reviewers have comments.

Copy link
Collaborator

@hubert-reinterpretcast hubert-reinterpretcast left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

LGTM!

@jakeegan jakeegan merged commit 9358905 into llvm:main Nov 12, 2024
5 of 8 checks passed
@jakeegan jakeegan deleted the bad_asm branch November 12, 2024 08:00
@llvm-ci
Copy link
Collaborator

llvm-ci commented Nov 12, 2024

LLVM Buildbot has detected a new failure on builder llvm-clang-x86_64-gcc-ubuntu running on sie-linux-worker3 while building llvm at step 6 "test-build-unified-tree-check-all".

Full details are available at: https://lab.llvm.org/buildbot/#/builders/174/builds/8286

Here is the relevant piece of the build log for the reference
Step 6 (test-build-unified-tree-check-all) failure: test (failure)
******************** TEST 'lld :: ELF/ppc64-local-exec-tls.s' FAILED ********************
Exit Code: 1

Command Output (stderr):
--
RUN: at line 2: /home/buildbot/buildbot-root/llvm-clang-x86_64-gcc-ubuntu/build/bin/llvm-mc -filetype=obj -triple=powerpc64le-unknown-linux /home/buildbot/buildbot-root/llvm-clang-x86_64-gcc-ubuntu/llvm-project/lld/test/ELF/ppc64-local-exec-tls.s -o /home/buildbot/buildbot-root/llvm-clang-x86_64-gcc-ubuntu/build/tools/lld/test/ELF/Output/ppc64-local-exec-tls.s.tmp.o
+ /home/buildbot/buildbot-root/llvm-clang-x86_64-gcc-ubuntu/build/bin/llvm-mc -filetype=obj -triple=powerpc64le-unknown-linux /home/buildbot/buildbot-root/llvm-clang-x86_64-gcc-ubuntu/llvm-project/lld/test/ELF/ppc64-local-exec-tls.s -o /home/buildbot/buildbot-root/llvm-clang-x86_64-gcc-ubuntu/build/tools/lld/test/ELF/Output/ppc64-local-exec-tls.s.tmp.o
/home/buildbot/buildbot-root/llvm-clang-x86_64-gcc-ubuntu/llvm-project/lld/test/ELF/ppc64-local-exec-tls.s:65:3: error: invalid operand for instruction
  ld 3, b@tprel, 13
  ^
/home/buildbot/buildbot-root/llvm-clang-x86_64-gcc-ubuntu/llvm-project/lld/test/ELF/ppc64-local-exec-tls.s:74:3: error: invalid operand for instruction
  ld 3, b@tprel@l, 13
  ^

--

********************


@llvm-ci
Copy link
Collaborator

llvm-ci commented Nov 12, 2024

LLVM Buildbot has detected a new failure on builder premerge-monolithic-linux running on premerge-linux-1 while building llvm at step 7 "test-build-unified-tree-check-all".

Full details are available at: https://lab.llvm.org/buildbot/#/builders/153/builds/14374

Here is the relevant piece of the build log for the reference
Step 7 (test-build-unified-tree-check-all) failure: test (failure)
******************** TEST 'lld :: ELF/ppc64-local-exec-tls.s' FAILED ********************
Exit Code: 1

Command Output (stderr):
--
RUN: at line 2: /build/buildbot/premerge-monolithic-linux/build/bin/llvm-mc -filetype=obj -triple=powerpc64le-unknown-linux /build/buildbot/premerge-monolithic-linux/llvm-project/lld/test/ELF/ppc64-local-exec-tls.s -o /build/buildbot/premerge-monolithic-linux/build/tools/lld/test/ELF/Output/ppc64-local-exec-tls.s.tmp.o
+ /build/buildbot/premerge-monolithic-linux/build/bin/llvm-mc -filetype=obj -triple=powerpc64le-unknown-linux /build/buildbot/premerge-monolithic-linux/llvm-project/lld/test/ELF/ppc64-local-exec-tls.s -o /build/buildbot/premerge-monolithic-linux/build/tools/lld/test/ELF/Output/ppc64-local-exec-tls.s.tmp.o
/build/buildbot/premerge-monolithic-linux/llvm-project/lld/test/ELF/ppc64-local-exec-tls.s:65:3: error: invalid operand for instruction
  ld 3, b@tprel, 13
  ^
/build/buildbot/premerge-monolithic-linux/llvm-project/lld/test/ELF/ppc64-local-exec-tls.s:74:3: error: invalid operand for instruction
  ld 3, b@tprel@l, 13
  ^

--

********************


jakeegan added a commit that referenced this pull request Nov 12, 2024
…4277)"

This commit broke a test on a couple bots
lld :: ELF/ppc64-local-exec-tls.s

This reverts commit 9358905.
@llvm-ci
Copy link
Collaborator

llvm-ci commented Nov 12, 2024

LLVM Buildbot has detected a new failure on builder llvm-x86_64-debian-dylib running on gribozavr4 while building llvm at step 8 "test-build-unified-tree-check-lld".

Full details are available at: https://lab.llvm.org/buildbot/#/builders/60/builds/12474

Here is the relevant piece of the build log for the reference
Step 8 (test-build-unified-tree-check-lld) failure: test (failure)
******************** TEST 'lld :: ELF/ppc64-local-exec-tls.s' FAILED ********************
Exit Code: 1

Command Output (stderr):
--
RUN: at line 2: /b/1/llvm-x86_64-debian-dylib/build/bin/llvm-mc -filetype=obj -triple=powerpc64le-unknown-linux /b/1/llvm-x86_64-debian-dylib/llvm-project/lld/test/ELF/ppc64-local-exec-tls.s -o /b/1/llvm-x86_64-debian-dylib/build/tools/lld/test/ELF/Output/ppc64-local-exec-tls.s.tmp.o
+ /b/1/llvm-x86_64-debian-dylib/build/bin/llvm-mc -filetype=obj -triple=powerpc64le-unknown-linux /b/1/llvm-x86_64-debian-dylib/llvm-project/lld/test/ELF/ppc64-local-exec-tls.s -o /b/1/llvm-x86_64-debian-dylib/build/tools/lld/test/ELF/Output/ppc64-local-exec-tls.s.tmp.o
/b/1/llvm-x86_64-debian-dylib/llvm-project/lld/test/ELF/ppc64-local-exec-tls.s:65:3: error: invalid operand for instruction
  ld 3, b@tprel, 13
  ^
/b/1/llvm-x86_64-debian-dylib/llvm-project/lld/test/ELF/ppc64-local-exec-tls.s:74:3: error: invalid operand for instruction
  ld 3, b@tprel@l, 13
  ^

--

********************


@llvm-ci
Copy link
Collaborator

llvm-ci commented Nov 12, 2024

LLVM Buildbot has detected a new failure on builder lld-x86_64-ubuntu-fast running on as-builder-4 while building llvm at step 6 "test-build-unified-tree-check-all".

Full details are available at: https://lab.llvm.org/buildbot/#/builders/33/builds/6306

Here is the relevant piece of the build log for the reference
Step 6 (test-build-unified-tree-check-all) failure: test (failure)
******************** TEST 'lld :: ELF/ppc64-local-exec-tls.s' FAILED ********************
Exit Code: 1

Command Output (stderr):
--
RUN: at line 2: /home/buildbot/worker/as-builder-4/ramdisk/lld-x86_64/build/bin/llvm-mc -filetype=obj -triple=powerpc64le-unknown-linux /home/buildbot/worker/as-builder-4/ramdisk/lld-x86_64/llvm-project/lld/test/ELF/ppc64-local-exec-tls.s -o /home/buildbot/worker/as-builder-4/ramdisk/lld-x86_64/build/tools/lld/test/ELF/Output/ppc64-local-exec-tls.s.tmp.o
+ /home/buildbot/worker/as-builder-4/ramdisk/lld-x86_64/build/bin/llvm-mc -filetype=obj -triple=powerpc64le-unknown-linux /home/buildbot/worker/as-builder-4/ramdisk/lld-x86_64/llvm-project/lld/test/ELF/ppc64-local-exec-tls.s -o /home/buildbot/worker/as-builder-4/ramdisk/lld-x86_64/build/tools/lld/test/ELF/Output/ppc64-local-exec-tls.s.tmp.o
/home/buildbot/worker/as-builder-4/ramdisk/lld-x86_64/llvm-project/lld/test/ELF/ppc64-local-exec-tls.s:65:3: error: invalid operand for instruction
  ld 3, b@tprel, 13
  ^
/home/buildbot/worker/as-builder-4/ramdisk/lld-x86_64/llvm-project/lld/test/ELF/ppc64-local-exec-tls.s:74:3: error: invalid operand for instruction
  ld 3, b@tprel@l, 13
  ^

--

********************


@jakeegan jakeegan restored the bad_asm branch November 12, 2024 16:38
jakeegan added a commit to jakeegan/llvm-project that referenced this pull request Nov 12, 2024
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)
jakeegan added a commit that referenced this pull request Nov 14, 2024
…4277)" (#115958)

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.
Groverkss pushed a commit to iree-org/llvm-project that referenced this pull request Nov 15, 2024
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.
Groverkss pushed a commit to iree-org/llvm-project that referenced this pull request Nov 15, 2024
…m#114277)"

This commit broke a test on a couple bots
lld :: ELF/ppc64-local-exec-tls.s

This reverts commit 9358905.
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
backend:PowerPC mc Machine (object) code
Projects
None yet
Development

Successfully merging this pull request may close these issues.

5 participants