diff --git a/llvm/tools/llvm-upgrade/UpgradeLexer.l b/llvm/tools/llvm-upgrade/UpgradeLexer.l index 4b5fde7d09fb..2cf7c51dac6f 100644 --- a/llvm/tools/llvm-upgrade/UpgradeLexer.l +++ b/llvm/tools/llvm-upgrade/UpgradeLexer.l @@ -182,6 +182,28 @@ setlt { RET_TOK( SETLT); } setgt { RET_TOK( SETGT); } setle { RET_TOK( SETLE); } setge { RET_TOK( SETGE); } +icmp { RET_TOK(ICMP); } +fcmp { RET_TOK(FCMP); } +eq { RET_TOK(EQ); } +ne { RET_TOK(NE); } +slt { RET_TOK(SLT); } +sgt { RET_TOK(SGT); } +sle { RET_TOK(SLE); } +sge { RET_TOK(SGE); } +oeq { RET_TOK(OEQ); } +one { RET_TOK(ONE); } +olt { RET_TOK(OLT); } +ogt { RET_TOK(OGT); } +ole { RET_TOK(OLE); } +oge { RET_TOK(OGE); } +ord { RET_TOK(ORD); } +uno { RET_TOK(UNO); } +ueq { RET_TOK(UEQ); } +une { RET_TOK(UNE); } +ult { RET_TOK(ULT); } +ugt { RET_TOK(UGT); } +ule { RET_TOK(ULE); } +uge { RET_TOK(UGE); } phi { RET_TOK( PHI_TOK); } call { RET_TOK( CALL); } diff --git a/llvm/tools/llvm-upgrade/UpgradeParser.y b/llvm/tools/llvm-upgrade/UpgradeParser.y index 7815892cb878..9d2031dc740b 100644 --- a/llvm/tools/llvm-upgrade/UpgradeParser.y +++ b/llvm/tools/llvm-upgrade/UpgradeParser.y @@ -22,6 +22,7 @@ #define YYERROR_VERBOSE 1 #define YYINCLUDED_STDLIB_H #define YYDEBUG 1 +#define UPGRADE_SETCOND_OPS 0 int yylex(); // declaration" of xxx warnings. int yyparse(); @@ -232,6 +233,34 @@ const char* getDivRemOpcode(const std::string& opcode, const TypeInfo& TI) { yyerror("Invalid type for rem instruction"); return op; } + +std::string +getCompareOp(const std::string& setcc, const TypeInfo& TI) { + assert(setcc.length() == 5); + char cc1 = setcc[3]; + char cc2 = setcc[4]; + assert(cc1 == 'e' || cc1 == 'n' || cc1 == 'l' || cc1 == 'g'); + assert(cc2 == 'q' || cc2 == 'e' || cc2 == 'e' || cc2 == 't'); + std::string result("xcmp xxx"); + result[6] = cc1; + result[7] = cc2; + if (TI.isFloatingPoint()) { + result[0] = 'f'; + result[5] = 'o'; // FIXME: Always map to ordered comparison ? + } else if (TI.isIntegral() || TI.isPointer()) { + result[0] = 'i'; + if ((cc1 == 'e' && cc2 == 'q') || (cc1 == 'n' && cc2 == 'e')) + result.erase(5,1); + else if (TI.isSigned()) + result[5] = 's'; + else if (TI.isUnsigned() || TI.isPointer()) + result[5] = 'u'; + else + yyerror("Invalid integral type for setcc"); + } + return result; +} + %} %file-prefix="UpgradeParser" @@ -262,6 +291,8 @@ const char* getDivRemOpcode(const std::string& opcode, const TypeInfo& TI) { %token RET BR SWITCH INVOKE EXCEPT UNWIND UNREACHABLE %token ADD SUB MUL DIV UDIV SDIV FDIV REM UREM SREM FREM AND OR XOR %token SETLE SETGE SETLT SETGT SETEQ SETNE // Binary Comparators +%token ICMP FCMP EQ NE SLT SGT SLE SGE OEQ ONE OLT OGT OLE OGE +%token ORD UNO UEQ UNE ULT UGT ULE UGE %token MALLOC ALLOCA FREE LOAD STORE GETELEMENTPTR %token PHI_TOK SELECT SHL SHR ASHR LSHR VAARG %token EXTRACTELEMENT INSERTELEMENT SHUFFLEVECTOR @@ -279,7 +310,8 @@ const char* getDivRemOpcode(const std::string& opcode, const TypeInfo& TI) { %type MemoryInst SymbolicValueRef OptSideEffect GlobalType %type FnDeclareLinkage BasicBlockList BigOrLittle AsmBlock %type Name ConstValueRef ConstVector External -%type ShiftOps SetCondOps LogicalOps ArithmeticOps CastOps +%type ShiftOps SetCondOps LogicalOps ArithmeticOps CastOps CompareOps +%type Predicates %type ValueRefList ValueRefListE IndexList @@ -305,6 +337,9 @@ ArithmeticOps: ADD | SUB | MUL | DIV | UDIV | SDIV | FDIV | REM | UREM | SREM | FREM; LogicalOps : AND | OR | XOR; SetCondOps : SETLE | SETGE | SETLT | SETGT | SETEQ | SETNE; +CompareOps : ICMP | FCMP; +Predicates : EQ | NE | SLT | SGT | SLE | SGE | ULT | UGT | ULE | UGE + | OEQ | ONE | OLT | OGT | OLE | OGE | ORD | UNO | UEQ | UNE ; ShiftOps : SHL | SHR | ASHR | LSHR; CastOps : TRUNC | ZEXT | SEXT | FPTRUNC | FPEXT | FPTOUI | FPTOSI | UITOFP | SITOFP | PTRTOINT | INTTOPTR | BITCAST | CAST @@ -627,10 +662,18 @@ ConstExpr: CastOps '(' ConstVal TO Types ')' { $$ = $1; } | SetCondOps '(' ConstVal ',' ConstVal ')' { +#if UPGRADE_SETCOND_OPS + *$1 = getCompareOp(*$1, $3.type); +#endif *$1 += "(" + *$3.cnst + "," + *$5.cnst + ")"; $3.destroy(); $5.destroy(); $$ = $1; } + | CompareOps Predicates '(' ConstVal ',' ConstVal ')' { + *$1 += "(" + *$2 + "," + *$4.cnst + "," + *$6.cnst + ")"; + delete $2; $4.destroy(); $6.destroy(); + $$ = $1; + } | ShiftOps '(' ConstVal ',' ConstVal ')' { const char* shiftop = $1->c_str(); if (*$1 == "shr") @@ -1132,10 +1175,18 @@ InstVal : ArithmeticOps Types ValueRef ',' ValueRef { $$ = $1; } | SetCondOps Types ValueRef ',' ValueRef { +#if UPGRADE_SETCOND_OPS + *$1 = getCompareOp(*$1, $2); +#endif *$1 += " " + *$2.newTy + " " + *$3.val + ", " + *$5.val; $2.destroy(); $3.destroy(); $5.destroy(); $$ = $1; } + | CompareOps Predicates Types ValueRef ',' ValueRef ')' { + *$1 += " " + *$2 + " " + *$4.val + "," + *$6.val + ")"; + delete $2; $4.destroy(); $6.destroy(); + $$ = $1; + } | NOT ResolvedVal { *$1 += " " + *$2.val; $2.destroy();