Revert "Include optional subclass flags, such as inbounds, nsw, etc., ...", this
authorDaniel Dunbar <daniel@zuster.org>
Sun, 6 Sep 2009 00:11:24 +0000 (00:11 +0000)
committerDaniel Dunbar <daniel@zuster.org>
Sun, 6 Sep 2009 00:11:24 +0000 (00:11 +0000)
breaks MiniSAT on x86_64.

git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@81098 91177308-0d34-0410-b5e6-96231b3b80d8

16 files changed:
include/llvm/Constants.h
include/llvm/InstrTypes.h
include/llvm/Instructions.h
include/llvm/Operator.h
include/llvm/Value.h
lib/AsmParser/LLParser.cpp
lib/Bitcode/Reader/BitcodeReader.cpp
lib/Transforms/Scalar/InstructionCombining.cpp
lib/VMCore/Constants.cpp
lib/VMCore/ConstantsContext.h
lib/VMCore/Instructions.cpp
test/Assembler/flags-plain.ll [new file with mode: 0644]
test/Assembler/flags-reversed.ll [new file with mode: 0644]
test/Assembler/flags-signed.ll [new file with mode: 0644]
test/Assembler/flags-unsigned.ll [new file with mode: 0644]
test/Assembler/flags.ll

index e79ca543ab37594969ac3a9b50d81156dd63cb91..da6fe96a7726e48f28f126e4993e0e417729055c 100644 (file)
@@ -571,17 +571,13 @@ protected:
   // These private methods are used by the type resolution code to create
   // ConstantExprs in intermediate forms.
   static Constant *getTy(const Type *Ty, unsigned Opcode,
-                         Constant *C1, Constant *C2,
-                         unsigned Flags = 0);
+                         Constant *C1, Constant *C2);
   static Constant *getCompareTy(unsigned short pred, Constant *C1,
                                 Constant *C2);
   static Constant *getSelectTy(const Type *Ty,
                                Constant *C1, Constant *C2, Constant *C3);
   static Constant *getGetElementPtrTy(const Type *Ty, Constant *C,
                                       Value* const *Idxs, unsigned NumIdxs);
-  static Constant *getInBoundsGetElementPtrTy(const Type *Ty, Constant *C,
-                                              Value* const *Idxs,
-                                              unsigned NumIdxs);
   static Constant *getExtractElementTy(const Type *Ty, Constant *Val,
                                        Constant *Idx);
   static Constant *getInsertElementTy(const Type *Ty, Constant *Val,
@@ -722,8 +718,7 @@ public:
   /// get - Return a binary or shift operator constant expression,
   /// folding if possible.
   ///
-  static Constant *get(unsigned Opcode, Constant *C1, Constant *C2,
-                       unsigned Flags = 0);
+  static Constant *get(unsigned Opcode, Constant *C1, Constant *C2);
 
   /// @brief Return an ICmp or FCmp comparison operator constant expression.
   static Constant *getCompare(unsigned short pred, Constant *C1, Constant *C2);
index 032a1e7f7a19ff7215a62998ed175d4e0aedff08..35d7534e5a3418cad89a726f19f39f0addc44202 100644 (file)
@@ -200,19 +200,19 @@ public:
   static BinaryOperator *CreateNSWAdd(Value *V1, Value *V2,
                                       const Twine &Name = "") {
     BinaryOperator *BO = CreateAdd(V1, V2, Name);
-    BO->setHasNoSignedWrap(true);
+    cast<AddOperator>(BO)->setHasNoSignedWrap(true);
     return BO;
   }
   static BinaryOperator *CreateNSWAdd(Value *V1, Value *V2,
                                       const Twine &Name, BasicBlock *BB) {
     BinaryOperator *BO = CreateAdd(V1, V2, Name, BB);
-    BO->setHasNoSignedWrap(true);
+    cast<AddOperator>(BO)->setHasNoSignedWrap(true);
     return BO;
   }
   static BinaryOperator *CreateNSWAdd(Value *V1, Value *V2,
                                       const Twine &Name, Instruction *I) {
     BinaryOperator *BO = CreateAdd(V1, V2, Name, I);
-    BO->setHasNoSignedWrap(true);
+    cast<AddOperator>(BO)->setHasNoSignedWrap(true);
     return BO;
   }
 
@@ -221,19 +221,19 @@ public:
   static BinaryOperator *CreateExactSDiv(Value *V1, Value *V2,
                                          const Twine &Name = "") {
     BinaryOperator *BO = CreateSDiv(V1, V2, Name);
-    BO->setIsExact(true);
+    cast<SDivOperator>(BO)->setIsExact(true);
     return BO;
   }
   static BinaryOperator *CreateExactSDiv(Value *V1, Value *V2,
                                          const Twine &Name, BasicBlock *BB) {
     BinaryOperator *BO = CreateSDiv(V1, V2, Name, BB);
-    BO->setIsExact(true);
+    cast<SDivOperator>(BO)->setIsExact(true);
     return BO;
   }
   static BinaryOperator *CreateExactSDiv(Value *V1, Value *V2,
                                          const Twine &Name, Instruction *I) {
     BinaryOperator *BO = CreateSDiv(V1, V2, Name, I);
-    BO->setIsExact(true);
+    cast<SDivOperator>(BO)->setIsExact(true);
     return BO;
   }
 
@@ -287,21 +287,6 @@ public:
   ///
   bool swapOperands();
 
-  /// setHasNoUnsignedWrap - Set or clear the nsw flag on this instruction,
-  /// which must be an operator which supports this flag. See LangRef.html
-  /// for the meaning of this flag.
-  void setHasNoUnsignedWrap(bool);
-
-  /// setHasNoSignedWrap - Set or clear the nsw flag on this instruction,
-  /// which must be an operator which supports this flag. See LangRef.html
-  /// for the meaning of this flag.
-  void setHasNoSignedWrap(bool);
-
-  /// setIsExact - Set or clear the exact flag on this instruction,
-  /// which must be an operator which supports this flag. See LangRef.html
-  /// for the meaning of this flag.
-  void setIsExact(bool);
-
   // Methods for support type inquiry through isa, cast, and dyn_cast:
   static inline bool classof(const BinaryOperator *) { return true; }
   static inline bool classof(const Instruction *I) {
index 57cff1722131414af6fe4f9774eeb030242e0c8b..71f4738528975e3955a533837eb62b040625e643 100644 (file)
@@ -496,7 +496,7 @@ public:
                                            Instruction *InsertBefore = 0) {
     GetElementPtrInst *GEP = Create(Ptr, IdxBegin, IdxEnd,
                                     NameStr, InsertBefore);
-    GEP->setIsInBounds(true);
+    cast<GEPOperator>(GEP)->setIsInBounds(true);
     return GEP;
   }
   template<typename InputIterator>
@@ -507,21 +507,21 @@ public:
                                            BasicBlock *InsertAtEnd) {
     GetElementPtrInst *GEP = Create(Ptr, IdxBegin, IdxEnd,
                                     NameStr, InsertAtEnd);
-    GEP->setIsInBounds(true);
+    cast<GEPOperator>(GEP)->setIsInBounds(true);
     return GEP;
   }
   static GetElementPtrInst *CreateInBounds(Value *Ptr, Value *Idx,
                                            const Twine &NameStr = "",
                                            Instruction *InsertBefore = 0) {
     GetElementPtrInst *GEP = Create(Ptr, Idx, NameStr, InsertBefore);
-    GEP->setIsInBounds(true);
+    cast<GEPOperator>(GEP)->setIsInBounds(true);
     return GEP;
   }
   static GetElementPtrInst *CreateInBounds(Value *Ptr, Value *Idx,
                                            const Twine &NameStr,
                                            BasicBlock *InsertAtEnd) {
     GetElementPtrInst *GEP = Create(Ptr, Idx, NameStr, InsertAtEnd);
-    GEP->setIsInBounds(true);
+    cast<GEPOperator>(GEP)->setIsInBounds(true);
     return GEP;
   }
 
