diff options
Diffstat (limited to 'llvm/lib/AsmParser/llvmAsmParser.y')
-rw-r--r-- | llvm/lib/AsmParser/llvmAsmParser.y | 38 |
1 files changed, 34 insertions, 4 deletions
diff --git a/llvm/lib/AsmParser/llvmAsmParser.y b/llvm/lib/AsmParser/llvmAsmParser.y index 8eea9abfef5..4611262b012 100644 --- a/llvm/lib/AsmParser/llvmAsmParser.y +++ b/llvm/lib/AsmParser/llvmAsmParser.y @@ -820,7 +820,7 @@ static PATypeHolder HandleUpRefs(const Type *ty) { /// an obsolete opcode. For example, "div" was replaced by [usf]div but we need /// to maintain backwards compatibility for asm files that still have the "div" /// instruction. This function handles converting div -> [usf]div appropriately. -/// @brief Convert obsolete opcodes to new values +/// @brief Convert obsolete BinaryOps opcodes to new values static void sanitizeOpCode(OpcodeInfo<Instruction::BinaryOps> &OI, const PATypeHolder& PATy) { @@ -855,7 +855,31 @@ sanitizeOpCode(OpcodeInfo<Instruction::BinaryOps> &OI, const PATypeHolder& PATy) // Its not obsolete any more, we fixed it. OI.obsolete = false; } - + +/// This function is similar to the previous overload of sanitizeOpCode but +/// operates on Instruction::OtherOps instead of Instruction::BinaryOps. +/// @brief Convert obsolete OtherOps opcodes to new values +static void +sanitizeOpCode(OpcodeInfo<Instruction::OtherOps> &OI, const PATypeHolder& PATy) +{ + // If its not obsolete, don't do anything + if (!OI.obsolete) + return; + + const Type* Ty = PATy; // type conversion + switch (OI.opcode) { + default: + GenerateError("Invalid obsolete opcode (check Lexer.l)"); + break; + case Instruction::LShr: + if (Ty->isSigned()) + OI.opcode = Instruction::AShr; + break; + } + // Its not obsolete any more, we fixed it. + OI.obsolete = false; +} + // common code from the two 'RunVMAsmParser' functions static Module* RunParser(Module * M) { @@ -1126,7 +1150,7 @@ Module *llvm::RunVMAsmParser(const char * AsmString, Module * M) { // Other Operators %type <OtherOpVal> ShiftOps -%token <OtherOpVal> PHI_TOK CAST SELECT SHL SHR VAARG +%token <OtherOpVal> PHI_TOK CAST SELECT SHL LSHR ASHR VAARG %token <OtherOpVal> EXTRACTELEMENT INSERTELEMENT SHUFFLEVECTOR %token VAARG_old VANEXT_old //OBSOLETE @@ -1160,7 +1184,7 @@ ArithmeticOps: ADD | SUB | MUL | UDIV | SDIV | FDIV | UREM | SREM | FREM; LogicalOps : AND | OR | XOR; SetCondOps : SETLE | SETGE | SETLT | SETGT | SETEQ | SETNE; -ShiftOps : SHL | SHR; +ShiftOps : SHL | LSHR | ASHR; // These are some types that allow classification if we only want a particular // thing... for example, only a signed, unsigned, or integral type. @@ -1730,6 +1754,9 @@ ConstExpr: CAST '(' ConstVal TO Types ')' { GEN_ERROR("Shift count for shift constant must be unsigned byte!"); if (!$3->getType()->isInteger()) GEN_ERROR("Shift constant expression requires integer operand!"); + // Handle opcode upgrade situations + sanitizeOpCode($1, $3->getType()); + CHECK_FOR_ERROR; $$ = ConstantExpr::get($1.opcode, $3, $5); CHECK_FOR_ERROR } @@ -2534,6 +2561,9 @@ InstVal : ArithmeticOps Types ValueRef ',' ValueRef { GEN_ERROR("Shift amount must be ubyte!"); if (!$2->getType()->isInteger()) GEN_ERROR("Shift constant expression requires integer operand!"); + // Handle opcode upgrade situations + sanitizeOpCode($1, $2->getType()); + CHECK_FOR_ERROR; $$ = new ShiftInst($1.opcode, $2, $4); CHECK_FOR_ERROR } |