diff --git a/docs/LangRef.html b/docs/LangRef.html index da365ff808a..f7997495e04 100644 --- a/docs/LangRef.html +++ b/docs/LangRef.html @@ -3441,7 +3441,8 @@ Instruction
Syntax:
-  <result> = udiv <ty> <op1>, <op2>   ; yields {ty}:result
+  <result> = udiv <ty> <op1>, <op2>         ; yields {ty}:result
+  <result> = udiv exact <ty> <op1>, <op2>   ; yields {ty}:result
 
Overview:
@@ -3460,6 +3461,11 @@ Instruction

Division by zero leads to undefined behavior.

+

If the exact keyword is present, the result value of the + udiv is a trap value if %op1 is not a + multiple of %op2 (as such, "((a udiv exact b) mul b) == a").

+ +
Example:
   <result> = udiv i32 4, %var          ; yields {i32}:result = 4 / %var
diff --git a/include/llvm/Bitcode/LLVMBitCodes.h b/include/llvm/Bitcode/LLVMBitCodes.h
index d15c3ce93ef..7692bd28720 100644
--- a/include/llvm/Bitcode/LLVMBitCodes.h
+++ b/include/llvm/Bitcode/LLVMBitCodes.h
@@ -199,10 +199,10 @@ namespace bitc {
     OBO_NO_SIGNED_WRAP = 1
   };
 
-  /// SDivOperatorOptionalFlags - Flags for serializing SDivOperator's
-  /// SubclassOptionalData contents.
-  enum SDivOperatorOptionalFlags {
-    SDIV_EXACT = 0
+  /// PossiblyExactOperatorOptionalFlags - Flags for serializing 
+  /// PossiblyExactOperator's SubclassOptionalData contents.
+  enum PossiblyExactOperatorOptionalFlags {
+    PEO_EXACT = 0
   };
 
   // The function body block (FUNCTION_BLOCK_ID) describes function bodies.  It
diff --git a/include/llvm/Constants.h b/include/llvm/Constants.h
index a7653948f13..b782737d31a 100644
--- a/include/llvm/Constants.h
+++ b/include/llvm/Constants.h
@@ -725,6 +725,7 @@ public:
   static Constant *getNSWMul(Constant *C1, Constant *C2);
   static Constant *getNUWMul(Constant *C1, Constant *C2);
   static Constant *getExactSDiv(Constant *C1, Constant *C2);
+  static Constant *getExactUDiv(Constant *C1, Constant *C2);
 
   /// Transparently provide more efficient getOperand methods.
   DECLARE_TRANSPARENT_OPERAND_ACCESSORS(Constant);
diff --git a/include/llvm/InstrTypes.h b/include/llvm/InstrTypes.h
index 9dcf6883583..1bb50b78fae 100644
--- a/include/llvm/InstrTypes.h
+++ b/include/llvm/InstrTypes.h
@@ -341,7 +341,7 @@ public:
     BO->setIsExact(true);
     return BO;
   }
-
+  
   /// Helper functions to construct and inspect unary operations (NEG and NOT)
   /// via binary operators SUB and XOR:
   ///
diff --git a/include/llvm/Operator.h b/include/llvm/Operator.h
index 3aae586f144..288edf12244 100644
--- a/include/llvm/Operator.h
+++ b/include/llvm/Operator.h
@@ -173,30 +173,47 @@ public:
   }
 };
 
-/// SDivOperator - An Operator with opcode Instruction::SDiv.
-///
-class SDivOperator : public Operator {
+/// PossiblyExactOperator - A udiv or sdiv instruction, which can be marked as
+/// "exact", indicating that no bits are destroyed.
+class PossiblyExactOperator : 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);
   }
-
+  
+private:
+  ~PossiblyExactOperator(); // do not implement
 public:
   /// isExact - Test whether this division is known to be exact, with
   /// zero remainder.
   bool isExact() const {
     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(V) && classof(cast(V))) ||
