[llvm-commits] [llvm] r125006 - in /llvm/trunk: docs/LangRef.html include/llvm/Constants.h include/llvm/Operator.h lib/AsmParser/LLParser.cpp lib/Bitcode/Reader/BitcodeReader.cpp lib/VMCore/Constants.cpp test/Assembler/2003-05-21-MalformedShiftCrash.ll test/Assembler/flags.ll
Nick Lewycky
nicholas at mxc.ca
Tue Feb 8 00:42:16 PST 2011
Chris Lattner wrote:
> Author: lattner
> Date: Mon Feb 7 10:40:21 2011
> New Revision: 125006
>
> URL: http://llvm.org/viewvc/llvm-project?rev=125006&view=rev
> Log:
> implement .ll and .bc support for nsw/nuw on shl and exact on lshr/ashr.
> Factor some code better.
>
> Modified:
> llvm/trunk/docs/LangRef.html
> llvm/trunk/include/llvm/Constants.h
> llvm/trunk/include/llvm/Operator.h
> llvm/trunk/lib/AsmParser/LLParser.cpp
> llvm/trunk/lib/Bitcode/Reader/BitcodeReader.cpp
> llvm/trunk/lib/VMCore/Constants.cpp
> llvm/trunk/test/Assembler/2003-05-21-MalformedShiftCrash.ll
> llvm/trunk/test/Assembler/flags.ll
>
> Modified: llvm/trunk/docs/LangRef.html
> URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/docs/LangRef.html?rev=125006&r1=125005&r2=125006&view=diff
> ==============================================================================
> --- llvm/trunk/docs/LangRef.html (original)
> +++ llvm/trunk/docs/LangRef.html Mon Feb 7 10:40:21 2011
> @@ -3684,7 +3684,10 @@
>
> <h5>Syntax:</h5>
> <pre>
> -<result> = shl<ty><op1>,<op2><i>; yields {ty}:result</i>
> +<result> = shl<ty><op1>,<op2><i>; yields {ty}:result</i>
> +<result> = shl nuw<ty><op1>,<op2><i>; yields {ty}:result</i>
> +<result> = shl nsw<ty><op1>,<op2><i>; yields {ty}:result</i>
> +<result> = shl nuw nsw<ty><op1>,<op2><i>; yields {ty}:result</i>
> </pre>
>
> <h5>Overview:</h5>
> @@ -3704,6 +3707,14 @@
> vectors, each vector element of<tt>op1</tt> is shifted by the corresponding
> shift amount in<tt>op2</tt>.</p>
>
> +<p>If the<tt>nuw</tt> keyword is present, then the shift produces a
> +<a href="#trapvalues">trap value</a> if it shifts out any non-zero bits. If
> + the<tt>nsw</tt> keywrod is present, then the shift produces a
Typo: keywrod
Nick
> +<a href="#trapvalues">trap value</a> if it shifts out any bits that disagree
> + with the resultant sign bit. As such, NUW/NSW have the same semantics as
> + they would if the shift were expressed as a mul instruction with the same
> + nsw/nuw bits in (mul %op1, (shl 1, %op2)).</p>
> +
> <h5>Example:</h5>
> <pre>
> <result> = shl i32 4, %var<i>; yields {i32}: 4<< %var</i>
> @@ -3723,7 +3734,8 @@
>
> <h5>Syntax:</h5>
> <pre>
> -<result> = lshr<ty><op1>,<op2><i>; yields {ty}:result</i>
> +<result> = lshr<ty><op1>,<op2><i>; yields {ty}:result</i>
> +<result> = lshr exact<ty><op1>,<op2><i>; yields {ty}:result</i>
> </pre>
>
> <h5>Overview:</h5>
> @@ -3743,6 +3755,11 @@
> vectors, each vector element of<tt>op1</tt> is shifted by the corresponding
> shift amount in<tt>op2</tt>.</p>
>
> +<p>If the<tt>exact</tt> keyword is present, the result value of the
> +<tt>lshr</tt> is a<a href="#trapvalues">trap value</a> if any of the bits
> + shifted out are non-zero.</p>
> +
> +
> <h5>Example:</h5>
> <pre>
> <result> = lshr i32 4, 1<i>; yields {i32}:result = 2</i>
> @@ -3762,7 +3779,8 @@
>
> <h5>Syntax:</h5>
> <pre>
> -<result> = ashr<ty><op1>,<op2><i>; yields {ty}:result</i>
> +<result> = ashr<ty><op1>,<op2><i>; yields {ty}:result</i>
> +<result> = ashr exact<ty><op1>,<op2><i>; yields {ty}:result</i>
> </pre>
>
> <h5>Overview:</h5>
> @@ -3783,6 +3801,10 @@
> the arguments are vectors, each vector element of<tt>op1</tt> is shifted by
> the corresponding shift amount in<tt>op2</tt>.</p>
>
> +<p>If the<tt>exact</tt> keyword is present, the result value of the
> +<tt>ashr</tt> is a<a href="#trapvalues">trap value</a> if any of the bits
> + shifted out are non-zero.</p>
> +
> <h5>Example:</h5>
> <pre>
> <result> = ashr i32 4, 1<i>; yields {i32}:result = 2</i>
>
> Modified: llvm/trunk/include/llvm/Constants.h
> URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/include/llvm/Constants.h?rev=125006&r1=125005&r2=125006&view=diff
> ==============================================================================
> --- llvm/trunk/include/llvm/Constants.h (original)
> +++ llvm/trunk/include/llvm/Constants.h Mon Feb 7 10:40:21 2011
> @@ -724,8 +724,12 @@
> static Constant *getNUWSub(Constant *C1, Constant *C2);
> static Constant *getNSWMul(Constant *C1, Constant *C2);
> static Constant *getNUWMul(Constant *C1, Constant *C2);
> + static Constant *getNSWShl(Constant *C1, Constant *C2);
> + static Constant *getNUWShl(Constant *C1, Constant *C2);
> static Constant *getExactSDiv(Constant *C1, Constant *C2);
> static Constant *getExactUDiv(Constant *C1, Constant *C2);
> + static Constant *getExactAShr(Constant *C1, Constant *C2);
> + static Constant *getExactLShr(Constant *C1, Constant *C2);
>
> /// Transparently provide more efficient getOperand methods.
> DECLARE_TRANSPARENT_OPERAND_ACCESSORS(Constant);
>
> Modified: llvm/trunk/include/llvm/Operator.h
> URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/include/llvm/Operator.h?rev=125006&r1=125005&r2=125006&view=diff
> ==============================================================================
> --- llvm/trunk/include/llvm/Operator.h (original)
> +++ llvm/trunk/include/llvm/Operator.h Mon Feb 7 10:40:21 2011
> @@ -106,66 +106,14 @@
> static inline bool classof(const Instruction *I) {
> return I->getOpcode() == Instruction::Add ||
> I->getOpcode() == Instruction::Sub ||
> - I->getOpcode() == Instruction::Mul;
> + I->getOpcode() == Instruction::Mul ||
> + I->getOpcode() == Instruction::Shl;
> }
> static inline bool classof(const ConstantExpr *CE) {
> return CE->getOpcode() == Instruction::Add ||
> CE->getOpcode() == Instruction::Sub ||
> - CE->getOpcode() == Instruction::Mul;
> - }
> - static inline bool classof(const Value *V) {
> - return (isa<Instruction>(V)&& classof(cast<Instruction>(V))) ||
> - (isa<ConstantExpr>(V)&& classof(cast<ConstantExpr>(V)));
> - }
> -};
> -
> -/// AddOperator - Utility class for integer addition operators.
> -///
> -class AddOperator : public OverflowingBinaryOperator {
> - ~AddOperator(); // do not implement
> -public:
> - static inline bool classof(const AddOperator *) { return true; }
> - static inline bool classof(const Instruction *I) {
> - return I->getOpcode() == Instruction::Add;
> - }
> - static inline bool classof(const ConstantExpr *CE) {
> - return CE->getOpcode() == Instruction::Add;
> - }
> - static inline bool classof(const Value *V) {
> - return (isa<Instruction>(V)&& classof(cast<Instruction>(V))) ||
> - (isa<ConstantExpr>(V)&& classof(cast<ConstantExpr>(V)));
> - }
> -};
> -
> -/// SubOperator - Utility class for integer subtraction operators.
> -///
> -class SubOperator : public OverflowingBinaryOperator {
> - ~SubOperator(); // do not implement
> -public:
> - static inline bool classof(const SubOperator *) { return true; }
> - static inline bool classof(const Instruction *I) {
> - return I->getOpcode() == Instruction::Sub;
> - }
> - static inline bool classof(const ConstantExpr *CE) {
> - return CE->getOpcode() == Instruction::Sub;
> - }
> - static inline bool classof(const Value *V) {
> - return (isa<Instruction>(V)&& classof(cast<Instruction>(V))) ||
> - (isa<ConstantExpr>(V)&& classof(cast<ConstantExpr>(V)));
> - }
> -};
> -
> -/// MulOperator - Utility class for integer multiplication operators.
> -///
> -class MulOperator : public OverflowingBinaryOperator {
> - ~MulOperator(); // do not implement
> -public:
> - static inline bool classof(const MulOperator *) { return true; }
> - static inline bool classof(const Instruction *I) {
> - return I->getOpcode() == Instruction::Mul;
> - }
> - static inline bool classof(const ConstantExpr *CE) {
> - return CE->getOpcode() == Instruction::Mul;
> + CE->getOpcode() == Instruction::Mul ||
> + CE->getOpcode() == Instruction::Shl;
> }
> static inline bool classof(const Value *V) {
> return (isa<Instruction>(V)&& classof(cast<Instruction>(V))) ||
> @@ -196,63 +144,74 @@
> return SubclassOptionalData& IsExact;
> }
>
> - static inline bool classof(const ConstantExpr *CE) {
> - return CE->getOpcode() == Instruction::SDiv ||
> - CE->getOpcode() == Instruction::UDiv;
> - }
> - static inline bool classof(const Instruction *I) {
> - return I->getOpcode() == Instruction::SDiv ||
> - I->getOpcode() == Instruction::UDiv;
> - }
> - static inline bool classof(const Value *V) {
> - return (isa<Instruction>(V)&& classof(cast<Instruction>(V))) ||
> - (isa<ConstantExpr>(V)&& classof(cast<ConstantExpr>(V)));
> + static bool isPossiblyExactOpcode(unsigned OpC) {
> + return OpC == Instruction::SDiv ||
> + OpC == Instruction::UDiv ||
> + OpC == Instruction::AShr ||
> + OpC == Instruction::LShr;
> }
> -};
> -
> -/// SDivOperator - An Operator with opcode Instruction::SDiv.
> -///
> -class SDivOperator : public PossiblyExactOperator {
> -public:
> - // Methods for support type inquiry through isa, cast, and dyn_cast:
> - static inline bool classof(const SDivOperator *) { return true; }
> static inline bool classof(const ConstantExpr *CE) {
> - return CE->getOpcode() == Instruction::SDiv;
> + return isPossiblyExactOpcode(CE->getOpcode());
> }
> static inline bool classof(const Instruction *I) {
> - return I->getOpcode() == Instruction::SDiv;
> + return isPossiblyExactOpcode(I->getOpcode());
> }
> static inline bool classof(const Value *V) {
> return (isa<Instruction>(V)&& classof(cast<Instruction>(V))) ||
> (isa<ConstantExpr>(V)&& classof(cast<ConstantExpr>(V)));
> }
> };
> +
>
> -/// UDivOperator - An Operator with opcode Instruction::UDiv.
> -///
> -class UDivOperator : public PossiblyExactOperator {
> +
> +/// ConcreteOperator - A helper template for defining operators for individual
> +/// opcodes.
> +template<typename SuperClass, unsigned Opc>
> +class ConcreteOperator : public SuperClass {
> + ~ConcreteOperator(); // DO NOT IMPLEMENT
> public:
> - // Methods for support type inquiry through isa, cast, and dyn_cast:
> - static inline bool classof(const UDivOperator *) { return true; }
> - static inline bool classof(const ConstantExpr *CE) {
> - return CE->getOpcode() == Instruction::UDiv;
> + static inline bool classof(const ConcreteOperator<SuperClass, Opc> *) {
> + return true;
> }
> static inline bool classof(const Instruction *I) {
> - return I->getOpcode() == Instruction::UDiv;
> + return I->getOpcode() == Opc;
> + }
> + static inline bool classof(const ConstantExpr *CE) {
> + return CE->getOpcode() == Opc;
> }
> static inline bool classof(const Value *V) {
> return (isa<Instruction>(V)&& classof(cast<Instruction>(V))) ||
> - (isa<ConstantExpr>(V)&& classof(cast<ConstantExpr>(V)));
> + (isa<ConstantExpr>(V)&& classof(cast<ConstantExpr>(V)));
> }
> };
> +
> +class AddOperator
> + : public ConcreteOperator<OverflowingBinaryOperator, Instruction::Add> {};
> +class SubOperator
> + : public ConcreteOperator<OverflowingBinaryOperator, Instruction::Sub> {};
> +class MulOperator
> + : public ConcreteOperator<OverflowingBinaryOperator, Instruction::Mul> {};
> +class ShlOperator
> + : public ConcreteOperator<OverflowingBinaryOperator, Instruction::Shl> {};
> +
> +
> +class SDivOperator
> + : public ConcreteOperator<PossiblyExactOperator, Instruction::SDiv> {};
> +class UDivOperator
> + : public ConcreteOperator<PossiblyExactOperator, Instruction::UDiv> {};
> +class AShrOperator
> + : public ConcreteOperator<PossiblyExactOperator, Instruction::AShr> {};
> +class LShrOperator
> + : public ConcreteOperator<PossiblyExactOperator, Instruction::LShr> {};
> +
>
> -class GEPOperator : public Operator {
> +
> +class GEPOperator
> + : public ConcreteOperator<Operator, Instruction::GetElementPtr> {
> enum {
> IsInBounds = (1<< 0)
> };
>
> - ~GEPOperator(); // do not implement
> -
> friend class GetElementPtrInst;
> friend class ConstantExpr;
> void setIsInBounds(bool B) {
> @@ -301,8 +260,8 @@
> /// value, just potentially different types.
> bool hasAllZeroIndices() const {
> for (const_op_iterator I = idx_begin(), E = idx_end(); I != E; ++I) {
> - if (Constant *C = dyn_cast<Constant>(I))
> - if (C->isNullValue())
> + if (ConstantInt *C = dyn_cast<ConstantInt>(I))
> + if (C->isZero())
> continue;
> return false;
> }
> @@ -319,21 +278,6 @@
> }
> return true;
> }
> -
> -
> - // Methods for support type inquiry through isa, cast, and dyn_cast:
> - static inline bool classof(const GEPOperator *) { return true; }
> - static inline bool classof(const GetElementPtrInst *) { return true; }
> - static inline bool classof(const ConstantExpr *CE) {
> - return CE->getOpcode() == Instruction::GetElementPtr;
> - }
> - static inline bool classof(const Instruction *I) {
> - return I->getOpcode() == Instruction::GetElementPtr;
> - }
> - static inline bool classof(const Value *V) {
> - return (isa<Instruction>(V)&& classof(cast<Instruction>(V))) ||
> - (isa<ConstantExpr>(V)&& classof(cast<ConstantExpr>(V)));
> - }
> };
>
> } // End llvm namespace
>
> Modified: llvm/trunk/lib/AsmParser/LLParser.cpp
> URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/AsmParser/LLParser.cpp?rev=125006&r1=125005&r2=125006&view=diff
> ==============================================================================
> --- llvm/trunk/lib/AsmParser/LLParser.cpp (original)
> +++ llvm/trunk/lib/AsmParser/LLParser.cpp Mon Feb 7 10:40:21 2011
> @@ -2286,7 +2286,10 @@
> case lltok::kw_fdiv:
> case lltok::kw_urem:
> case lltok::kw_srem:
> - case lltok::kw_frem: {
> + case lltok::kw_frem:
> + case lltok::kw_shl:
> + case lltok::kw_lshr:
> + case lltok::kw_ashr: {
> bool NUW = false;
> bool NSW = false;
> bool Exact = false;
> @@ -2294,9 +2297,8 @@
> Constant *Val0, *Val1;
> Lex.Lex();
> LocTy ModifierLoc = Lex.getLoc();
> - if (Opc == Instruction::Add ||
> - Opc == Instruction::Sub ||
> - Opc == Instruction::Mul) {
> + if (Opc == Instruction::Add || Opc == Instruction::Sub ||
> + Opc == Instruction::Mul || Opc == Instruction::Shl) {
> if (EatIfPresent(lltok::kw_nuw))
> NUW = true;
> if (EatIfPresent(lltok::kw_nsw)) {
> @@ -2304,7 +2306,8 @@
> if (EatIfPresent(lltok::kw_nuw))
> NUW = true;
> }
> - } else if (Opc == Instruction::SDiv || Opc == Instruction::UDiv) {
> + } else if (Opc == Instruction::SDiv || Opc == Instruction::UDiv ||
> + Opc == Instruction::LShr || Opc == Instruction::AShr) {
> if (EatIfPresent(lltok::kw_exact))
> Exact = true;
> }
> @@ -2331,6 +2334,9 @@
> case Instruction::SDiv:
> case Instruction::URem:
> case Instruction::SRem:
> + case Instruction::Shl:
> + case Instruction::AShr:
> + case Instruction::LShr:
> if (!Val0->getType()->isIntOrIntVectorTy())
> return Error(ID.Loc, "constexpr requires integer operands");
> break;
> @@ -2355,9 +2361,6 @@
> }
>
> // Logical Operations
> - case lltok::kw_shl:
> - case lltok::kw_lshr:
> - case lltok::kw_ashr:
> case lltok::kw_and:
> case lltok::kw_or:
> case lltok::kw_xor: {
> @@ -3002,55 +3005,38 @@
> // Binary Operators.
> case lltok::kw_add:
> case lltok::kw_sub:
> - case lltok::kw_mul: {
> - bool NUW = false;
> - bool NSW = false;
> + case lltok::kw_mul:
> + case lltok::kw_shl: {
> 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;
> - }
> - bool Result = ParseArithmetic(Inst, PFS, KeywordVal, 1);
> - if (!Result) {
> - if (!Inst->getType()->isIntOrIntVectorTy()) {
> - 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<BinaryOperator>(Inst)->setHasNoUnsignedWrap(true);
> - if (NSW)
> - cast<BinaryOperator>(Inst)->setHasNoSignedWrap(true);
> - }
> - return Result;
> + bool NUW = EatIfPresent(lltok::kw_nuw);
> + bool NSW = EatIfPresent(lltok::kw_nsw);
> + if (!NUW) NUW = EatIfPresent(lltok::kw_nuw);
> +
> + if (ParseArithmetic(Inst, PFS, KeywordVal, 1)) return true;
> +
> + if (NUW) cast<BinaryOperator>(Inst)->setHasNoUnsignedWrap(true);
> + if (NSW) cast<BinaryOperator>(Inst)->setHasNoSignedWrap(true);
> + return false;
> }
> case lltok::kw_fadd:
> case lltok::kw_fsub:
> case lltok::kw_fmul: return ParseArithmetic(Inst, PFS, KeywordVal, 2);
>
> case lltok::kw_sdiv:
> - case lltok::kw_udiv: {
> - bool Exact = false;
> - if (EatIfPresent(lltok::kw_exact))
> - Exact = true;
> - bool Result = ParseArithmetic(Inst, PFS, KeywordVal, 1);
> - if (!Result)
> - if (Exact)
> - cast<BinaryOperator>(Inst)->setIsExact(true);
> - return Result;
> + case lltok::kw_udiv:
> + case lltok::kw_lshr:
> + case lltok::kw_ashr: {
> + bool Exact = EatIfPresent(lltok::kw_exact);
> +
> + if (ParseArithmetic(Inst, PFS, KeywordVal, 1)) return true;
> + if (Exact) cast<BinaryOperator>(Inst)->setIsExact(true);
> + return false;
> }
>
> case lltok::kw_urem:
> case lltok::kw_srem: return ParseArithmetic(Inst, PFS, KeywordVal, 1);
> case lltok::kw_fdiv:
> case lltok::kw_frem: return ParseArithmetic(Inst, PFS, KeywordVal, 2);
> - case lltok::kw_shl:
> - case lltok::kw_lshr:
> - case lltok::kw_ashr:
> case lltok::kw_and:
> case lltok::kw_or:
> case lltok::kw_xor: return ParseLogical(Inst, PFS, KeywordVal);
>
> Modified: llvm/trunk/lib/Bitcode/Reader/BitcodeReader.cpp
> URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/Bitcode/Reader/BitcodeReader.cpp?rev=125006&r1=125005&r2=125006&view=diff
> ==============================================================================
> --- llvm/trunk/lib/Bitcode/Reader/BitcodeReader.cpp (original)
> +++ llvm/trunk/lib/Bitcode/Reader/BitcodeReader.cpp Mon Feb 7 10:40:21 2011
> @@ -1085,13 +1085,16 @@
> if (Record.size()>= 4) {
> if (Opc == Instruction::Add ||
> Opc == Instruction::Sub ||
> - Opc == Instruction::Mul) {
> + Opc == Instruction::Mul ||
> + Opc == Instruction::Shl) {
> if (Record[3]& (1<< bitc::OBO_NO_SIGNED_WRAP))
> Flags |= OverflowingBinaryOperator::NoSignedWrap;
> if (Record[3]& (1<< bitc::OBO_NO_UNSIGNED_WRAP))
> Flags |= OverflowingBinaryOperator::NoUnsignedWrap;
> } else if (Opc == Instruction::SDiv ||
> - Opc == Instruction::UDiv) {
> + Opc == Instruction::UDiv ||
> + Opc == Instruction::LShr ||
> + Opc == Instruction::AShr) {
> if (Record[3]& (1<< bitc::PEO_EXACT))
> Flags |= SDivOperator::IsExact;
> }
> @@ -1901,13 +1904,16 @@
> if (OpNum< Record.size()) {
> if (Opc == Instruction::Add ||
> Opc == Instruction::Sub ||
> - Opc == Instruction::Mul) {
> + Opc == Instruction::Mul ||
> + Opc == Instruction::Shl) {
> if (Record[OpNum]& (1<< bitc::OBO_NO_SIGNED_WRAP))
> cast<BinaryOperator>(I)->setHasNoSignedWrap(true);
> if (Record[OpNum]& (1<< bitc::OBO_NO_UNSIGNED_WRAP))
> cast<BinaryOperator>(I)->setHasNoUnsignedWrap(true);
> } else if (Opc == Instruction::SDiv ||
> - Opc == Instruction::UDiv) {
> + Opc == Instruction::UDiv ||
> + Opc == Instruction::LShr ||
> + Opc == Instruction::AShr) {
> if (Record[OpNum]& (1<< bitc::PEO_EXACT))
> cast<BinaryOperator>(I)->setIsExact(true);
> }
>
> Modified: llvm/trunk/lib/VMCore/Constants.cpp
> URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/VMCore/Constants.cpp?rev=125006&r1=125005&r2=125006&view=diff
> ==============================================================================
> --- llvm/trunk/lib/VMCore/Constants.cpp (original)
> +++ llvm/trunk/lib/VMCore/Constants.cpp Mon Feb 7 10:40:21 2011
> @@ -7,7 +7,7 @@
> //
> //===----------------------------------------------------------------------===//
> //
> -// This file implements the Constant* classes.
> +// This file implements the Constant *classes.
> //
> //===----------------------------------------------------------------------===//
>
> @@ -72,7 +72,7 @@
> }
> }
>
> -Constant* Constant::getIntegerValue(const Type *Ty, const APInt&V) {
> +Constant *Constant::getIntegerValue(const Type *Ty, const APInt&V) {
> const Type *ScalarTy = Ty->getScalarType();
>
> // Create the base integer constant.
> @@ -89,7 +89,7 @@
> return C;
> }
>
> -Constant* Constant::getAllOnesValue(const Type *Ty) {
> +Constant *Constant::getAllOnesValue(const Type *Ty) {
> if (const IntegerType *ITy = dyn_cast<IntegerType>(Ty))
> return ConstantInt::get(Ty->getContext(),
> APInt::getAllOnesValue(ITy->getBitWidth()));
> @@ -296,7 +296,7 @@
> return Slot;
> }
>
> -Constant* ConstantInt::get(const Type* Ty, uint64_t V, bool isSigned) {
> +Constant *ConstantInt::get(const Type* Ty, uint64_t V, bool isSigned) {
> Constant *C = get(cast<IntegerType>(Ty->getScalarType()),
> V, isSigned);
>
> @@ -321,7 +321,7 @@
> return get(Ty, V, true);
> }
>
> -Constant* ConstantInt::get(const Type* Ty, const APInt& V) {
> +Constant *ConstantInt::get(const Type* Ty, const APInt& V) {
> ConstantInt *C = get(Ty->getContext(), V);
> assert(C->getType() == Ty->getScalarType()&&
> "ConstantInt type doesn't match the type implied by its value!");
> @@ -360,7 +360,7 @@
> /// get() - This returns a constant fp for the specified value in the
> /// specified type. This should only be used for simple constant values like
> /// 2.0/1.0 etc, that are known-valid both as double and as the target format.
> -Constant* ConstantFP::get(const Type* Ty, double V) {
> +Constant *ConstantFP::get(const Type* Ty, double V) {
> LLVMContext&Context = Ty->getContext();
>
> APFloat FV(V);
> @@ -378,7 +378,7 @@
> }
>
>
> -Constant* ConstantFP::get(const Type* Ty, StringRef Str) {
> +Constant *ConstantFP::get(const Type* Ty, StringRef Str) {
> LLVMContext&Context = Ty->getContext();
>
> APFloat FV(*TypeToFloatSemantics(Ty->getScalarType()), Str);
> @@ -401,7 +401,7 @@
> }
>
>
> -Constant* ConstantFP::getZeroValueForNegation(const Type* Ty) {
> +Constant *ConstantFP::getZeroValueForNegation(const Type* Ty) {
> if (const VectorType *PTy = dyn_cast<VectorType>(Ty))
> if (PTy->getElementType()->isFloatingPointTy()) {
> std::vector<Constant*> zeros(PTy->getNumElements(),
> @@ -509,7 +509,7 @@
> }
>
>
> -Constant* ConstantArray::get(const ArrayType* T, Constant* const* Vals,
> +Constant *ConstantArray::get(const ArrayType* T, Constant *const* Vals,
> unsigned NumVals) {
> // FIXME: make this the primary ctor method.
> return get(T, std::vector<Constant*>(Vals, Vals+NumVals));
> @@ -521,7 +521,7 @@
> /// Otherwise, the length parameter specifies how much of the string to use
> /// and it won't be null terminated.
> ///
> -Constant* ConstantArray::get(LLVMContext&Context, StringRef Str,
> +Constant *ConstantArray::get(LLVMContext&Context, StringRef Str,
> bool AddNull) {
> std::vector<Constant*> ElementVals;
> ElementVals.reserve(Str.size() + size_t(AddNull));
> @@ -557,7 +557,7 @@
> }
>
> // ConstantStruct accessors.
> -Constant* ConstantStruct::get(const StructType* T,
> +Constant *ConstantStruct::get(const StructType* T,
> const std::vector<Constant*>& V) {
> LLVMContextImpl* pImpl = T->getContext().pImpl;
>
> @@ -569,7 +569,7 @@
> return ConstantAggregateZero::get(T);
> }
>
> -Constant* ConstantStruct::get(LLVMContext&Context,
> +Constant *ConstantStruct::get(LLVMContext&Context,
> const std::vector<Constant*>& V, bool packed) {
> std::vector<const Type*> StructEls;
> StructEls.reserve(V.size());
> @@ -578,8 +578,8 @@
> return get(StructType::get(Context, StructEls, packed), V);
> }
>
> -Constant* ConstantStruct::get(LLVMContext&Context,
> - Constant* const *Vals, unsigned NumVals,
> +Constant *ConstantStruct::get(LLVMContext&Context,
> + Constant *const *Vals, unsigned NumVals,
> bool Packed) {
> // FIXME: make this the primary ctor method.
> return get(Context, std::vector<Constant*>(Vals, Vals+NumVals), Packed);
> @@ -601,7 +601,7 @@
> }
>
> // ConstantVector accessors.
> -Constant* ConstantVector::get(const VectorType* T,
> +Constant *ConstantVector::get(const VectorType* T,
> const std::vector<Constant*>& V) {
> assert(!V.empty()&& "Vectors can't be empty");
> LLVMContext&Context = T->getContext();
> @@ -629,68 +629,89 @@
> return pImpl->VectorConstants.getOrCreate(T, V);
> }
>
> -Constant* ConstantVector::get(const std::vector<Constant*>& V) {
> +Constant *ConstantVector::get(const std::vector<Constant*>& V) {
> assert(!V.empty()&& "Cannot infer type if V is empty");
> return get(VectorType::get(V.front()->getType(),V.size()), V);
> }
>
> -Constant* ConstantVector::get(Constant* const* Vals, unsigned NumVals) {
> +Constant *ConstantVector::get(Constant *const* Vals, unsigned NumVals) {
> // FIXME: make this the primary ctor method.
> return get(std::vector<Constant*>(Vals, Vals+NumVals));
> }
>
> -Constant* ConstantExpr::getNSWNeg(Constant* C) {
> +Constant *ConstantExpr::getNSWNeg(Constant *C) {
> assert(C->getType()->isIntOrIntVectorTy()&&
> "Cannot NEG a nonintegral value!");
> return getNSWSub(ConstantFP::getZeroValueForNegation(C->getType()), C);
> }
>
> -Constant* ConstantExpr::getNUWNeg(Constant* C) {
> +Constant *ConstantExpr::getNUWNeg(Constant *C) {
> assert(C->getType()->isIntOrIntVectorTy()&&
> "Cannot NEG a nonintegral value!");
> return getNUWSub(ConstantFP::getZeroValueForNegation(C->getType()), C);
> }
>
> -Constant* ConstantExpr::getNSWAdd(Constant* C1, Constant* C2) {
> +Constant *ConstantExpr::getNSWAdd(Constant *C1, Constant *C2) {
> return getTy(C1->getType(), Instruction::Add, C1, C2,
> OverflowingBinaryOperator::NoSignedWrap);
> }
>
> -Constant* ConstantExpr::getNUWAdd(Constant* C1, Constant* C2) {
> +Constant *ConstantExpr::getNUWAdd(Constant *C1, Constant *C2) {
> return getTy(C1->getType(), Instruction::Add, C1, C2,
> OverflowingBinaryOperator::NoUnsignedWrap);
> }
>
> -Constant* ConstantExpr::getNSWSub(Constant* C1, Constant* C2) {
> +Constant *ConstantExpr::getNSWSub(Constant *C1, Constant *C2) {
> return getTy(C1->getType(), Instruction::Sub, C1, C2,
> OverflowingBinaryOperator::NoSignedWrap);
> }
>
> -Constant* ConstantExpr::getNUWSub(Constant* C1, Constant* C2) {
> +Constant *ConstantExpr::getNUWSub(Constant *C1, Constant *C2) {
> return getTy(C1->getType(), Instruction::Sub, C1, C2,
> OverflowingBinaryOperator::NoUnsignedWrap);
> }
>
> -Constant* ConstantExpr::getNSWMul(Constant* C1, Constant* C2) {
> +Constant *ConstantExpr::getNSWMul(Constant *C1, Constant *C2) {
> return getTy(C1->getType(), Instruction::Mul, C1, C2,
> OverflowingBinaryOperator::NoSignedWrap);
> }
>
> -Constant* ConstantExpr::getNUWMul(Constant* C1, Constant* C2) {
> +Constant *ConstantExpr::getNUWMul(Constant *C1, Constant *C2) {
> return getTy(C1->getType(), Instruction::Mul, C1, C2,
> OverflowingBinaryOperator::NoUnsignedWrap);
> }
>
> -Constant* ConstantExpr::getExactSDiv(Constant* C1, Constant* C2) {
> +Constant *ConstantExpr::getNSWShl(Constant *C1, Constant *C2) {
> + return getTy(C1->getType(), Instruction::Shl, C1, C2,
> + OverflowingBinaryOperator::NoSignedWrap);
> +}
> +
> +Constant *ConstantExpr::getNUWShl(Constant *C1, Constant *C2) {
> + return getTy(C1->getType(), Instruction::Shl, C1, C2,
> + OverflowingBinaryOperator::NoUnsignedWrap);
> +}
> +
> +Constant *ConstantExpr::getExactSDiv(Constant *C1, Constant *C2) {
> return getTy(C1->getType(), Instruction::SDiv, C1, C2,
> PossiblyExactOperator::IsExact);
> }
>
> -Constant* ConstantExpr::getExactUDiv(Constant* C1, Constant* C2) {
> +Constant *ConstantExpr::getExactUDiv(Constant *C1, Constant *C2) {
> return getTy(C1->getType(), Instruction::UDiv, C1, C2,
> PossiblyExactOperator::IsExact);
> }
>
> +Constant *ConstantExpr::getExactAShr(Constant *C1, Constant *C2) {
> + return getTy(C1->getType(), Instruction::AShr, C1, C2,
> + PossiblyExactOperator::IsExact);
> +}
> +
> +Constant *ConstantExpr::getExactLShr(Constant *C1, Constant *C2) {
> + return getTy(C1->getType(), Instruction::LShr, C1, C2,
> + PossiblyExactOperator::IsExact);
> +}
> +
> +
> // Utility function for determining if a ConstantExpr is a CastOp or not. This
> // can't be inline because we don't want to #include Instruction.h into
> // Constant.h
> @@ -816,7 +837,7 @@
> /// operands replaced with the specified values. The specified operands must
> /// match count and type with the existing ones.
> Constant *ConstantExpr::
> -getWithOperands(Constant* const *Ops, unsigned NumOps) const {
> +getWithOperands(Constant *const *Ops, unsigned NumOps) const {
> assert(NumOps == getNumOperands()&& "Operand count mismatch!");
> bool AnyChange = false;
> for (unsigned i = 0; i != NumOps; ++i) {
> @@ -1486,7 +1507,7 @@
> return getTy(C1->getType(), Opcode, C1, C2, Flags);
> }
>
> -Constant* ConstantExpr::getSizeOf(const Type* Ty) {
> +Constant *ConstantExpr::getSizeOf(const Type* Ty) {
> // sizeof is implemented as: (i64) gep (Ty*)null, 1
> // Note that a non-inbounds gep is used, as null isn't within any object.
> Constant *GEPIdx = ConstantInt::get(Type::getInt32Ty(Ty->getContext()), 1);
> @@ -1496,7 +1517,7 @@
> Type::getInt64Ty(Ty->getContext()));
> }
>
> -Constant* ConstantExpr::getAlignOf(const Type* Ty) {
> +Constant *ConstantExpr::getAlignOf(const Type* Ty) {
> // alignof is implemented as: (i64) gep ({i1,Ty}*)null, 0, 1
> // Note that a non-inbounds gep is used, as null isn't within any object.
> const Type *AligningTy = StructType::get(Ty->getContext(),
> @@ -1510,12 +1531,12 @@
> Type::getInt64Ty(Ty->getContext()));
> }
>
> -Constant* ConstantExpr::getOffsetOf(const StructType* STy, unsigned FieldNo) {
> +Constant *ConstantExpr::getOffsetOf(const StructType* STy, unsigned FieldNo) {
> return getOffsetOf(STy, ConstantInt::get(Type::getInt32Ty(STy->getContext()),
> FieldNo));
> }
>
> -Constant* ConstantExpr::getOffsetOf(const Type* Ty, Constant *FieldNo) {
> +Constant *ConstantExpr::getOffsetOf(const Type* Ty, Constant *FieldNo) {
> // offsetof is implemented as: (i64) gep (Ty*)null, 0, FieldNo
> // Note that a non-inbounds gep is used, as null isn't within any object.
> Constant *GEPIdx[] = {
> @@ -1823,7 +1844,7 @@
> return getExtractValueTy(ReqTy, Agg, IdxList, NumIdx);
> }
>
> -Constant* ConstantExpr::getNeg(Constant* C) {
> +Constant *ConstantExpr::getNeg(Constant *C) {
> assert(C->getType()->isIntOrIntVectorTy()&&
> "Cannot NEG a nonintegral value!");
> return get(Instruction::Sub,
> @@ -1831,7 +1852,7 @@
> C);
> }
>
> -Constant* ConstantExpr::getFNeg(Constant* C) {
> +Constant *ConstantExpr::getFNeg(Constant *C) {
> assert(C->getType()->isFPOrFPVectorTy()&&
> "Cannot FNEG a non-floating-point value!");
> return get(Instruction::FSub,
> @@ -1839,81 +1860,81 @@
> C);
> }
>
> -Constant* ConstantExpr::getNot(Constant* C) {
> +Constant *ConstantExpr::getNot(Constant *C) {
> assert(C->getType()->isIntOrIntVectorTy()&&
> "Cannot NOT a nonintegral value!");
> return get(Instruction::Xor, C, Constant::getAllOnesValue(C->getType()));
> }
>
> -Constant* ConstantExpr::getAdd(Constant* C1, Constant* C2) {
> +Constant *ConstantExpr::getAdd(Constant *C1, Constant *C2) {
> return get(Instruction::Add, C1, C2);
> }
>
> -Constant* ConstantExpr::getFAdd(Constant* C1, Constant* C2) {
> +Constant *ConstantExpr::getFAdd(Constant *C1, Constant *C2) {
> return get(Instruction::FAdd, C1, C2);
> }
>
> -Constant* ConstantExpr::getSub(Constant* C1, Constant* C2) {
> +Constant *ConstantExpr::getSub(Constant *C1, Constant *C2) {
> return get(Instruction::Sub, C1, C2);
> }
>
> -Constant* ConstantExpr::getFSub(Constant* C1, Constant* C2) {
> +Constant *ConstantExpr::getFSub(Constant *C1, Constant *C2) {
> return get(Instruction::FSub, C1, C2);
> }
>
> -Constant* ConstantExpr::getMul(Constant* C1, Constant* C2) {
> +Constant *ConstantExpr::getMul(Constant *C1, Constant *C2) {
> return get(Instruction::Mul, C1, C2);
> }
>
> -Constant* ConstantExpr::getFMul(Constant* C1, Constant* C2) {
> +Constant *ConstantExpr::getFMul(Constant *C1, Constant *C2) {
> return get(Instruction::FMul, C1, C2);
> }
>
> -Constant* ConstantExpr::getUDiv(Constant* C1, Constant* C2) {
> +Constant *ConstantExpr::getUDiv(Constant *C1, Constant *C2) {
> return get(Instruction::UDiv, C1, C2);
> }
>
> -Constant* ConstantExpr::getSDiv(Constant* C1, Constant* C2) {
> +Constant *ConstantExpr::getSDiv(Constant *C1, Constant *C2) {
> return get(Instruction::SDiv, C1, C2);
> }
>
> -Constant* ConstantExpr::getFDiv(Constant* C1, Constant* C2) {
> +Constant *ConstantExpr::getFDiv(Constant *C1, Constant *C2) {
> return get(Instruction::FDiv, C1, C2);
> }
>
> -Constant* ConstantExpr::getURem(Constant* C1, Constant* C2) {
> +Constant *ConstantExpr::getURem(Constant *C1, Constant *C2) {
> return get(Instruction::URem, C1, C2);
> }
>
> -Constant* ConstantExpr::getSRem(Constant* C1, Constant* C2) {
> +Constant *ConstantExpr::getSRem(Constant *C1, Constant *C2) {
> return get(Instruction::SRem, C1, C2);
> }
>
> -Constant* ConstantExpr::getFRem(Constant* C1, Constant* C2) {
> +Constant *ConstantExpr::getFRem(Constant *C1, Constant *C2) {
> return get(Instruction::FRem, C1, C2);
> }
>
> -Constant* ConstantExpr::getAnd(Constant* C1, Constant* C2) {
> +Constant *ConstantExpr::getAnd(Constant *C1, Constant *C2) {
> return get(Instruction::And, C1, C2);
> }
>
> -Constant* ConstantExpr::getOr(Constant* C1, Constant* C2) {
> +Constant *ConstantExpr::getOr(Constant *C1, Constant *C2) {
> return get(Instruction::Or, C1, C2);
> }
>
> -Constant* ConstantExpr::getXor(Constant* C1, Constant* C2) {
> +Constant *ConstantExpr::getXor(Constant *C1, Constant *C2) {
> return get(Instruction::Xor, C1, C2);
> }
>
> -Constant* ConstantExpr::getShl(Constant* C1, Constant* C2) {
> +Constant *ConstantExpr::getShl(Constant *C1, Constant *C2) {
> return get(Instruction::Shl, C1, C2);
> }
>
> -Constant* ConstantExpr::getLShr(Constant* C1, Constant* C2) {
> +Constant *ConstantExpr::getLShr(Constant *C1, Constant *C2) {
> return get(Instruction::LShr, C1, C2);
> }
>
> -Constant* ConstantExpr::getAShr(Constant* C1, Constant* C2) {
> +Constant *ConstantExpr::getAShr(Constant *C1, Constant *C2) {
> return get(Instruction::AShr, C1, C2);
> }
>
>
> Modified: llvm/trunk/test/Assembler/2003-05-21-MalformedShiftCrash.ll
> URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/test/Assembler/2003-05-21-MalformedShiftCrash.ll?rev=125006&r1=125005&r2=125006&view=diff
> ==============================================================================
> --- llvm/trunk/test/Assembler/2003-05-21-MalformedShiftCrash.ll (original)
> +++ llvm/trunk/test/Assembler/2003-05-21-MalformedShiftCrash.ll Mon Feb 7 10:40:21 2011
> @@ -1,4 +1,4 @@
> ; Found by inspection of the code
> -; RUN: not llvm-as< %s> /dev/null |& grep {constexpr requires integer or integer vector operands}
> +; RUN: not llvm-as< %s> /dev/null |& grep {constexpr requires integer operands}
>
> global i32 ashr (float 1.0, float 2.0)
>
> Modified: llvm/trunk/test/Assembler/flags.ll
> URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/test/Assembler/flags.ll?rev=125006&r1=125005&r2=125006&view=diff
> ==============================================================================
> --- llvm/trunk/test/Assembler/flags.ll (original)
> +++ llvm/trunk/test/Assembler/flags.ll Mon Feb 7 10:40:21 2011
> @@ -92,6 +92,12 @@
> ret i64 %z
> }
>
> +define i64 @shl_both(i64 %x, i64 %y) {
> +; CHECK: %z = shl nuw nsw i64 %x, %y
> + %z = shl nuw nsw i64 %x, %y
> + ret i64 %z
> +}
> +
> define i64 @sdiv_exact(i64 %x, i64 %y) {
> ; CHECK: %z = sdiv exact i64 %x, %y
> %z = sdiv exact i64 %x, %y
> @@ -116,6 +122,29 @@
> ret i64 %z
> }
>
> +define i64 @ashr_plain(i64 %x, i64 %y) {
> +; CHECK: %z = ashr i64 %x, %y
> + %z = ashr i64 %x, %y
> + ret i64 %z
> +}
> +
> +define i64 @ashr_exact(i64 %x, i64 %y) {
> +; CHECK: %z = ashr exact i64 %x, %y
> + %z = ashr exact i64 %x, %y
> + ret i64 %z
> +}
> +
> +define i64 @lshr_plain(i64 %x, i64 %y) {
> +; CHECK: %z = lshr i64 %x, %y
> + %z = lshr i64 %x, %y
> + ret i64 %z
> +}
> +
> +define i64 @lshr_exact(i64 %x, i64 %y) {
> +; CHECK: %z = lshr exact i64 %x, %y
> + %z = lshr exact i64 %x, %y
> + ret i64 %z
> +}
>
> define i64* @gep_nw(i64* %p, i64 %x) {
> ; CHECK: %z = getelementptr inbounds i64* %p, i64 %x
> @@ -154,6 +183,16 @@
> ret i64 udiv exact (i64 ptrtoint (i64* @addr to i64), i64 91)
> }
>
> +define i64 @ashr_exact_ce() {
> +; CHECK: ret i64 ashr exact (i64 ptrtoint (i64* @addr to i64), i64 9)
> + ret i64 ashr exact (i64 ptrtoint (i64* @addr to i64), i64 9)
> +}
> +
> +define i64 @lshr_exact_ce() {
> +; CHECK: ret i64 lshr exact (i64 ptrtoint (i64* @addr to i64), i64 9)
> + ret i64 lshr exact (i64 ptrtoint (i64* @addr to i64), i64 9)
> +}
> +
> define i64* @gep_nw_ce() {
> ; CHECK: ret i64* getelementptr inbounds (i64* @addr, i64 171)
> ret i64* getelementptr inbounds (i64* @addr, i64 171)
> @@ -214,6 +253,12 @@
> ret i64 mul nsw (i64 ptrtoint (i64* @addr to i64), i64 91)
> }
>
> +define i64 @shl_signed_ce() {
> +; CHECK: ret i64 shl nsw (i64 ptrtoint (i64* @addr to i64), i64 17)
> + ret i64 shl nsw (i64 ptrtoint (i64* @addr to i64), i64 17)
> +}
> +
> +
> define i64 @add_unsigned_ce() {
> ; 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)
>
>
> _______________________________________________
> llvm-commits mailing list
> llvm-commits at cs.uiuc.edu
> http://lists.cs.uiuc.edu/mailman/listinfo/llvm-commits
>
More information about the llvm-commits
mailing list