[RISCV] Check register class for AMO memory operands
authorJames Clarke <jrtc27@jrtc27.com>
Mon, 13 Jan 2020 00:50:37 +0000 (00:50 +0000)
committerJames Clarke <jrtc27@jrtc27.com>
Mon, 13 Jan 2020 00:50:37 +0000 (00:50 +0000)
Summary:
AMO memory operands use a custom parser in order to accept both (reg)
and 0(reg). However, the validation predicate used for these operands
was only checking that they were registers, and not the register class,
so non-GPRs (such as FPRs) were also accepted. Thus, fix this by making
the predicate check that they are GPRs.

Reviewers: asb, lenary

Reviewed By: asb, lenary

Subscribers: hiraditya, rbar, johnrusso, simoncook, sabuasal, niosHD, kito-cheng, shiva0217, MaskRay, zzheng, edward-jones, rogfer01, MartinMosbeck, brucehoult, the_o, rkruppe, PkmX, jocewei, psnobl, benna, Jim, s.egerton, pzheng, sameer.abuasal, apazos, luismarques, llvm-commits

Tags: #llvm

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

llvm/lib/Target/RISCV/AsmParser/RISCVAsmParser.cpp
llvm/lib/Target/RISCV/RISCVInstrInfoA.td
llvm/test/MC/RISCV/rva-aliases-invalid.s

index f7fb487..fe0455f 100644 (file)
@@ -258,6 +258,11 @@ public:
   bool isMem() const override { return false; }
   bool isSystemRegister() const { return Kind == KindTy::SystemRegister; }
 
