From b22c1d29bc7fd6ac3f389ac313ef4b80e493d966 Mon Sep 17 00:00:00 2001 From: Shiva Chen Date: Fri, 2 Feb 2018 02:43:23 +0000 Subject: [PATCH] [RISCV] Fix c.addi and c.addi16sp immediate constraints which should be non-zero Differential Revision: https://reviews.llvm.org/D42782 llvm-svn: 324055 --- .../Target/RISCV/AsmParser/RISCVAsmParser.cpp | 25 ++++++++++++++++--- llvm/lib/Target/RISCV/RISCVInstrInfoC.td | 18 +++++++++---- llvm/test/MC/RISCV/rv32c-invalid.s | 13 +++++++--- 3 files changed, 43 insertions(+), 13 deletions(-) diff --git a/llvm/lib/Target/RISCV/AsmParser/RISCVAsmParser.cpp b/llvm/lib/Target/RISCV/AsmParser/RISCVAsmParser.cpp index 3299a53ff5ba..64f59c230ec0 100644 --- a/llvm/lib/Target/RISCV/AsmParser/RISCVAsmParser.cpp +++ b/llvm/lib/Target/RISCV/AsmParser/RISCVAsmParser.cpp @@ -260,6 +260,19 @@ public: (VK == RISCVMCExpr::VK_RISCV_None || VK == RISCVMCExpr::VK_RISCV_LO); } + bool isSImm6NonZero() const { + RISCVMCExpr::VariantKind VK; + int64_t Imm; + bool IsValid; + bool IsConstantImm = evaluateConstantImm(Imm, VK); + if (!IsConstantImm) + IsValid = RISCVAsmParser::classifySymbolRef(getImm(), VK, Imm); + else + IsValid = ((Imm != 0) && isInt<6>(Imm)); + return IsValid && + (VK == RISCVMCExpr::VK_RISCV_None || VK == RISCVMCExpr::VK_RISCV_LO); + } + bool isUImm6NonZero() const { int64_t Imm; RISCVMCExpr::VariantKind VK; @@ -338,11 +351,11 @@ public: bool isSImm13Lsb0() const { return isBareSimmNLsb0<13>(); } - bool isSImm10Lsb0000() const { + bool isSImm10Lsb0000NonZero() const { int64_t Imm; RISCVMCExpr::VariantKind VK; bool IsConstantImm = evaluateConstantImm(Imm, VK); - return IsConstantImm && isShiftedInt<6, 4>(Imm) && + return IsConstantImm && (Imm != 0) && isShiftedInt<6, 4>(Imm) && VK == RISCVMCExpr::VK_RISCV_None; } @@ -613,6 +626,10 @@ bool RISCVAsmParser::MatchAndEmitInstruction(SMLoc IDLoc, unsigned &Opcode, case Match_InvalidSImm6: return generateImmOutOfRangeError(Operands, ErrorInfo, -(1 << 5), (1 << 5) - 1); + case Match_InvalidSImm6NonZero: + return generateImmOutOfRangeError(Operands, ErrorInfo, -(1 << 5), + (1 << 5) - 1, + "immediate must be non-zero in the range"); case Match_InvalidUImm6NonZero: return generateImmOutOfRangeError(Operands, ErrorInfo, 1, (1 << 6) - 1); case Match_InvalidUImm7Lsb00: @@ -639,10 +656,10 @@ bool RISCVAsmParser::MatchAndEmitInstruction(SMLoc IDLoc, unsigned &Opcode, return generateImmOutOfRangeError( Operands, ErrorInfo, 4, (1 << 10) - 4, "immediate must be a multiple of 4 bytes in the range"); - case Match_InvalidSImm10Lsb0000: + case Match_InvalidSImm10Lsb0000NonZero: return generateImmOutOfRangeError( Operands, ErrorInfo, -(1 << 9), (1 << 9) - 16, - "immediate must be a multiple of 16 bytes in the range"); + "immediate must be a multiple of 16 bytes and non-zero in the range"); case Match_InvalidSImm12: return generateImmOutOfRangeError(Operands, ErrorInfo, -(1 << 11), (1 << 11) - 1); diff --git a/llvm/lib/Target/RISCV/RISCVInstrInfoC.td b/llvm/lib/Target/RISCV/RISCVInstrInfoC.td index f39b128099d6..fc9c1dea5a89 100644 --- a/llvm/lib/Target/RISCV/RISCVInstrInfoC.td +++ b/llvm/lib/Target/RISCV/RISCVInstrInfoC.td @@ -35,6 +35,13 @@ def simm6 : Operand, ImmLeaf(Imm);}]> { let DecoderMethod = "decodeSImmOperand<6>"; } +def simm6nonzero : Operand, + ImmLeaf(Imm);}]> { + let ParserMatchClass = SImmAsmOperand<6, "NonZero">; + let EncoderMethod = "getImmOpValue"; + let DecoderMethod = "decodeSImmOperand<6>"; +} + def uimm6nonzero : Operand, ImmLeaf(Imm) && (Imm != 0);}]> { let ParserMatchClass = UImmAsmOperand<6, "NonZero">; @@ -91,9 +98,10 @@ def uimm10_lsb00nonzero : Operand, } // A 10-bit signed immediate where the least significant four bits are zero. -def simm10_lsb0000 : Operand, - ImmLeaf(Imm);}]> { - let ParserMatchClass = SImmAsmOperand<10, "Lsb0000">; +def simm10_lsb0000nonzero : Operand, + ImmLeaf(Imm);}]> { + let ParserMatchClass = SImmAsmOperand<10, "Lsb0000NonZero">; let EncoderMethod = "getImmOpValue"; let DecoderMethod = "decodeSImmOperand<10>"; } @@ -253,7 +261,7 @@ def C_NOP : RVInst16CI<0b000, 0b01, (outs), (ins), "c.nop", "">; let hasSideEffects = 0, mayLoad = 0, mayStore = 0 in def C_ADDI : RVInst16CI<0b000, 0b01, (outs GPRNoX0:$rd_wb), - (ins GPRNoX0:$rd, simm6:$imm), + (ins GPRNoX0:$rd, simm6nonzero:$imm), "c.addi", "$rd, $imm"> { let Constraints = "$rd = $rd_wb"; let Inst{6-2} = imm{4-0}; @@ -282,7 +290,7 @@ def C_LI : RVInst16CI<0b010, 0b01, (outs GPRNoX0:$rd), (ins simm6:$imm), let hasSideEffects = 0, mayLoad = 0, mayStore = 0 in def C_ADDI16SP : RVInst16CI<0b011, 0b01, (outs SP:$rd_wb), - (ins SP:$rd, simm10_lsb0000:$imm), + (ins SP:$rd, simm10_lsb0000nonzero:$imm), "c.addi16sp", "$rd, $imm"> { let Constraints = "$rd = $rd_wb"; let Inst{12} = imm{9}; diff --git a/llvm/test/MC/RISCV/rv32c-invalid.s b/llvm/test/MC/RISCV/rv32c-invalid.s index 188bb68c2b59..7c4380708df1 100644 --- a/llvm/test/MC/RISCV/rv32c-invalid.s +++ b/llvm/test/MC/RISCV/rv32c-invalid.s @@ -45,9 +45,13 @@ c.srai a0, 0 # CHECK: :[[@LINE]]:12: error: immediate must be an integer in the ## simm6 c.li t0, 128 # CHECK: :[[@LINE]]:10: error: immediate must be an integer in the range [-32, 31] -c.addi t0, 32 # CHECK: :[[@LINE]]:12: error: immediate must be an integer in the range [-32, 31] c.andi a0, -33 # CHECK: :[[@LINE]]:12: error: immediate must be an integer in the range [-32, 31] +## simm6nonzero +c.addi t0, 0 # CHECK: :[[@LINE]]:12: error: immediate must be non-zero in the range [-32, 31] +c.addi t0, -33 # CHECK: :[[@LINE]]:12: error: immediate must be non-zero in the range [-32, 31] +c.addi t0, 32 # CHECK: :[[@LINE]]:12: error: immediate must be non-zero in the range [-32, 31] + ## uimm6nonzero c.lui t0, 64 # CHECK: :[[@LINE]]:11: error: immediate must be an integer in the range [1, 63] c.lui t0, 0 # CHECK: :[[@LINE]]:11: error: immediate must be an integer in the range [1, 63] @@ -71,6 +75,7 @@ c.jal -2050 # CHECK: :[[@LINE]]:7: error: immediate must be a multiple of 2 byte c.addi4spn a0, sp, 0 # CHECK: :[[@LINE]]:21: error: immediate must be a multiple of 4 bytes in the range [4, 1020] c.addi4spn a0, sp, 1024 # CHECK: :[[@LINE]]:21: error: immediate must be a multiple of 4 bytes in the range [4, 1020] -## simm10_lsb0000 -c.addi16sp sp, -528 # CHECK: :[[@LINE]]:17: error: immediate must be a multiple of 16 bytes in the range [-512, 496] -c.addi16sp sp, 512 # CHECK: :[[@LINE]]:17: error: immediate must be a multiple of 16 bytes in the range [-512, 496] +## simm10_lsb0000nonzero +c.addi16sp sp, -528 # CHECK: :[[@LINE]]:17: error: immediate must be a multiple of 16 bytes and non-zero in the range [-512, 496] +c.addi16sp sp, 512 # CHECK: :[[@LINE]]:17: error: immediate must be a multiple of 16 bytes and non-zero in the range [-512, 496] +c.addi16sp sp, 0 # CHECK: :[[@LINE]]:17: error: immediate must be a multiple of 16 bytes and non-zero in the range [-512, 496]