From 59858cf7926702596cf708daf21aeaf5b6feedf8 Mon Sep 17 00:00:00 2001 From: Dan Gohman Date: Mon, 27 Jul 2009 16:11:46 +0000 Subject: Change the assembly syntax for nsw, nuw, and exact, putting them after their associated opcodes rather than before. This makes them a little easier to read. git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@77194 91177308-0d34-0410-b5e6-96231b3b80d8 --- lib/AsmParser/LLParser.cpp | 162 +++++++++++++++-------------------- lib/VMCore/AsmWriter.cpp | 14 +-- test/Analysis/ScalarEvolution/nsw.ll | 2 +- test/Assembler/flags-reversed.ll | 12 +-- test/Assembler/flags-signed.ll | 12 +-- test/Assembler/flags-unsigned.ll | 12 +-- test/Assembler/flags.ll | 68 +++++++-------- 7 files changed, 131 insertions(+), 151 deletions(-) diff --git a/lib/AsmParser/LLParser.cpp b/lib/AsmParser/LLParser.cpp index 481a616..c6f1b25 100644 --- a/lib/AsmParser/LLParser.cpp +++ b/lib/AsmParser/LLParser.cpp @@ -1954,9 +1954,27 @@ bool LLParser::ParseValID(ValID &ID) { case lltok::kw_urem: case lltok::kw_srem: case lltok::kw_frem: { + bool NUW = false; + bool NSW = false; + bool Exact = false; unsigned Opc = Lex.getUIntVal(); Constant *Val0, *Val1; Lex.Lex(); + LocTy ModifierLoc = Lex.getLoc(); + if (Opc == Instruction::Add || + Opc == Instruction::Sub || + Opc == Instruction::Mul) { + if (EatIfPresent(lltok::kw_nuw)) + NUW = true; + if (EatIfPresent(lltok::kw_nsw)) { + NSW = true; + if (EatIfPresent(lltok::kw_nuw)) + NUW = true; + } + } else if (Opc == Instruction::SDiv) { + if (EatIfPresent(lltok::kw_exact)) + Exact = true; + } if (ParseToken(lltok::lparen, "expected '(' in binary constantexpr") || ParseGlobalTypeAndValue(Val0) || ParseToken(lltok::comma, "expected comma in binary constantexpr") || @@ -1965,10 +1983,25 @@ bool LLParser::ParseValID(ValID &ID) { return true; if (Val0->getType() != Val1->getType()) return Error(ID.Loc, "operands of constexpr must have same type"); + if (!Val0->getType()->isIntOrIntVector()) { + if (NUW) + return Error(ModifierLoc, "nuw only applies to integer operations"); + if (NSW) + return Error(ModifierLoc, "nsw only applies to integer operations"); + } + // API compatibility: Accept either integer or floating-point types with + // add, sub, and mul. if (!Val0->getType()->isIntOrIntVector() && !Val0->getType()->isFPOrFPVector()) return Error(ID.Loc,"constexpr requires integer, fp, or vector operands"); - ID.ConstantVal = Context.getConstantExpr(Opc, Val0, Val1); + Constant *C = Context.getConstantExpr(Opc, Val0, Val1); + if (NUW) + cast(C)->setHasNoUnsignedOverflow(true); + if (NSW) + cast(C)->setHasNoSignedOverflow(true); + if (Exact) + cast(C)->setIsExact(true); + ID.ConstantVal = C; ID.Kind = ValID::t_Constant; return false; } @@ -2055,49 +2088,6 @@ bool LLParser::ParseValID(ValID &ID) { ID.Kind = ValID::t_Constant; return false; } - case lltok::kw_nuw: { - Lex.Lex(); - bool AlsoSigned = EatIfPresent(lltok::kw_nsw); - if (Lex.getKind() != lltok::kw_add && - Lex.getKind() != lltok::kw_sub && - Lex.getKind() != lltok::kw_mul) - return TokError("expected 'add', 'sub', or 'mul'"); - bool Result = LLParser::ParseValID(ID); - if (!Result) { - cast(ID.ConstantVal) - ->setHasNoUnsignedOverflow(true); - if (AlsoSigned) - cast(ID.ConstantVal) - ->setHasNoSignedOverflow(true); - } - return Result; - } - case lltok::kw_nsw: { - Lex.Lex(); - bool AlsoUnsigned = EatIfPresent(lltok::kw_nuw); - if (Lex.getKind() != lltok::kw_add && - Lex.getKind() != lltok::kw_sub && - Lex.getKind() != lltok::kw_mul) - return TokError("expected 'add', 'sub', or 'mul'"); - bool Result = LLParser::ParseValID(ID); - if (!Result) { - cast(ID.ConstantVal) - ->setHasNoSignedOverflow(true); - if (AlsoUnsigned) - cast(ID.ConstantVal) - ->setHasNoUnsignedOverflow(true); - } - return Result; - } - case lltok::kw_exact: { - Lex.Lex(); - if (Lex.getKind() != lltok::kw_sdiv) - return TokError("expected 'sdiv'"); - bool Result = LLParser::ParseValID(ID); - if (!Result) - cast(ID.ConstantVal)->setIsExact(true); - return Result; - } } Lex.Lex(); @@ -2563,15 +2553,49 @@ bool LLParser::ParseInstruction(Instruction *&Inst, BasicBlock *BB, // Binary Operators. case lltok::kw_add: case lltok::kw_sub: - case lltok::kw_mul: + case lltok::kw_mul: { + bool NUW = false; + bool NSW = false; + LocTy ModifierLoc = Lex.getLoc(); + if (EatIfPresent(lltok::kw_nuw)) + NUW = true; + if (EatIfPresent(lltok::kw_nsw)) { + NSW = true; + if (EatIfPresent(lltok::kw_nuw)) + NUW = true; + } // API compatibility: Accept either integer or floating-point types. - return ParseArithmetic(Inst, PFS, KeywordVal, 0); + bool Result = ParseArithmetic(Inst, PFS, KeywordVal, 0); + if (!Result) { + if (!Inst->getType()->isIntOrIntVector()) { + if (NUW) + return Error(ModifierLoc, "nuw only applies to integer operations"); + if (NSW) + return Error(ModifierLoc, "nsw only applies to integer operations"); + } + if (NUW) + cast(Inst)->setHasNoUnsignedOverflow(true); + if (NSW) + cast(Inst)->setHasNoSignedOverflow(true); + } + return Result; + } case lltok::kw_fadd: case lltok::kw_fsub: case lltok::kw_fmul: return ParseArithmetic(Inst, PFS, KeywordVal, 2); + case lltok::kw_sdiv: { + bool Exact = false; + if (EatIfPresent(lltok::kw_exact)) + Exact = true; + bool Result = ParseArithmetic(Inst, PFS, KeywordVal, 1); + if (!Result) + if (Exact) + cast(Inst)->setIsExact(true); + return Result; + } + case lltok::kw_udiv: - case lltok::kw_sdiv: case lltok::kw_urem: case lltok::kw_srem: return ParseArithmetic(Inst, PFS, KeywordVal, 1); case lltok::kw_fdiv: @@ -2619,50 +2643,6 @@ bool LLParser::ParseInstruction(Instruction *&Inst, BasicBlock *BB, return ParseStore(Inst, PFS, true); else return TokError("expected 'load' or 'store'"); - case lltok::kw_nuw: { - bool AlsoSigned = EatIfPresent(lltok::kw_nsw); - if (Lex.getKind() == lltok::kw_add || - Lex.getKind() == lltok::kw_sub || - Lex.getKind() == lltok::kw_mul) { - Lex.Lex(); - KeywordVal = Lex.getUIntVal(); - bool Result = ParseArithmetic(Inst, PFS, KeywordVal, 0); - if (!Result) { - cast(Inst)->setHasNoUnsignedOverflow(true); - if (AlsoSigned) - cast(Inst)->setHasNoSignedOverflow(true); - } - return Result; - } - return TokError("expected 'add', 'sub', or 'mul'"); - } - case lltok::kw_nsw: { - bool AlsoUnsigned = EatIfPresent(lltok::kw_nuw); - if (Lex.getKind() == lltok::kw_add || - Lex.getKind() == lltok::kw_sub || - Lex.getKind() == lltok::kw_mul) { - Lex.Lex(); - KeywordVal = Lex.getUIntVal(); - bool Result = ParseArithmetic(Inst, PFS, KeywordVal, 1); - if (!Result) { - cast(Inst)->setHasNoSignedOverflow(true); - if (AlsoUnsigned) - cast(Inst)->setHasNoUnsignedOverflow(true); - } - return Result; - } - return TokError("expected 'add', 'sub', or 'mul'"); - } - case lltok::kw_exact: - if (Lex.getKind() == lltok::kw_sdiv) { - Lex.Lex(); - KeywordVal = Lex.getUIntVal(); - bool Result = ParseArithmetic(Inst, PFS, KeywordVal, 1); - if (!Result) - cast(Inst)->setIsExact(true); - return Result; - } - return TokError("expected 'udiv'"); case lltok::kw_getresult: return ParseGetResult(Inst, PFS); case lltok::kw_getelementptr: return ParseGetElementPtr(Inst, PFS); case lltok::kw_extractvalue: return ParseExtractValue(Inst, PFS); diff --git a/lib/VMCore/AsmWriter.cpp b/lib/VMCore/AsmWriter.cpp index bb117e1..3853813 100644 --- a/lib/VMCore/AsmWriter.cpp +++ b/lib/VMCore/AsmWriter.cpp @@ -848,12 +848,12 @@ static void WriteOptimizationInfo(raw_ostream &Out, const User *U) { if (const OverflowingBinaryOperator *OBO = dyn_cast(U)) { if (OBO->hasNoUnsignedOverflow()) - Out << "nuw "; + Out << " nuw"; if (OBO->hasNoSignedOverflow()) - Out << "nsw "; + Out << " nsw"; } else if (const SDivOperator *Div = dyn_cast(U)) { if (Div->isExact()) - Out << "exact "; + Out << " exact"; } } @@ -1061,8 +1061,8 @@ static void WriteConstantInt(raw_ostream &Out, const Constant *CV, } if (const ConstantExpr *CE = dyn_cast(CV)) { - WriteOptimizationInfo(Out, CE); Out << CE->getOpcodeName(); + WriteOptimizationInfo(Out, CE); if (CE->isCompare()) Out << ' ' << getPredicateText(CE->getPredicate()); Out << " ("; @@ -1694,12 +1694,12 @@ void AssemblyWriter::printInstruction(const Instruction &I) { Out << "tail "; } - // Print out optimization information. - WriteOptimizationInfo(Out, &I); - // Print out the opcode... Out << I.getOpcodeName(); + // Print out optimization information. + WriteOptimizationInfo(Out, &I); + // Print out the compare instruction predicates if (const CmpInst *CI = dyn_cast(&I)) Out << ' ' << getPredicateText(CI->getPredicate()); diff --git a/test/Analysis/ScalarEvolution/nsw.ll b/test/Analysis/ScalarEvolution/nsw.ll index 245ed6f..26528c9 100644 --- a/test/Analysis/ScalarEvolution/nsw.ll +++ b/test/Analysis/ScalarEvolution/nsw.ll @@ -22,7 +22,7 @@ bb: ; preds = %bb1, %bb.nph %tmp6 = sext i32 %i.01 to i64 ; [#uses=1] %tmp7 = getelementptr double* %p, i64 %tmp6 ; [#uses=1] store double %tmp5, double* %tmp7, align 8 - %tmp8 = nsw add i32 %i.01, 1 ; [#uses=2] + %tmp8 = add nsw i32 %i.01, 1 ; [#uses=2] br label %bb1 bb1: ; preds = %bb diff --git a/test/Assembler/flags-reversed.ll b/test/Assembler/flags-reversed.ll index d66095a..25fa6a0 100644 --- a/test/Assembler/flags-reversed.ll +++ b/test/Assembler/flags-reversed.ll @@ -3,16 +3,16 @@ @addr = external global i64 define i64 @add_both_reversed_ce() { -; CHECK: ret i64 nuw nsw add (i64 ptrtoint (i64* @addr to i64), i64 91) - ret i64 nsw nuw add (i64 ptrtoint (i64* @addr to i64), i64 91) +; CHECK: ret i64 add nuw nsw (i64 ptrtoint (i64* @addr to i64), i64 91) + ret i64 add nsw nuw (i64 ptrtoint (i64* @addr to i64), i64 91) } define i64 @sub_both_reversed_ce() { -; CHECK: ret i64 nuw nsw sub (i64 ptrtoint (i64* @addr to i64), i64 91) - ret i64 nsw nuw sub (i64 ptrtoint (i64* @addr to i64), i64 91) +; CHECK: ret i64 sub nuw nsw (i64 ptrtoint (i64* @addr to i64), i64 91) + ret i64 sub nsw nuw (i64 ptrtoint (i64* @addr to i64), i64 91) } define i64 @mul_both_reversed_ce() { -; CHECK: ret i64 nuw nsw mul (i64 ptrtoint (i64* @addr to i64), i64 91) - ret i64 nsw nuw mul (i64 ptrtoint (i64* @addr to i64), i64 91) +; CHECK: ret i64 mul nuw nsw (i64 ptrtoint (i64* @addr to i64), i64 91) + ret i64 mul nsw nuw (i64 ptrtoint (i64* @addr to i64), i64 91) } diff --git a/test/Assembler/flags-signed.ll b/test/Assembler/flags-signed.ll index 62c38a9..9c40813 100644 --- a/test/Assembler/flags-signed.ll +++ b/test/Assembler/flags-signed.ll @@ -3,16 +3,16 @@ @addr = external global i64 define i64 @add_signed_ce() { -; CHECK: ret i64 nsw add (i64 ptrtoint (i64* @addr to i64), i64 91) - ret i64 nsw add (i64 ptrtoint (i64* @addr to i64), i64 91) +; CHECK: ret i64 add nsw (i64 ptrtoint (i64* @addr to i64), i64 91) + ret i64 add nsw (i64 ptrtoint (i64* @addr to i64), i64 91) } define i64 @sub_signed_ce() { -; CHECK: ret i64 nsw sub (i64 ptrtoint (i64* @addr to i64), i64 91) - ret i64 nsw sub (i64 ptrtoint (i64* @addr to i64), i64 91) +; CHECK: ret i64 sub nsw (i64 ptrtoint (i64* @addr to i64), i64 91) + ret i64 sub nsw (i64 ptrtoint (i64* @addr to i64), i64 91) } define i64 @mul_signed_ce() { -; CHECK: ret i64 nsw mul (i64 ptrtoint (i64* @addr to i64), i64 91) - ret i64 nsw mul (i64 ptrtoint (i64* @addr to i64), i64 91) +; CHECK: ret i64 mul nsw (i64 ptrtoint (i64* @addr to i64), i64 91) + ret i64 mul nsw (i64 ptrtoint (i64* @addr to i64), i64 91) } diff --git a/test/Assembler/flags-unsigned.ll b/test/Assembler/flags-unsigned.ll index cd051af..1ddffca 100644 --- a/test/Assembler/flags-unsigned.ll +++ b/test/Assembler/flags-unsigned.ll @@ -3,16 +3,16 @@ @addr = external global i64 define i64 @add_unsigned_ce() { -; CHECK: ret i64 nuw add (i64 ptrtoint (i64* @addr to i64), i64 91) - ret i64 nuw add (i64 ptrtoint (i64* @addr to i64), i64 91) +; CHECK: ret i64 add nuw (i64 ptrtoint (i64* @addr to i64), i64 91) + ret i64 add nuw (i64 ptrtoint (i64* @addr to i64), i64 91) } define i64 @sub_unsigned_ce() { -; CHECK: ret i64 nuw sub (i64 ptrtoint (i64* @addr to i64), i64 91) - ret i64 nuw sub (i64 ptrtoint (i64* @addr to i64), i64 91) +; CHECK: ret i64 sub nuw (i64 ptrtoint (i64* @addr to i64), i64 91) + ret i64 sub nuw (i64 ptrtoint (i64* @addr to i64), i64 91) } define i64 @mul_unsigned_ce() { -; CHECK: ret i64 nuw mul (i64 ptrtoint (i64* @addr to i64), i64 91) - ret i64 nuw mul (i64 ptrtoint (i64* @addr to i64), i64 91) +; CHECK: ret i64 mul nuw (i64 ptrtoint (i64* @addr to i64), i64 91) + ret i64 mul nuw (i64 ptrtoint (i64* @addr to i64), i64 91) } diff --git a/test/Assembler/flags.ll b/test/Assembler/flags.ll index a0c2abc..4efb1cd 100644 --- a/test/Assembler/flags.ll +++ b/test/Assembler/flags.ll @@ -3,38 +3,38 @@ @addr = external global i64 define i64 @add_unsigned(i64 %x, i64 %y) { -; CHECK: %z = nuw add i64 %x, %y - %z = nuw add i64 %x, %y +; CHECK: %z = add nuw i64 %x, %y + %z = add nuw i64 %x, %y ret i64 %z } define i64 @sub_unsigned(i64 %x, i64 %y) { -; CHECK: %z = nuw sub i64 %x, %y - %z = nuw sub i64 %x, %y +; CHECK: %z = sub nuw i64 %x, %y + %z = sub nuw i64 %x, %y ret i64 %z } define i64 @mul_unsigned(i64 %x, i64 %y) { -; CHECK: %z = nuw mul i64 %x, %y - %z = nuw mul i64 %x, %y +; CHECK: %z = mul nuw i64 %x, %y + %z = mul nuw i64 %x, %y ret i64 %z } define i64 @add_signed(i64 %x, i64 %y) { -; CHECK: %z = nsw add i64 %x, %y - %z = nsw add i64 %x, %y +; CHECK: %z = add nsw i64 %x, %y + %z = add nsw i64 %x, %y ret i64 %z } define i64 @sub_signed(i64 %x, i64 %y) { -; CHECK: %z = nsw sub i64 %x, %y - %z = nsw sub i64 %x, %y +; CHECK: %z = sub nsw i64 %x, %y + %z = sub nsw i64 %x, %y ret i64 %z } define i64 @mul_signed(i64 %x, i64 %y) { -; CHECK: %z = nsw mul i64 %x, %y - %z = nsw mul i64 %x, %y +; CHECK: %z = mul nsw i64 %x, %y + %z = mul nsw i64 %x, %y ret i64 %z } @@ -57,44 +57,44 @@ define i64 @mul_plain(i64 %x, i64 %y) { } define i64 @add_both(i64 %x, i64 %y) { -; CHECK: %z = nuw nsw add i64 %x, %y - %z = nuw nsw add i64 %x, %y +; CHECK: %z = add nuw nsw i64 %x, %y + %z = add nuw nsw i64 %x, %y ret i64 %z } define i64 @sub_both(i64 %x, i64 %y) { -; CHECK: %z = nuw nsw sub i64 %x, %y - %z = nuw nsw sub i64 %x, %y +; CHECK: %z = sub nuw nsw i64 %x, %y + %z = sub nuw nsw i64 %x, %y ret i64 %z } define i64 @mul_both(i64 %x, i64 %y) { -; CHECK: %z = nuw nsw mul i64 %x, %y - %z = nuw nsw mul i64 %x, %y +; CHECK: %z = mul nuw nsw i64 %x, %y + %z = mul nuw nsw i64 %x, %y ret i64 %z } define i64 @add_both_reversed(i64 %x, i64 %y) { -; CHECK: %z = nuw nsw add i64 %x, %y - %z = nsw nuw add i64 %x, %y +; CHECK: %z = add nuw nsw i64 %x, %y + %z = add nsw nuw i64 %x, %y ret i64 %z } define i64 @sub_both_reversed(i64 %x, i64 %y) { -; CHECK: %z = nuw nsw sub i64 %x, %y - %z = nsw nuw sub i64 %x, %y +; CHECK: %z = sub nuw nsw i64 %x, %y + %z = sub nsw nuw i64 %x, %y ret i64 %z } define i64 @mul_both_reversed(i64 %x, i64 %y) { -; CHECK: %z = nuw nsw mul i64 %x, %y - %z = nsw nuw mul i64 %x, %y +; CHECK: %z = mul nuw nsw i64 %x, %y + %z = mul nsw nuw i64 %x, %y ret i64 %z } define i64 @sdiv_exact(i64 %x, i64 %y) { -; CHECK: %z = exact sdiv i64 %x, %y - %z = exact sdiv i64 %x, %y +; CHECK: %z = sdiv exact i64 %x, %y + %z = sdiv exact i64 %x, %y ret i64 %z } @@ -105,21 +105,21 @@ define i64 @sdiv_plain(i64 %x, i64 %y) { } define i64 @add_both_ce() { -; CHECK: ret i64 nuw nsw add (i64 ptrtoint (i64* @addr to i64), i64 91) - ret i64 nsw nuw add (i64 ptrtoint (i64* @addr to i64), i64 91) +; CHECK: ret i64 add nuw nsw (i64 ptrtoint (i64* @addr to i64), i64 91) + ret i64 add nsw nuw (i64 ptrtoint (i64* @addr to i64), i64 91) } define i64 @sub_both_ce() { -; CHECK: ret i64 nuw nsw sub (i64 ptrtoint (i64* @addr to i64), i64 91) - ret i64 nsw nuw sub (i64 ptrtoint (i64* @addr to i64), i64 91) +; CHECK: ret i64 sub nuw nsw (i64 ptrtoint (i64* @addr to i64), i64 91) + ret i64 sub nsw nuw (i64 ptrtoint (i64* @addr to i64), i64 91) } define i64 @mul_both_ce() { -; CHECK: ret i64 nuw nsw mul (i64 ptrtoint (i64* @addr to i64), i64 91) - ret i64 nuw nsw mul (i64 ptrtoint (i64* @addr to i64), i64 91) +; CHECK: ret i64 mul nuw nsw (i64 ptrtoint (i64* @addr to i64), i64 91) + ret i64 mul nuw nsw (i64 ptrtoint (i64* @addr to i64), i64 91) } define i64 @sdiv_exact_ce() { -; CHECK: ret i64 exact sdiv (i64 ptrtoint (i64* @addr to i64), i64 91) - ret i64 exact sdiv (i64 ptrtoint (i64* @addr to i64), i64 91) +; CHECK: ret i64 sdiv exact (i64 ptrtoint (i64* @addr to i64), i64 91) + ret i64 sdiv exact (i64 ptrtoint (i64* @addr to i64), i64 91) } -- cgit v1.1