+  bool isGPR() const {
+    return Kind == KindTy::Register &&
+           RISCVMCRegisterClasses[RISCV::GPRRegClassID].contains(Reg.RegNum);
+  }
+
   static bool evaluateConstantImm(const MCExpr *Expr, int64_t &Imm,
                                   RISCVMCExpr::VariantKind &VK) {
     if (auto *RE = dyn_cast<RISCVMCExpr>(Expr)) {
index 38ba3f9..7321f4b 100644 (file)
@@ -20,7 +20,7 @@
 def AtomicMemOpOperand : AsmOperandClass {
   let Name = "AtomicMemOpOperand";
   let RenderMethod = "addRegOperands";
-  let PredicateMethod = "isReg";
+  let PredicateMethod = "isGPR";
   let ParserMethod = "parseAtomicMemOp";
 }
 
index ef101e2..a4e80e4 100644 (file)
@@ -10,6 +10,8 @@ lr.w a1, foo    # CHECK: :[[@LINE]]:10: error: expected '(' or optional integer
 lr.w a1, 1(a0)  # CHECK: :[[@LINE]]:10: error: optional integer offset must be 0
 lr.w a1, (foo)  # CHECK: :[[@LINE]]:11: error: expected register
 lr.w a1, 0(foo) # CHECK: :[[@LINE]]:12: error: expected register
+lr.w a1, (f0)   # CHECK: :[[@LINE]]:11: error: invalid operand for instruction
+lr.w a1, 0(f0)  # CHECK: :[[@LINE]]:12: error: invalid operand for instruction
 lr.w a1, 0(a0   # CHECK: :[[@LINE]]:17: error: expected ')'
 lr.w a1, (a0    # CHECK: :[[@LINE]]:17: error: expected ')'
 
@@ -18,6 +20,8 @@ sc.w a2, a1, foo    # CHECK: :[[@LINE]]:14: error: expected '(' or optional inte
 sc.w a2, a1, 1(a0)  # CHECK: :[[@LINE]]:14: error: optional integer offset must be 0
 sc.w a2, a1, (foo)  # CHECK: :[[@LINE]]:15: error: expected register
 sc.w a2, a1, 0(foo) # CHECK: :[[@LINE]]:16: error: expected register
+sc.w a2, a1, (f0)   # CHECK: :[[@LINE]]:15: error: invalid operand for instruction
+sc.w a2, a1, 0(f0)  # CHECK: :[[@LINE]]:16: error: invalid operand for instruction
 sc.w a2, a1, 0(a0   # CHECK: :[[@LINE]]:21: error: expected ')'
 sc.w a2, a1, (a0    # CHECK: :[[@LINE]]:21: error: expected ')'
 
@@ -26,6 +30,8 @@ amoswap.w a2, a1, foo    # CHECK: :[[@LINE]]:19: error: expected '(' or optional
 amoswap.w a2, a1, 1(a0)  # CHECK: :[[@LINE]]:19: error: optional integer offset must be 0
 amoswap.w a2, a1, (foo)  # CHECK: :[[@LINE]]:20: error: expected register
 amoswap.w a2, a1, 0(foo) # CHECK: :[[@LINE]]:21: error: expected register
+amoswap.w a2, a1, (f0)   # CHECK: :[[@LINE]]:20: error: invalid operand for instruction
+amoswap.w a2, a1, 0(f0)  # CHECK: :[[@LINE]]:21: error: invalid operand for instruction
 amoswap.w a2, a1, 0(a0   # CHECK: :[[@LINE]]:26: error: expected ')'
 amoswap.w a2, a1, (a0    # CHECK: :[[@LINE]]:26: error: expected ')'
 
@@ -34,6 +40,8 @@ amoadd.w a2, a1, foo    # CHECK: :[[@LINE]]:18: error: expected '(' or optional
 amoadd.w a2, a1, 1(a0)  # CHECK: :[[@LINE]]:18: error: optional integer offset must be 0
 amoadd.w a2, a1, (foo)  # CHECK: :[[@LINE]]:19: error: expected register
 amoadd.w a2, a1, 0(foo) # CHECK: :[[@LINE]]:20: error: expected register
+amoadd.w a2, a1, (f0)   # CHECK: :[[@LINE]]:19: error: invalid operand for instruction
+amoadd.w a2, a1, 0(f0)  # CHECK: :[[@LINE]]:20: error: invalid operand for instruction
 amoadd.w a2, a1, 0(a0   # CHECK: :[[@LINE]]:25: error: expected ')'
 amoadd.w a2, a1, (a0    # CHECK: :[[@LINE]]:25: error: expected ')'
 
@@ -42,6 +50,8 @@ amoxor.w a2, a1, foo    # CHECK: :[[@LINE]]:18: error: expected '(' or optional
 amoxor.w a2, a1, 1(a0)  # CHECK: :[[@LINE]]:18: error: optional integer offset must be 0
 amoxor.w a2, a1, (foo)  # CHECK: :[[@LINE]]:19: error: expected register
 amoxor.w a2, a1, 0(foo) # CHECK: :[[@LINE]]:20: error: expected register
+amoxor.w a2, a1, (f0)   # CHECK: :[[@LINE]]:19: error: invalid operand for instruction
+amoxor.w a2, a1, 0(f0)  # CHECK: :[[@LINE]]:20: error: invalid operand for instruction
 amoxor.w a2, a1, 0(a0   # CHECK: :[[@LINE]]:25: error: expected ')'
 amoxor.w a2, a1, (a0    # CHECK: :[[@LINE]]:25: error: expected ')'
 
@@ -50,6 +60,8 @@ amoand.w a2, a1, foo    # CHECK: :[[@LINE]]:18: error: expected '(' or optional
 amoand.w a2, a1, 1(a0)  # CHECK: :[[@LINE]]:18: error: optional integer offset must be 0
 amoand.w a2, a1, (foo)  # CHECK: :[[@LINE]]:19: error: expected register
 amoand.w a2, a1, 0(foo) # CHECK: :[[@LINE]]:20: error: expected register
+amoand.w a2, a1, (f0)   # CHECK: :[[@LINE]]:19: error: invalid operand for instruction
+amoand.w a2, a1, 0(f0)  # CHECK: :[[@LINE]]:20: error: invalid operand for instruction
 amoand.w a2, a1, 0(a0   # CHECK: :[[@LINE]]:25: error: expected ')'
 amoand.w a2, a1, (a0    # CHECK: :[[@LINE]]:25: error: expected ')'
 
@@ -58,6 +70,8 @@ amoor.w a2, a1, foo    # CHECK: :[[@LINE]]:17: error: expected '(' or optional i
 amoor.w a2, a1, 1(a0)  # CHECK: :[[@LINE]]:17: error: optional integer offset must be 0
 amoor.w a2, a1, (foo)  # CHECK: :[[@LINE]]:18: error: expected register
 amoor.w a2, a1, 0(foo) # CHECK: :[[@LINE]]:19: error: expected register
+amoor.w a2, a1, (f0)   # CHECK: :[[@LINE]]:18: error: invalid operand for instruction
+amoor.w a2, a1, 0(f0)  # CHECK: :[[@LINE]]:19: error: invalid operand for instruction
 amoor.w a2, a1, 0(a0   # CHECK: :[[@LINE]]:24: error: expected ')'
 amoor.w a2, a1, (a0    # CHECK: :[[@LINE]]:24: error: expected ')'
 
@@ -66,6 +80,8 @@ amomin.w a2, a1, foo    # CHECK: :[[@LINE]]:18: error: expected '(' or optional
 amomin.w a2, a1, 1(a0)  # CHECK: :[[@LINE]]:18: error: optional integer offset must be 0
 amomin.w a2, a1, (foo)  # CHECK: :[[@LINE]]:19: error: expected register
 amomin.w a2, a1, 0(foo) # CHECK: :[[@LINE]]:20: error: expected register
+amomin.w a2, a1, (f0)   # CHECK: :[[@LINE]]:19: error: invalid operand for instruction
+amomin.w a2, a1, 0(f0)  # CHECK: :[[@LINE]]:20: error: invalid operand for instruction
 amomin.w a2, a1, 0(a0   # CHECK: :[[@LINE]]:25: error: expected ')'
 amomin.w a2, a1, (a0    # CHECK: :[[@LINE]]:25: error: expected ')'
 
@@ -74,6 +90,8 @@ amomax.w a2, a1, foo    # CHECK: :[[@LINE]]:18: error: expected '(' or optional
 amomax.w a2, a1, 1(a0)  # CHECK: :[[@LINE]]:18: error: optional integer offset must be 0
 amomax.w a2, a1, (foo)  # CHECK: :[[@LINE]]:19: error: expected register
 amomax.w a2, a1, 0(foo) # CHECK: :[[@LINE]]:20: error: expected register
+amomax.w a2, a1, (f0)   # CHECK: :[[@LINE]]:19: error: invalid operand for instruction
+amomax.w a2, a1, 0(f0)  # CHECK: :[[@LINE]]:20: error: invalid operand for instruction
 amomax.w a2, a1, 0(a0   # CHECK: :[[@LINE]]:25: error: expected ')'
 amomax.w a2, a1, (a0    # CHECK: :[[@LINE]]:25: error: expected ')'
 
@@ -82,6 +100,8 @@ amominu.w a2, a1, foo    # CHECK: :[[@LINE]]:19: error: expected '(' or optional
 amominu.w a2, a1, 1(a0)  # CHECK: :[[@LINE]]:19: error: optional integer offset must be 0
 amominu.w a2, a1, (foo)  # CHECK: :[[@LINE]]:20: error: expected register
 amominu.w a2, a1, 0(foo) # CHECK: :[[@LINE]]:21: error: expected register
+amominu.w a2, a1, (f0)   # CHECK: :[[@LINE]]:20: error: invalid operand for instruction
+amominu.w a2, a1, 0(f0)  # CHECK: :[[@LINE]]:21: error: invalid operand for instruction
 amominu.w a2, a1, 0(a0   # CHECK: :[[@LINE]]:26: error: expected ')'
 amominu.w a2, a1, (a0    # CHECK: :[[@LINE]]:26: error: expected ')'
 
@@ -90,5 +110,7 @@ amomaxu.w a2, a1, foo    # CHECK: :[[@LINE]]:19: error: expected '(' or optional
 amomaxu.w a2, a1, 1(a0)  # CHECK: :[[@LINE]]:19: error: optional integer offset must be 0
 amomaxu.w a2, a1, (foo)  # CHECK: :[[@LINE]]:20: error: expected register
 amomaxu.w a2, a1, 0(foo) # CHECK: :[[@LINE]]:21: error: expected register
+amomaxu.w a2, a1, (f0)   # CHECK: :[[@LINE]]:20: error: invalid operand for instruction
+amomaxu.w a2, a1, 0(f0)  # CHECK: :[[@LINE]]:21: error: invalid operand for instruction
 amomaxu.w a2, a1, 0(a0   # CHECK: :[[@LINE]]:26: error: expected ')'
 amomaxu.w a2, a1, (a0    # CHECK: :[[@LINE]]:26: error: expected ')'
\ No newline at end of file