[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