@@ -602,10 +602,6 @@ public:
   /// a constant offset between them.
   bool hasAllConstantIndices() const;
 
-  /// setIsInBounds - Set or clear the inbounds flag on this GEP instruction.
-  /// See LangRef.html for the meaning of inbounds on a getelementptr.
-  void setIsInBounds(bool);
-
   // Methods for support type inquiry through isa, cast, and dyn_cast:
   static inline bool classof(const GetElementPtrInst *) { return true; }
   static inline bool classof(const Instruction *I) {
index 06eb243418ec82a3f06b9f0656a14474d08a218d..48ac09d54fc401a2a5e1aa36411c1305aea00ec6 100644 (file)
@@ -21,8 +21,6 @@
 namespace llvm {
 
 class GetElementPtrInst;
-class BinaryOperator;
-class ConstantExpr;
 
 /// Operator - This is a utility class that provides an abstraction for the
 /// common functionality between Instructions and ConstantExprs.
@@ -69,37 +67,24 @@ public:
 /// despite that operator having the potential for overflow.
 ///
 class OverflowingBinaryOperator : public Operator {
-public:
-  enum {
-    NoUnsignedWrap = (1 << 0),
-    NoSignedWrap   = (1 << 1)
-  };
-
-private:
   ~OverflowingBinaryOperator(); // do not implement
-
-  friend class BinaryOperator;
-  friend class ConstantExpr;
-  void setHasNoUnsignedWrap(bool B) {
-    SubclassOptionalData =
-      (SubclassOptionalData & ~NoUnsignedWrap) | (B * NoUnsignedWrap);
-  }
-  void setHasNoSignedWrap(bool B) {
-    SubclassOptionalData =
-      (SubclassOptionalData & ~NoSignedWrap) | (B * NoSignedWrap);
-  }
-
 public:
   /// hasNoUnsignedWrap - Test whether this operation is known to never
   /// undergo unsigned overflow, aka the nuw property.
   bool hasNoUnsignedWrap() const {
-    return SubclassOptionalData & NoUnsignedWrap;
+    return SubclassOptionalData & (1 << 0);
+  }
+  void setHasNoUnsignedWrap(bool B) {
+    SubclassOptionalData = (SubclassOptionalData & ~(1 << 0)) | (B << 0);
   }
 
   /// hasNoSignedWrap - Test whether this operation is known to never
   /// undergo signed overflow, aka the nsw property.
   bool hasNoSignedWrap() const {
-    return SubclassOptionalData & NoSignedWrap;
+    return SubclassOptionalData & (1 << 1);
+  }
+  void setHasNoSignedWrap(bool B) {
+    SubclassOptionalData = (SubclassOptionalData & ~(1 << 1)) | (B << 1);
   }
 
   static inline bool classof(const OverflowingBinaryOperator *) { return true; }
@@ -176,25 +161,15 @@ public:
 /// SDivOperator - An Operator with opcode Instruction::SDiv.
 ///
 class SDivOperator : public Operator {
-public:
-  enum {
-    IsExact = (1 << 0)
-  };
-
-private:
   ~SDivOperator(); // do not implement
-
-  friend class BinaryOperator;
-  friend class ConstantExpr;
-  void setIsExact(bool B) {
-    SubclassOptionalData = (SubclassOptionalData & ~IsExact) | (B * IsExact);
-  }
-
 public:
   /// isExact - Test whether this division is known to be exact, with
   /// zero remainder.
   bool isExact() const {
-    return SubclassOptionalData & IsExact;
+    return SubclassOptionalData & (1 << 0);
+  }
+  void setIsExact(bool B) {
+    SubclassOptionalData = (SubclassOptionalData & ~(1 << 0)) | (B << 0);
   }
 
   // Methods for support type inquiry through isa, cast, and dyn_cast:
@@ -212,24 +187,15 @@ public:
 };
 
 class GEPOperator : public Operator {
-  enum {
-    IsInBounds = (1 << 0)
-  };
-
   ~GEPOperator(); // do not implement
-
-  friend class GetElementPtrInst;
-  friend class ConstantExpr;
-  void setIsInBounds(bool B) {
-    SubclassOptionalData =
-      (SubclassOptionalData & ~IsInBounds) | (B * IsInBounds);
-  }
-
 public:
   /// isInBounds - Test whether this is an inbounds GEP, as defined
   /// by LangRef.html.
   bool isInBounds() const {
-    return SubclassOptionalData & IsInBounds;
+    return SubclassOptionalData & (1 << 0);
+  }
+  void setIsInBounds(bool B) {
+    SubclassOptionalData = (SubclassOptionalData & ~(1 << 0)) | (B << 0);
   }
 
   inline op_iterator       idx_begin()       { return op_begin()+1; }
index 415b8fbb2ba28eb547c2ee85b8fece2a5d9ccad6..fdc3aeb9567a97f4ca6b6fa414725ee8c7953172 100644 (file)
@@ -146,6 +146,12 @@ public:
   // Only use when in type resolution situations!
   void uncheckedReplaceAllUsesWith(Value *V);
 
+  /// clearOptionalData - Clear any optional optimization data from this Value.
+  /// Transformation passes must call this method whenever changing the IR
+  /// in a way that would affect the values produced by this Value, unless
+  /// it takes special care to ensure correctness in some other way.
+  void clearOptionalData() { SubclassOptionalData = 0; }
+
   //----------------------------------------------------------------------
   // Methods for handling the chain of uses of this Value.
   //
@@ -234,13 +240,6 @@ public:
     return SubclassID;
   }
 
-  /// getRawSubclassOptionalData - Return the raw optional flags value
-  /// contained in this value. This should only be used when testing two
-  /// Values for equivalence.
-  unsigned getRawSubclassOptionalData() const {
-    return SubclassOptionalData;
-  }
-
   /// hasSameSubclassOptionalData - Test whether the optional flags contained
   /// in this value are equal to the optional flags in the given value.
   bool hasSameSubclassOptionalData(const Value *V) const {
index b7b95d7ecf059a39b63f5030f27ed7b70e0b6bf4..3ef4aaf649809794b8d8f43697f572c8bd4d0c93 100644 (file)
@@ -2095,11 +2095,13 @@ bool LLParser::ParseValID(ValID &ID) {
     if (!Val0->getType()->isIntOrIntVector() &&
         !Val0->getType()->isFPOrFPVector())
       return Error(ID.Loc,"constexpr requires integer, fp, or vector operands");
-    unsigned Flags = 0;
-    if (NUW)   Flags |= OverflowingBinaryOperator::NoUnsignedWrap;
-    if (NSW)   Flags |= OverflowingBinaryOperator::NoSignedWrap;
-    if (Exact) Flags |= SDivOperator::IsExact;
-    Constant *C = ConstantExpr::get(Opc, Val0, Val1, Flags);
+    Constant *C = ConstantExpr::get(Opc, Val0, Val1);
+    if (NUW)
+      cast<OverflowingBinaryOperator>(C)->setHasNoUnsignedWrap(true);
+    if (NSW)
+      cast<OverflowingBinaryOperator>(C)->setHasNoSignedWrap(true);
+    if (Exact)
+      cast<SDivOperator>(C)->setIsExact(true);
     ID.ConstantVal = C;
     ID.Kind = ValID::t_Constant;
     return false;
@@ -2155,12 +2157,10 @@ bool LLParser::ParseValID(ValID &ID) {
                                              (Value**)(Elts.data() + 1),
                                              Elts.size() - 1))
         return Error(ID.Loc, "invalid indices for getelementptr");
-      ID.ConstantVal = InBounds ?
-        ConstantExpr::getInBoundsGetElementPtr(Elts[0],
-                                               Elts.data() + 1,
-                                               Elts.size() - 1) :
-        ConstantExpr::getGetElementPtr(Elts[0],
-                                       Elts.data() + 1, Elts.size() - 1);
+      ID.ConstantVal = ConstantExpr::getGetElementPtr(Elts[0],
+                                              Elts.data() + 1, Elts.size() - 1);
+      if (InBounds)
+        cast<GEPOperator>(ID.ConstantVal)->setIsInBounds(true);
     } else if (Opc == Instruction::Select) {
       if (Elts.size() != 3)
         return Error(ID.Loc, "expected three operands to select");
@@ -2681,9 +2681,9 @@ bool LLParser::ParseInstruction(Instruction *&Inst, BasicBlock *BB,
           return Error(ModifierLoc, "nsw only applies to integer operations");
       }
       if (NUW)
-        cast<BinaryOperator>(Inst)->setHasNoUnsignedWrap(true);
+        cast<OverflowingBinaryOperator>(Inst)->setHasNoUnsignedWrap(true);
       if (NSW)
-        cast<BinaryOperator>(Inst)->setHasNoSignedWrap(true);
+        cast<OverflowingBinaryOperator>(Inst)->setHasNoSignedWrap(true);
     }
     return Result;
   }
@@ -2698,7 +2698,7 @@ bool LLParser::ParseInstruction(Instruction *&Inst, BasicBlock *BB,
     bool Result = ParseArithmetic(Inst, PFS, KeywordVal, 1);
     if (!Result)
       if (Exact)
-        cast<BinaryOperator>(Inst)->setIsExact(true);
+        cast<SDivOperator>(Inst)->setIsExact(true);
     return Result;
   }
 
@@ -3501,7 +3501,7 @@ bool LLParser::ParseGetElementPtr(Instruction *&Inst, PerFunctionState &PFS) {
     return Error(Loc, "invalid getelementptr indices");
   Inst = GetElementPtrInst::Create(Ptr, Indices.begin(), Indices.end());
   if (InBounds)
-    cast<GetElementPtrInst>(Inst)->setIsInBounds(true);
+    cast<GEPOperator>(Inst)->setIsInBounds(true);
   return false;
 }
 
index 05f7b52292dacec0dd91b796f808e9002456c485..9ed75ab1313f7e0b7787c143b2edd38c4446b03b 100644 (file)
@@ -883,6 +883,19 @@ bool BitcodeReader::ResolveGlobalAndAliasInits() {
   return false;
 }
 
+static void SetOptimizationFlags(Value *V, uint64_t Flags) {
+  if (OverflowingBinaryOperator *OBO =
+        dyn_cast<OverflowingBinaryOperator>(V)) {
+    if (Flags & (1 << bitc::OBO_NO_SIGNED_WRAP))
+      OBO->setHasNoSignedWrap(true);
+    if (Flags & (1 << bitc::OBO_NO_UNSIGNED_WRAP))
+      OBO->setHasNoUnsignedWrap(true);
+  } else if (SDivOperator *Div = dyn_cast<SDivOperator>(V)) {
+    if (Flags & (1 << bitc::SDIV_EXACT))
+      Div->setIsExact(true);
+  }
+}
+
 bool BitcodeReader::ParseConstants() {
   if (Stream.EnterSubBlock(bitc::CONSTANTS_BLOCK_ID))
     return Error("Malformed block record");
@@ -1034,22 +1047,10 @@ bool BitcodeReader::ParseConstants() {
       } else {
         Constant *LHS = ValueList.getConstantFwdRef(Record[1], CurTy);
         Constant *RHS = ValueList.getConstantFwdRef(Record[2], CurTy);
-        unsigned Flags = 0;
-        if (Record.size() >= 4) {
-          if (Opc == Instruction::Add ||
-              Opc == Instruction::Sub ||
-              Opc == Instruction::Mul) {
-            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) {
-            if (Record[3] & (1 << bitc::SDIV_EXACT))
-              Flags |= SDivOperator::IsExact;
-          }
-        }
-        V = ConstantExpr::get(Opc, LHS, RHS, Flags);
+        V = ConstantExpr::get(Opc, LHS, RHS);
       }
+      if (Record.size() >= 4)
+        SetOptimizationFlags(V, Record[3]);
       break;
     }  
     case bitc::CST_CODE_CE_CAST: {  // CE_CAST: [opcode, opty, opval]
@@ -1074,12 +1075,10 @@ bool BitcodeReader::ParseConstants() {
         if (!ElTy) return Error("Invalid CE_GEP record");
         Elts.push_back(ValueList.getConstantFwdRef(Record[i+1], ElTy));
       }
+      V = ConstantExpr::getGetElementPtr(Elts[0], &Elts[1], 
+                                               Elts.size()-1);
       if (BitCode == bitc::CST_CODE_CE_INBOUNDS_GEP)
-        V = ConstantExpr::getInBoundsGetElementPtr(Elts[0], &Elts[1],
-                                                   Elts.size()-1);
-      else
-        V = ConstantExpr::getGetElementPtr(Elts[0], &Elts[1],
-                                           Elts.size()-1);
+        cast<GEPOperator>(V)->setIsInBounds(true);
       break;
     }
     case bitc::CST_CODE_CE_SELECT:  // CE_SELECT: [opval#, opval#, opval#]
@@ -1611,19 +1610,8 @@ bool BitcodeReader::ParseFunctionBody(Function *F) {
       int Opc = GetDecodedBinaryOpcode(Record[OpNum++], LHS->getType());
       if (Opc == -1) return Error("Invalid BINOP record");
       I = BinaryOperator::Create((Instruction::BinaryOps)Opc, LHS, RHS);
-      if (OpNum < Record.size()) {
-        if (Opc == Instruction::Add ||
-            Opc == Instruction::Sub ||
-            Opc == Instruction::Mul) {
-          if (Record[3] & (1 << bitc::OBO_NO_SIGNED_WRAP))
-            cast<BinaryOperator>(I)->setHasNoSignedWrap(true);
-          if (Record[3] & (1 << bitc::OBO_NO_UNSIGNED_WRAP))
-            cast<BinaryOperator>(I)->setHasNoUnsignedWrap(true);
-        } else if (Opc == Instruction::SDiv) {
-          if (Record[3] & (1 << bitc::SDIV_EXACT))
-            cast<BinaryOperator>(I)->setIsExact(true);
-        }
-      }
+      if (OpNum < Record.size())
+        SetOptimizationFlags(I, Record[3]);
       break;
     }
     case bitc::FUNC_CODE_INST_CAST: {    // CAST: [opval, opty, destty, castopc]
@@ -1657,7 +1645,7 @@ bool BitcodeReader::ParseFunctionBody(Function *F) {
 
       I = GetElementPtrInst::Create(BasePtr, GEPIdx.begin(), GEPIdx.end());
       if (BitCode == bitc::FUNC_CODE_INST_INBOUNDS_GEP)
-        cast<GetElementPtrInst>(I)->setIsInBounds(true);
+        cast<GEPOperator>(I)->setIsInBounds(true);
       break;
     }
       
index 432b88f911da6bc8f1a6d206b6c5ba9625aa8a20..ce2f4520c6a52f65af72e84abeeab79662b15709 100644 (file)
@@ -8086,11 +8086,11 @@ Instruction *InstCombiner::commonPointerCastTransforms(CastInst &CI) {
           // If we were able to index down into an element, create the GEP
           // and bitcast the result.  This eliminates one bitcast, potentially
           // two.
-          Value *NGEP = cast<GEPOperator>(GEP)->isInBounds() ?
-            Builder->CreateInBoundsGEP(OrigBase,
-                                       NewIndices.begin(), NewIndices.end()) :
-            Builder->CreateGEP(OrigBase, NewIndices.begin(), NewIndices.end());
+          Value *NGEP = Builder->CreateGEP(OrigBase, NewIndices.begin(),
+                                           NewIndices.end());
           NGEP->takeName(GEP);
+          if (isa<Instruction>(NGEP) && cast<GEPOperator>(GEP)->isInBounds())
+            cast<GEPOperator>(NGEP)->setIsInBounds(true);
           
           if (isa<BitCastInst>(CI))
             return new BitCastInst(NGEP, CI.getType());
@@ -8805,8 +8805,11 @@ Instruction *InstCombiner::visitBitCast(BitCastInst &CI) {
     // If we found a path from the src to dest, create the getelementptr now.
     if (SrcElTy == DstElTy) {
       SmallVector<Value*, 8> Idxs(NumZeros+1, ZeroUInt);
-      return GetElementPtrInst::CreateInBounds(Src, Idxs.begin(), Idxs.end(), "",
-                                               ((Instruction*) NULL));
+      Instruction *GEP = GetElementPtrInst::Create(Src,
+                                                   Idxs.begin(), Idxs.end(), "",
+                                                   ((Instruction*) NULL));
+      cast<GEPOperator>(GEP)->setIsInBounds(true);
+      return GEP;
     }
   }
 
@@ -10478,11 +10481,12 @@ Instruction *InstCombiner::FoldPHIArgGEPIntoPHI(PHINode &PN) {
   }
   
   Value *Base = FixedOperands[0];
-  return cast<GEPOperator>(FirstInst)->isInBounds() ?
-    GetElementPtrInst::CreateInBounds(Base, FixedOperands.begin()+1,
-                                      FixedOperands.end()) :
+  GetElementPtrInst *GEP =
     GetElementPtrInst::Create(Base, FixedOperands.begin()+1,
                               FixedOperands.end());
+  if (cast<GEPOperator>(FirstInst)->isInBounds())
+    cast<GEPOperator>(GEP)->setIsInBounds(true);
+  return GEP;
 }
 
 
@@ -10885,13 +10889,14 @@ Instruction *InstCombiner::visitGetElementPtrInst(GetElementPtrInst &GEP) {
       Indices.append(GEP.idx_begin()+1, GEP.idx_end());
     }
 
-    if (!Indices.empty())
-      return (cast<GEPOperator>(&GEP)->isInBounds() &&
-              Src->isInBounds()) ?
-        GetElementPtrInst::CreateInBounds(Src->getOperand(0), Indices.begin(),
-                                          Indices.end(), GEP.getName()) :
+    if (!Indices.empty()) {
+      GetElementPtrInst *NewGEP =
         GetElementPtrInst::Create(Src->getOperand(0), Indices.begin(),
                                   Indices.end(), GEP.getName());
+      if (cast<GEPOperator>(&GEP)->isInBounds() && Src->isInBounds())
+        cast<GEPOperator>(NewGEP)->setIsInBounds(true);
+      return NewGEP;
+    }
   }
   
   // Handle gep(bitcast x) and gep(gep x, 0, 0, 0).
@@ -10921,11 +10926,12 @@ Instruction *InstCombiner::visitGetElementPtrInst(GetElementPtrInst &GEP) {
         if (CATy->getElementType() == XTy->getElementType()) {
           // -> GEP i8* X, ...
           SmallVector<Value*, 8> Indices(GEP.idx_begin()+1, GEP.idx_end());
-          return cast<GEPOperator>(&GEP)->isInBounds() ?
-            GetElementPtrInst::CreateInBounds(X, Indices.begin(), Indices.end(),
-                                              GEP.getName()) :
+          GetElementPtrInst *NewGEP =
             GetElementPtrInst::Create(X, Indices.begin(), Indices.end(),
                                       GEP.getName());
+          if (cast<GEPOperator>(&GEP)->isInBounds())
+            cast<GEPOperator>(NewGEP)->setIsInBounds(true);
+          return NewGEP;
         }
         
         if (const ArrayType *XATy = dyn_cast<ArrayType>(XTy->getElementType())){
@@ -10953,9 +10959,10 @@ Instruction *InstCombiner::visitGetElementPtrInst(GetElementPtrInst &GEP) {
         Value *Idx[2];
         Idx[0] = Constant::getNullValue(Type::getInt32Ty(*Context));
         Idx[1] = GEP.getOperand(1);
-        Value *NewGEP = cast<GEPOperator>(&GEP)->isInBounds() ?
-          Builder->CreateInBoundsGEP(X, Idx, Idx + 2, GEP.getName()) :
+        Value *NewGEP =
           Builder->CreateGEP(X, Idx, Idx + 2, GEP.getName());
+        if (cast<GEPOperator>(&GEP)->isInBounds())
+          cast<GEPOperator>(NewGEP)->setIsInBounds(true);
         // V and GEP are both pointer types --> BitCast
         return new BitCastInst(NewGEP, GEP.getType());
       }
@@ -11012,9 +11019,9 @@ Instruction *InstCombiner::visitGetElementPtrInst(GetElementPtrInst &GEP) {
           Value *Idx[2];
           Idx[0] = Constant::getNullValue(Type::getInt32Ty(*Context));
           Idx[1] = NewIdx;
-          Value *NewGEP = cast<GEPOperator>(&GEP)->isInBounds() ?
-            Builder->CreateInBoundsGEP(X, Idx, Idx + 2, GEP.getName()) :
-            Builder->CreateGEP(X, Idx, Idx + 2, GEP.getName());
+          Value *NewGEP = Builder->CreateGEP(X, Idx, Idx + 2, GEP.getName());
+          if (cast<GEPOperator>(&GEP)->isInBounds())
+            cast<GEPOperator>(NewGEP)->setIsInBounds(true);
           // The NewGEP must be pointer typed, so must the old one -> BitCast
           return new BitCastInst(NewGEP, GEP.getType());
         }
@@ -11062,11 +11069,10 @@ Instruction *InstCombiner::visitGetElementPtrInst(GetElementPtrInst &GEP) {
       const Type *InTy =
         cast<PointerType>(BCI->getOperand(0)->getType())->getElementType();
       if (FindElementAtOffset(InTy, Offset, NewIndices, TD, Context)) {
-        Value *NGEP = cast<GEPOperator>(&GEP)->isInBounds() ?
-          Builder->CreateInBoundsGEP(BCI->getOperand(0), NewIndices.begin(),
-                                     NewIndices.end()) :
-          Builder->CreateGEP(BCI->getOperand(0), NewIndices.begin(),
-                             NewIndices.end());
+        Value *NGEP = Builder->CreateGEP(BCI->getOperand(0), NewIndices.begin(),
+                                         NewIndices.end());
+        if (cast<GEPOperator>(&GEP)->isInBounds())
+          cast<GEPOperator>(NGEP)->setIsInBounds(true);
         
         if (NGEP->getType() == GEP.getType())
           return ReplaceInstUsesWith(GEP, NGEP);
@@ -11109,8 +11115,9 @@ Instruction *InstCombiner::visitAllocationInst(AllocationInst &AI) {
       Value *Idx[2];
       Idx[0] = NullIdx;
       Idx[1] = NullIdx;
-      Value *V = GetElementPtrInst::CreateInBounds(New, Idx, Idx + 2,
-                                                   New->getName()+".sub", It);
+      Value *V = GetElementPtrInst::Create(New, Idx, Idx + 2,
+                                           New->getName()+".sub", It);
+      cast<GEPOperator>(V)->setIsInBounds(true);
 
       // Now make everything use the getelementptr instead of the original
       // allocation.
@@ -11479,9 +11486,11 @@ static Instruction *InstCombineStoreToCast(InstCombiner &IC, StoreInst &SI) {
   
   // SIOp0 is a pointer to aggregate and this is a store to the first field,
   // emit a GEP to index into its first field.
-  if (!NewGEPIndices.empty())
-    CastOp = IC.Builder->CreateInBoundsGEP(CastOp, NewGEPIndices.begin(),
-                                           NewGEPIndices.end());
+  if (!NewGEPIndices.empty()) {
+    CastOp = IC.Builder->CreateGEP(CastOp, NewGEPIndices.begin(),
+                                   NewGEPIndices.end());
+    cast<GEPOperator>(CastOp)->setIsInBounds(true);
+  }
   
   NewCast = IC.Builder->CreateCast(opcode, SIOp0, CastDstTy,
                                    SIOp0->getName()+".c");
@@ -12151,7 +12160,8 @@ Instruction *InstCombiner::visitExtractElementInst(ExtractElementInst &EI) {
                                             PointerType::get(EI.getType(), AS),
                                             I->getOperand(0)->getName());
         Value *GEP =
-          Builder->CreateInBoundsGEP(Ptr, EI.getOperand(1), I->getName()+".gep");
+          Builder->CreateGEP(Ptr, EI.getOperand(1), I->getName()+".gep");
+        cast<GEPOperator>(GEP)->setIsInBounds(true);
         
         LoadInst *Load = Builder->CreateLoad(GEP, "tmp");
 
index a5b4f289688b417473d2c2337c39c694f7372cd4..37efafc9b208902ba9f1624cdf26ff1c54ea3852 100644 (file)
@@ -632,13 +632,21 @@ Constant* ConstantVector::get(Constant* const* Vals, unsigned NumVals) {
 }
 
 Constant* ConstantExpr::getNSWAdd(Constant* C1, Constant* C2) {
-  return getTy(C1->getType(), Instruction::Add, C1, C2,
-               OverflowingBinaryOperator::NoSignedWrap);
+  Constant *C = getAdd(C1, C2);
+  // Set nsw attribute, assuming constant folding didn't eliminate the
+  // Add.
+  if (AddOperator *Add = dyn_cast<AddOperator>(C))
+    Add->setHasNoSignedWrap(true);
+  return C;
 }
 
 Constant* ConstantExpr::getExactSDiv(Constant* C1, Constant* C2) {
-  return getTy(C1->getType(), Instruction::SDiv, C1, C2,
-               SDivOperator::IsExact);
+  Constant *C = getSDiv(C1, C2);
+  // Set exact attribute, assuming constant folding didn't eliminate the
+  // SDiv.
+  if (SDivOperator *SDiv = dyn_cast<SDivOperator>(C))
+    SDiv->setIsExact(true);
+  return C;
 }
 
 // Utility function for determining if a ConstantExpr is a CastOp or not. This
@@ -721,19 +729,15 @@ ConstantExpr::getWithOperandReplaced(unsigned OpNo, Constant *Op) const {
     for (unsigned i = 1, e = getNumOperands(); i != e; ++i)
       Ops[i-1] = getOperand(i);
     if (OpNo == 0)
-      return cast<GEPOperator>(this)->isInBounds() ?
-        ConstantExpr::getInBoundsGetElementPtr(Op, &Ops[0], Ops.size()) :
-        ConstantExpr::getGetElementPtr(Op, &Ops[0], Ops.size());
+      return ConstantExpr::getGetElementPtr(Op, &Ops[0], Ops.size());
     Ops[OpNo-1] = Op;
-    return cast<GEPOperator>(this)->isInBounds() ?
-      ConstantExpr::getInBoundsGetElementPtr(getOperand(0), &Ops[0], Ops.size()) :
-      ConstantExpr::getGetElementPtr(getOperand(0), &Ops[0], Ops.size());
+    return ConstantExpr::getGetElementPtr(getOperand(0), &Ops[0], Ops.size());
   }
   default:
     assert(getNumOperands() == 2 && "Must be binary operator?");
     Op0 = (OpNo == 0) ? Op : getOperand(0);
     Op1 = (OpNo == 1) ? Op : getOperand(1);
-    return ConstantExpr::get(getOpcode(), Op0, Op1, SubclassData);
+    return ConstantExpr::get(getOpcode(), Op0, Op1);
   }
 }
 
@@ -775,15 +779,13 @@ getWithOperands(Constant* const *Ops, unsigned NumOps) const {
   case Instruction::ShuffleVector:
     return ConstantExpr::getShuffleVector(Ops[0], Ops[1], Ops[2]);
   case Instruction::GetElementPtr:
-    return cast<GEPOperator>(this)->isInBounds() ?
-      ConstantExpr::getInBoundsGetElementPtr(Ops[0], &Ops[1], NumOps-1) :
-      ConstantExpr::getGetElementPtr(Ops[0], &Ops[1], NumOps-1);
+    return ConstantExpr::getGetElementPtr(Ops[0], &Ops[1], NumOps-1);
   case Instruction::ICmp:
   case Instruction::FCmp:
     return ConstantExpr::getCompare(getPredicate(), Ops[0], Ops[1]);
   default:
     assert(getNumOperands() == 2 && "Must be binary operator?");
-    return ConstantExpr::get(getOpcode(), Ops[0], Ops[1], SubclassData);
+    return ConstantExpr::get(getOpcode(), Ops[0], Ops[1]);
   }
 }
 
@@ -1029,9 +1031,8 @@ static ExprMapKeyType getValType(ConstantExpr *CE) {
   Operands.reserve(CE->getNumOperands());
   for (unsigned i = 0, e = CE->getNumOperands(); i != e; ++i)
     Operands.push_back(cast<Constant>(CE->getOperand(i)));
-  return ExprMapKeyType(CE->getOpcode(), Operands,
+  return ExprMapKeyType(CE->getOpcode(), Operands, 
       CE->isCompare() ? CE->getPredicate() : 0,
-      CE->getRawSubclassOptionalData(),
       CE->hasIndices() ?
         CE->getIndices() : SmallVector<unsigned, 4>());
 }
@@ -1279,8 +1280,7 @@ Constant *ConstantExpr::getBitCast(Constant *C, const Type *DstTy) {
 }
 
 Constant *ConstantExpr::getTy(const Type *ReqTy, unsigned Opcode,
-                              Constant *C1, Constant *C2,
-                              unsigned Flags) {
+                              Constant *C1, Constant *C2) {
   // Check the operands for consistency first
   assert(Opcode >= Instruction::BinaryOpsBegin &&
          Opcode <  Instruction::BinaryOpsEnd   &&
@@ -1294,7 +1294,7 @@ Constant *ConstantExpr::getTy(const Type *ReqTy, unsigned Opcode,
       return FC;          // Fold a few common cases...
 
   std::vector<Constant*> argVec(1, C1); argVec.push_back(C2);
-  ExprMapKeyType Key(Opcode, argVec, 0, Flags);
+  ExprMapKeyType Key(Opcode, argVec);
   
   LLVMContextImpl *pImpl = ReqTy->getContext().pImpl;
   
@@ -1322,8 +1322,7 @@ Constant *ConstantExpr::getCompareTy(unsigned short predicate,
   }
 }
 
-Constant *ConstantExpr::get(unsigned Opcode, Constant *C1, Constant *C2,
-                            unsigned Flags) {
+Constant *ConstantExpr::get(unsigned Opcode, Constant *C1, Constant *C2) {
   // API compatibility: Adjust integer opcodes to floating-point opcodes.
   if (C1->getType()->isFPOrFPVector()) {
     if (Opcode == Instruction::Add) Opcode = Instruction::FAdd;
@@ -1388,7 +1387,7 @@ Constant *ConstantExpr::get(unsigned Opcode, Constant *C1, Constant *C2,
   }
 #endif
 
-  return getTy(C1->getType(), Opcode, C1, C2, Flags);
+  return getTy(C1->getType(), Opcode, C1, C2);
 }
 
 Constant* ConstantExpr::getSizeOf(const Type* Ty) {
@@ -1482,36 +1481,6 @@ Constant *ConstantExpr::getGetElementPtrTy(const Type *ReqTy, Constant *C,
   return pImpl->ExprConstants.getOrCreate(ReqTy, Key);
 }
 
-Constant *ConstantExpr::getInBoundsGetElementPtrTy(const Type *ReqTy,
-                                                   Constant *C,
-                                                   Value* const *Idxs,
-                                                   unsigned NumIdx) {
-  assert(GetElementPtrInst::getIndexedType(C->getType(), Idxs,
-                                           Idxs+NumIdx) ==
-         cast<PointerType>(ReqTy)->getElementType() &&
-         "GEP indices invalid!");
-
-  if (Constant *FC = ConstantFoldGetElementPtr(
-                              ReqTy->getContext(), C, (Constant**)Idxs, NumIdx))
-    return FC;          // Fold a few common cases...
-
-  assert(isa<PointerType>(C->getType()) &&
-         "Non-pointer type for constant GetElementPtr expression");
-  // Look up the constant in the table first to ensure uniqueness
-  std::vector<Constant*> ArgVec;
-  ArgVec.reserve(NumIdx+1);
-  ArgVec.push_back(C);
-  for (unsigned i = 0; i != NumIdx; ++i)
-    ArgVec.push_back(cast<Constant>(Idxs[i]));
-  const ExprMapKeyType Key(Instruction::GetElementPtr, ArgVec, 0,
-                           GEPOperator::IsInBounds);
-
-  LLVMContextImpl *pImpl = ReqTy->getContext().pImpl;
-
-  // Implicitly locked.
-  return pImpl->ExprConstants.getOrCreate(ReqTy, Key);
-}
-
 Constant *ConstantExpr::getGetElementPtr(Constant *C, Value* const *Idxs,
                                          unsigned NumIdx) {
   // Get the result type of the getelementptr!
@@ -1525,12 +1494,12 @@ Constant *ConstantExpr::getGetElementPtr(Constant *C, Value* const *Idxs,
 Constant *ConstantExpr::getInBoundsGetElementPtr(Constant *C,
                                                  Value* const *Idxs,
                                                  unsigned NumIdx) {
-  // Get the result type of the getelementptr!
-  const Type *Ty = 
-    GetElementPtrInst::getIndexedType(C->getType(), Idxs, Idxs+NumIdx);
-  assert(Ty && "GEP indices invalid!");
-  unsigned As = cast<PointerType>(C->getType())->getAddressSpace();
-  return getInBoundsGetElementPtrTy(PointerType::get(Ty, As), C, Idxs, NumIdx);
+  Constant *Result = getGetElementPtr(C, Idxs, NumIdx);
+  // Set in bounds attribute, assuming constant folding didn't eliminate the
+  // GEP.
+  if (GEPOperator *GEP = dyn_cast<GEPOperator>(Result))
+    GEP->setIsInBounds(true);
+  return Result;
 }
 
 Constant *ConstantExpr::getGetElementPtr(Constant *C, Constant* const *Idxs,
@@ -2135,7 +2104,7 @@ void ConstantExpr::replaceUsesOfWithOnConstant(Value *From, Value *ToV,
     Constant *C2 = getOperand(1);
     if (C1 == From) C1 = To;
     if (C2 == From) C2 = To;
-    Replacement = ConstantExpr::get(getOpcode(), C1, C2, SubclassData);
+    Replacement = ConstantExpr::get(getOpcode(), C1, C2);
   } else {
     llvm_unreachable("Unknown ConstantExpr type!");
     return;
index 16975b3611ebb5f3a5abd1109df55f0e6de5f228..718470aff42389fc520ec76caa8de61285b80767 100644 (file)
@@ -53,12 +53,10 @@ public:
   void *operator new(size_t s) {
     return User::operator new(s, 2);
   }
-  BinaryConstantExpr(unsigned Opcode, Constant *C1, Constant *C2,
-                     unsigned Flags)
+  BinaryConstantExpr(unsigned Opcode, Constant *C1, Constant *C2)
     : ConstantExpr(C1->getType(), Opcode, &Op<0>(), 2) {
     Op<0>() = C1;
     Op<1>() = C2;
-    SubclassOptionalData = Flags;
   }
   /// Transparently provide more efficient getOperand methods.
   DECLARE_TRANSPARENT_OPERAND_ACCESSORS(Value);
@@ -208,12 +206,9 @@ class GetElementPtrConstantExpr : public ConstantExpr {
 public:
   static GetElementPtrConstantExpr *Create(Constant *C,
                                            const std::vector<Constant*>&IdxList,
-                                           const Type *DestTy,
-                                           unsigned Flags) {
-    GetElementPtrConstantExpr *Result =
+                                           const Type *DestTy) {
+    return
       new(IdxList.size() + 1) GetElementPtrConstantExpr(C, IdxList, DestTy);
-    Result->SubclassOptionalData = Flags;
-    return Result;
   }
   /// Transparently provide more efficient getOperand methods.
   DECLARE_TRANSPARENT_OPERAND_ACCESSORS(Value);
@@ -296,32 +291,26 @@ struct ExprMapKeyType {
 
   ExprMapKeyType(unsigned opc,
       const std::vector<Constant*> &ops,
-      unsigned short flags = 0,
-      unsigned short optionalflags = 0,
+      unsigned short pred = 0,
       const IndexList &inds = IndexList())
-        : opcode(opc), subclassoptionaldata(optionalflags), subclassdata(flags),
-        operands(ops), indices(inds) {}
-  uint8_t opcode;
-  uint8_t subclassoptionaldata;
-  uint16_t subclassdata;
+        : opcode(opc), predicate(pred), operands(ops), indices(inds) {}
+  uint16_t opcode;
+  uint16_t predicate;
   std::vector<Constant*> operands;
   IndexList indices;
   bool operator==(const ExprMapKeyType& that) const {
     return this->opcode == that.opcode &&
-           this->subclassdata == that.subclassdata &&
-           this->subclassoptionaldata == that.subclassoptionaldata &&
+           this->predicate == that.predicate &&
            this->operands == that.operands &&
            this->indices == that.indices;
   }
   bool operator<(const ExprMapKeyType & that) const {
-    if (this->opcode != that.opcode) return this->opcode < that.opcode;
-    if (this->operands != that.operands) return this->operands < that.operands;
-    if (this->subclassdata != that.subclassdata)
-      return this->subclassdata < that.subclassdata;
-    if (this->subclassoptionaldata != that.subclassoptionaldata)
-      return this->subclassoptionaldata < that.subclassoptionaldata;
-    if (this->indices != that.indices) return this->indices < that.indices;
-    return false;
+    return this->opcode < that.opcode ||
+      (this->opcode == that.opcode && this->predicate < that.predicate) ||
+      (this->opcode == that.opcode && this->predicate == that.predicate &&
+       this->operands < that.operands) ||
+      (this->opcode == that.opcode && this->predicate == that.predicate &&
+       this->operands == that.operands && this->indices < that.indices);
   }
 
   bool operator!=(const ExprMapKeyType& that) const {
@@ -365,8 +354,7 @@ struct ConstantCreator<ConstantExpr, Type, ExprMapKeyType> {
       return new UnaryConstantExpr(V.opcode, V.operands[0], Ty);
     if ((V.opcode >= Instruction::BinaryOpsBegin &&
          V.opcode < Instruction::BinaryOpsEnd))
-      return new BinaryConstantExpr(V.opcode, V.operands[0], V.operands[1],
-                                    V.subclassoptionaldata);
+      return new BinaryConstantExpr(V.opcode, V.operands[0], V.operands[1]);
     if (V.opcode == Instruction::Select)
       return new SelectConstantExpr(V.operands[0], V.operands[1], 
                                     V.operands[2]);
@@ -385,18 +373,17 @@ struct ConstantCreator<ConstantExpr, Type, ExprMapKeyType> {
       return new ExtractValueConstantExpr(V.operands[0], V.indices, Ty);
     if (V.opcode == Instruction::GetElementPtr) {
       std::vector<Constant*> IdxList(V.operands.begin()+1, V.operands.end());
-      return GetElementPtrConstantExpr::Create(V.operands[0], IdxList, Ty,
-                                               V.subclassoptionaldata);
+      return GetElementPtrConstantExpr::Create(V.operands[0], IdxList, Ty);
     }
 
     // The compare instructions are weird. We have to encode the predicate
     // value and it is combined with the instruction opcode by multiplying
     // the opcode by one hundred. We must decode this to get the predicate.
     if (V.opcode == Instruction::ICmp)
-      return new CompareConstantExpr(Ty, Instruction::ICmp, V.subclassdata,
+      return new CompareConstantExpr(Ty, Instruction::ICmp, V.predicate, 
                                      V.operands[0], V.operands[1]);
     if (V.opcode == Instruction::FCmp) 
-      return new CompareConstantExpr(Ty, Instruction::FCmp, V.subclassdata,
+      return new CompareConstantExpr(Ty, Instruction::FCmp, V.predicate, 
                                      V.operands[0], V.operands[1]);
     llvm_unreachable("Invalid ConstantExpr!");
     return 0;
index 9d8e0477eed943eb853f3212c94e736f2c103e9c..2d4ab557217653e107b91a27571f266d549a59c6 100644 (file)
@@ -1171,9 +1171,6 @@ bool GetElementPtrInst::hasAllConstantIndices() const {
   return true;
 }
 
-void GetElementPtrInst::setIsInBounds(bool B) {
-  cast<GEPOperator>(this)->setIsInBounds(B);
-}
 
 //===----------------------------------------------------------------------===//
 //                           ExtractElementInst Implementation
@@ -1719,18 +1716,6 @@ bool BinaryOperator::swapOperands() {
   return false;
 }
 
-void BinaryOperator::setHasNoUnsignedWrap(bool b) {
-  cast<OverflowingBinaryOperator>(this)->setHasNoUnsignedWrap(b);
-}
-
-void BinaryOperator::setHasNoSignedWrap(bool b) {
-  cast<OverflowingBinaryOperator>(this)->setHasNoSignedWrap(b);
-}
-
-void BinaryOperator::setIsExact(bool b) {
-  cast<SDivOperator>(this)->setIsExact(b);
-}
-
 //===----------------------------------------------------------------------===//
 //                                CastInst Class
 //===----------------------------------------------------------------------===//
diff --git a/test/Assembler/flags-plain.ll b/test/Assembler/flags-plain.ll
new file mode 100644 (file)
index 0000000..bf3d5d8
--- /dev/null
@@ -0,0 +1,28 @@
+; RUN: llvm-as < %s | llvm-dis | FileCheck %s
+
+@addr = external global i64
+
+define i64 @add_plain_ce() {
+; CHECK: ret i64 add (i64 ptrtoint (i64* @addr to i64), i64 91)
+       ret i64 add (i64 ptrtoint (i64* @addr to i64), i64 91)
+}
+
+define i64 @sub_plain_ce() {
+; CHECK: ret i64 sub (i64 ptrtoint (i64* @addr to i64), i64 91)
+       ret i64 sub (i64 ptrtoint (i64* @addr to i64), i64 91)
+}
+
+define i64 @mul_plain_ce() {
+; CHECK: ret i64 mul (i64 ptrtoint (i64* @addr to i64), i64 91)
+       ret i64 mul (i64 ptrtoint (i64* @addr to i64), i64 91)
+}
+
+define i64 @sdiv_plain_ce() {
+; CHECK: ret i64 sdiv (i64 ptrtoint (i64* @addr to i64), i64 91)
+       ret i64 sdiv (i64 ptrtoint (i64* @addr to i64), i64 91)
+}
+
+define i64* @gep_plain_ce() {
+; CHECK: ret i64* getelementptr (i64* @addr, i64 171)
+        ret i64* getelementptr (i64* @addr, i64 171)
+}
diff --git a/test/Assembler/flags-reversed.ll b/test/Assembler/flags-reversed.ll
new file mode 100644 (file)
index 0000000..25fa6a0
--- /dev/null
@@ -0,0 +1,18 @@
+; RUN: llvm-as < %s | llvm-dis | FileCheck %s
+
+@addr = external global i64
+
+define i64 @add_both_reversed_ce() {
+; 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 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 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
new file mode 100644 (file)
index 0000000..9c40813
--- /dev/null
@@ -0,0 +1,18 @@
+; RUN: llvm-as < %s | llvm-dis | FileCheck %s
+
+@addr = external global i64
+
+define i64 @add_signed_ce() {
+; 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 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 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
new file mode 100644 (file)
index 0000000..1ddffca
--- /dev/null
@@ -0,0 +1,18 @@
+; RUN: llvm-as < %s | llvm-dis | FileCheck %s
+
+@addr = external global i64
+
+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)
+}
+
+define i64 @sub_unsigned_ce() {
+; 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 mul nuw (i64 ptrtoint (i64* @addr to i64), i64 91)
+       ret i64 mul nuw (i64 ptrtoint (i64* @addr to i64), i64 91)
+}
index 324190905975865ba3e4c090d524973c1357cf44..981a4e592cef02cf6c2a23f52676cce31c0fb863 100644 (file)
@@ -141,72 +141,4 @@ define i64* @gep_nw_ce() {
         ret i64* getelementptr inbounds (i64* @addr, i64 171)
 }
 
-define i64 @add_plain_ce() {
-; CHECK: ret i64 add (i64 ptrtoint (i64* @addr to i64), i64 91)
-       ret i64 add (i64 ptrtoint (i64* @addr to i64), i64 91)
-}
-
-define i64 @sub_plain_ce() {
-; CHECK: ret i64 sub (i64 ptrtoint (i64* @addr to i64), i64 91)
-       ret i64 sub (i64 ptrtoint (i64* @addr to i64), i64 91)
-}
-
-define i64 @mul_plain_ce() {
-; CHECK: ret i64 mul (i64 ptrtoint (i64* @addr to i64), i64 91)
-       ret i64 mul (i64 ptrtoint (i64* @addr to i64), i64 91)
-}
-
-define i64 @sdiv_plain_ce() {
-; CHECK: ret i64 sdiv (i64 ptrtoint (i64* @addr to i64), i64 91)
-       ret i64 sdiv (i64 ptrtoint (i64* @addr to i64), i64 91)
-}
-
-define i64* @gep_plain_ce() {
-; CHECK: ret i64* getelementptr (i64* @addr, i64 171)
-        ret i64* getelementptr (i64* @addr, i64 171)
-}
-
-define i64 @add_both_reversed_ce() {
-; 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 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 mul nuw nsw (i64 ptrtoint (i64* @addr to i64), i64 91)
-       ret i64 mul nsw nuw (i64 ptrtoint (i64* @addr to i64), i64 91)
-}
-
-define i64 @add_signed_ce() {
-; 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 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 mul nsw (i64 ptrtoint (i64* @addr to i64), i64 91)
-       ret i64 mul nsw (i64 ptrtoint (i64* @addr to i64), i64 91)
-}
-
-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)
-}
-
-define i64 @sub_unsigned_ce() {
-; 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 mul nuw (i64 ptrtoint (i64* @addr to i64), i64 91)
-       ret i64 mul nuw (i64 ptrtoint (i64* @addr to i64), i64 91)
-}