+    (isa(V) && classof(cast(V)));
+  }
+};
+  
+/// 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) {
@@ -211,6 +228,24 @@ public:
   }
 };
 
+/// UDivOperator - An Operator with opcode Instruction::SDiv.
+///
+class UDivOperator : public PossiblyExactOperator {
+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 Instruction *I) {
+    return I->getOpcode() == Instruction::UDiv;
+  }
+  static inline bool classof(const Value *V) {
+    return (isa(V) && classof(cast(V))) ||
+    (isa(V) && classof(cast(V)));
+  }
+};
+  
 class GEPOperator : public Operator {
   enum {
     IsInBounds = (1 << 0)
diff --git a/lib/AsmParser/LLParser.cpp b/lib/AsmParser/LLParser.cpp
index 8ef46344175..6d71c9e3e60 100644
--- a/lib/AsmParser/LLParser.cpp
+++ b/lib/AsmParser/LLParser.cpp
@@ -2304,7 +2304,7 @@ bool LLParser::ParseValID(ValID &ID, PerFunctionState *PFS) {
         if (EatIfPresent(lltok::kw_nuw))
           NUW = true;
       }
-    } else if (Opc == Instruction::SDiv) {
+    } else if (Opc == Instruction::SDiv || Opc == Instruction::UDiv) {
       if (EatIfPresent(lltok::kw_exact))
         Exact = true;
     }
@@ -2347,7 +2347,7 @@ bool LLParser::ParseValID(ValID &ID, PerFunctionState *PFS) {
     unsigned Flags = 0;
     if (NUW)   Flags |= OverflowingBinaryOperator::NoUnsignedWrap;
     if (NSW)   Flags |= OverflowingBinaryOperator::NoSignedWrap;
-    if (Exact) Flags |= SDivOperator::IsExact;
+    if (Exact) Flags |= PossiblyExactOperator::IsExact;
     Constant *C = ConstantExpr::get(Opc, Val0, Val1, Flags);
     ID.ConstantVal = C;
     ID.Kind = ValID::t_Constant;
@@ -3032,7 +3032,8 @@ int LLParser::ParseInstruction(Instruction *&Inst, BasicBlock *BB,
   case lltok::kw_fsub:
   case lltok::kw_fmul:    return ParseArithmetic(Inst, PFS, KeywordVal, 2);
 
-  case lltok::kw_sdiv: {
+  case lltok::kw_sdiv:
+  case lltok::kw_udiv: {
     bool Exact = false;
     if (EatIfPresent(lltok::kw_exact))
       Exact = true;
@@ -3043,7 +3044,6 @@ int LLParser::ParseInstruction(Instruction *&Inst, BasicBlock *BB,
     return Result;
   }
 
-  case lltok::kw_udiv:
   case lltok::kw_urem:
   case lltok::kw_srem:   return ParseArithmetic(Inst, PFS, KeywordVal, 1);
   case lltok::kw_fdiv:
diff --git a/lib/Bitcode/Reader/BitcodeReader.cpp b/lib/Bitcode/Reader/BitcodeReader.cpp
index adcad749891..a744d833026 100644
--- a/lib/Bitcode/Reader/BitcodeReader.cpp
+++ b/lib/Bitcode/Reader/BitcodeReader.cpp
@@ -1090,8 +1090,9 @@ bool BitcodeReader::ParseConstants() {
               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))
+          } else if (Opc == Instruction::SDiv ||
+                     Opc == Instruction::UDiv) {
+            if (Record[3] & (1 << bitc::PEO_EXACT))
               Flags |= SDivOperator::IsExact;
           }
         }
@@ -1905,8 +1906,9 @@ bool BitcodeReader::ParseFunctionBody(Function *F) {
             cast(I)->setHasNoSignedWrap(true);
           if (Record[OpNum] & (1 << bitc::OBO_NO_UNSIGNED_WRAP))
             cast(I)->setHasNoUnsignedWrap(true);
-        } else if (Opc == Instruction::SDiv) {
-          if (Record[OpNum] & (1 << bitc::SDIV_EXACT))
+        } else if (Opc == Instruction::SDiv ||
+                   Opc == Instruction::UDiv) {
+          if (Record[OpNum] & (1 << bitc::PEO_EXACT))
             cast(I)->setIsExact(true);
         }
       }
diff --git a/lib/Bitcode/Writer/BitcodeWriter.cpp b/lib/Bitcode/Writer/BitcodeWriter.cpp
index 702a611cbe5..f8ef8c668c4 100644
--- a/lib/Bitcode/Writer/BitcodeWriter.cpp
+++ b/lib/Bitcode/Writer/BitcodeWriter.cpp
@@ -470,9 +470,10 @@ static uint64_t GetOptimizationFlags(const Value *V) {
       Flags |= 1 << bitc::OBO_NO_SIGNED_WRAP;
     if (OBO->hasNoUnsignedWrap())
       Flags |= 1 << bitc::OBO_NO_UNSIGNED_WRAP;
-  } else if (const SDivOperator *Div = dyn_cast(V)) {
-    if (Div->isExact())
-      Flags |= 1 << bitc::SDIV_EXACT;
+  } else if (const PossiblyExactOperator *PEO =
+               dyn_cast(V)) {
+    if (PEO->isExact())
+      Flags |= 1 << bitc::PEO_EXACT;
   }
 
   return Flags;
diff --git a/lib/Transforms/InstCombine/InstCombineMulDivRem.cpp b/lib/Transforms/InstCombine/InstCombineMulDivRem.cpp
index 035ee721bfd..559788b4a90 100644
--- a/lib/Transforms/InstCombine/InstCombineMulDivRem.cpp
+++ b/lib/Transforms/InstCombine/InstCombineMulDivRem.cpp
@@ -135,8 +135,8 @@ Instruction *InstCombiner::visitMul(BinaryOperator &I) {
          BO->getOpcode() == Instruction::SDiv)) {
       Value *Op0BO = BO->getOperand(0), *Op1BO = BO->getOperand(1);
 
-      // If the division is exact, X % Y is zero.
-      if (SDivOperator *SDiv = dyn_cast(BO))
+      // If the division is exact, X % Y is zero, so we end up with X or -X.
+      if (PossiblyExactOperator *SDiv = dyn_cast(BO))
         if (SDiv->isExact()) {
           if (Op1BO == Op1C)
             return ReplaceInstUsesWith(I, Op0BO);
diff --git a/lib/VMCore/AsmWriter.cpp b/lib/VMCore/AsmWriter.cpp
index 1a11d9c7980..5b56cb572cf 100644
--- a/lib/VMCore/AsmWriter.cpp
+++ b/lib/VMCore/AsmWriter.cpp
@@ -831,7 +831,8 @@ static void WriteOptimizationInfo(raw_ostream &Out, const User *U) {
       Out << " nuw";
     if (OBO->hasNoSignedWrap())
       Out << " nsw";
-  } else if (const SDivOperator *Div = dyn_cast(U)) {
+  } else if (const PossiblyExactOperator *Div =
+               dyn_cast(U)) {
     if (Div->isExact())
       Out << " exact";
   } else if (const GEPOperator *GEP = dyn_cast(U)) {
diff --git a/lib/VMCore/Constants.cpp b/lib/VMCore/Constants.cpp
index 62117b22e6c..d2359e5bcda 100644
--- a/lib/VMCore/Constants.cpp
+++ b/lib/VMCore/Constants.cpp
@@ -683,7 +683,12 @@ Constant* ConstantExpr::getNUWMul(Constant* C1, Constant* C2) {
 
 Constant* ConstantExpr::getExactSDiv(Constant* C1, Constant* C2) {
   return getTy(C1->getType(), Instruction::SDiv, C1, C2,
-               SDivOperator::IsExact);
+               PossiblyExactOperator::IsExact);
+}
+
+Constant* ConstantExpr::getExactUDiv(Constant* C1, Constant* C2) {
+  return getTy(C1->getType(), Instruction::UDiv, C1, C2,
+               PossiblyExactOperator::IsExact);
 }
 
 // Utility function for determining if a ConstantExpr is a CastOp or not. This
diff --git a/lib/VMCore/Instructions.cpp b/lib/VMCore/Instructions.cpp
index 6b561f34af2..d1290281cb1 100644
--- a/lib/VMCore/Instructions.cpp
+++ b/lib/VMCore/Instructions.cpp
@@ -1822,7 +1822,7 @@ void BinaryOperator::setHasNoSignedWrap(bool b) {
 }
 
 void BinaryOperator::setIsExact(bool b) {
-  cast(this)->setIsExact(b);
+  cast(this)->setIsExact(b);
 }
 
 bool BinaryOperator::hasNoUnsignedWrap() const {
@@ -1834,7 +1834,7 @@ bool BinaryOperator::hasNoSignedWrap() const {
 }
 
 bool BinaryOperator::isExact() const {
-  return cast(this)->isExact();
+  return cast(this)->isExact();
 }
 
 //===----------------------------------------------------------------------===//
diff --git a/test/Assembler/flags.ll b/test/Assembler/flags.ll
index 32419090597..82b35b5c210 100644
--- a/test/Assembler/flags.ll
+++ b/test/Assembler/flags.ll
@@ -104,6 +104,19 @@ define i64 @sdiv_plain(i64 %x, i64 %y) {
 	ret i64 %z
 }
 
+define i64 @udiv_exact(i64 %x, i64 %y) {
+; CHECK: %z = udiv exact i64 %x, %y
+	%z = udiv exact i64 %x, %y
+	ret i64 %z
+}
+
+define i64 @udiv_plain(i64 %x, i64 %y) {
+; CHECK: %z = udiv i64 %x, %y
+	%z = udiv i64 %x, %y
+	ret i64 %z
+}
+
+
 define i64* @gep_nw(i64* %p, i64 %x) {
 ; CHECK: %z = getelementptr inbounds i64* %p, i64 %x
 	%z = getelementptr inbounds i64* %p, i64 %x
@@ -136,6 +149,11 @@ define i64 @sdiv_exact_ce() {
 	ret i64 sdiv exact (i64 ptrtoint (i64* @addr to i64), i64 91)
 }
 
+define i64 @udiv_exact_ce() {
+; CHECK: ret i64 udiv exact (i64 ptrtoint (i64* @addr to i64), i64 91)
+	ret i64 udiv exact (i64 ptrtoint (i64* @addr to i64), i64 91)
+}
+
 define i64* @gep_nw_ce() {
 ; CHECK: ret i64* getelementptr inbounds (i64* @addr, i64 171)
         ret i64* getelementptr inbounds (i64* @addr, i64 171)
@@ -210,3 +228,4 @@ 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)
 }
+
diff --git a/test/Transforms/InstCombine/exact-sdiv.ll b/test/Transforms/InstCombine/exact.ll
similarity index 87%
rename from test/Transforms/InstCombine/exact-sdiv.ll
rename to test/Transforms/InstCombine/exact.ll
index e5677541e95..940469ea711 100644
--- a/test/Transforms/InstCombine/exact-sdiv.ll
+++ b/test/Transforms/InstCombine/exact.ll
@@ -50,3 +50,11 @@ define i32 @b1(i32 %x) {
   %z = mul i32 %y, -3
   ret i32 %z
 }
+
+; CHECK: i32 @b2
+; CHECK: ret i32 %x
+define i32 @b2(i32 %x, i32 %w) {
+  %y = udiv exact i32 %x, %w
+  %z = mul i32 %y, %w
+  ret i32 %z
+}