<h5>Syntax:</h5>
<pre>
- <result> = udiv <ty> <op1>, <op2> <i>; yields {ty}:result</i>
+ <result> = udiv <ty> <op1>, <op2> <i>; yields {ty}:result</i>
+ <result> = udiv exact <ty> <op1>, <op2> <i>; yields {ty}:result</i>
</pre>
<h5>Overview:</h5>
<p>Division by zero leads to undefined behavior.</p>
+<p>If the <tt>exact</tt> keyword is present, the result value of the
+ <tt>udiv</tt> is a <a href="#trapvalues">trap value</a> if %op1 is not a
+ multiple of %op2 (as such, "((a udiv exact b) mul b) == a").</p>
+
+
<h5>Example:</h5>
<pre>
<result> = udiv i32 4, %var <i>; yields {i32}:result = 4 / %var</i>
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
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);
BO->setIsExact(true);
return BO;
}
-
+
/// Helper functions to construct and inspect unary operations (NEG and NOT)
/// via binary operators SUB and XOR:
///
}
};
-/// 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<Instruction>(V) && classof(cast<Instruction>(V))) ||
+ (isa<ConstantExpr>(V) && classof(cast<ConstantExpr>(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) {
}
};
+/// 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<Instruction>(V) && classof(cast<Instruction>(V))) ||
+ (isa<ConstantExpr>(V) && classof(cast<ConstantExpr>(V)));
+ }
+};
+
class GEPOperator : public Operator {
enum {
IsInBounds = (1 << 0)
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;
}
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;
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;
return Result;
}
- case lltok::kw_udiv:
case lltok::kw_urem:
case lltok::kw_srem: return ParseArithmetic(Inst, PFS, KeywordVal, 1);
case lltok::kw_fdiv:
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;
}
}
cast<BinaryOperator>(I)->setHasNoSignedWrap(true);
if (Record[OpNum] & (1 << bitc::OBO_NO_UNSIGNED_WRAP))
cast<BinaryOperator>(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<BinaryOperator>(I)->setIsExact(true);
}
}
Flags |= 1 << bitc::OBO_NO_SIGNED_WRAP;
if (OBO->hasNoUnsignedWrap())
Flags |= 1 << bitc::OBO_NO_UNSIGNED_WRAP;
- } else if (const SDivOperator *Div = dyn_cast<SDivOperator>(V)) {
- if (Div->isExact())
- Flags |= 1 << bitc::SDIV_EXACT;
+ } else if (const PossiblyExactOperator *PEO =
+ dyn_cast<PossiblyExactOperator>(V)) {
+ if (PEO->isExact())
+ Flags |= 1 << bitc::PEO_EXACT;
}
return Flags;
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<SDivOperator>(BO))
+ // If the division is exact, X % Y is zero, so we end up with X or -X.
+ if (PossiblyExactOperator *SDiv = dyn_cast<PossiblyExactOperator>(BO))
if (SDiv->isExact()) {
if (Op1BO == Op1C)
return ReplaceInstUsesWith(I, Op0BO);
Out << " nuw";
if (OBO->hasNoSignedWrap())
Out << " nsw";
- } else if (const SDivOperator *Div = dyn_cast<SDivOperator>(U)) {
+ } else if (const PossiblyExactOperator *Div =
+ dyn_cast<PossiblyExactOperator>(U)) {
if (Div->isExact())
Out << " exact";
} else if (const GEPOperator *GEP = dyn_cast<GEPOperator>(U)) {
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
}
void BinaryOperator::setIsExact(bool b) {
- cast<SDivOperator>(this)->setIsExact(b);
+ cast<PossiblyExactOperator>(this)->setIsExact(b);
}
bool BinaryOperator::hasNoUnsignedWrap() const {
}
bool BinaryOperator::isExact() const {
- return cast<SDivOperator>(this)->isExact();
+ return cast<PossiblyExactOperator>(this)->isExact();
}
//===----------------------------------------------------------------------===//
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
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)
; 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)
}
+
+++ /dev/null
-; RUN: opt < %s -instcombine -S | FileCheck %s
-
-; CHECK: define i32 @foo
-; CHECK: sdiv i32 %x, 8
-define i32 @foo(i32 %x) {
- %y = sdiv i32 %x, 8
- ret i32 %y
-}
-
-; CHECK: define i32 @bar
-; CHECK: ashr i32 %x, 3
-define i32 @bar(i32 %x) {
- %y = sdiv exact i32 %x, 8
- ret i32 %y
-}
-
-; CHECK: i32 @a0
-; CHECK: %y = srem i32 %x, 3
-; CHECK: %z = sub i32 %x, %y
-; CHECK: ret i32 %z
-define i32 @a0(i32 %x) {
- %y = sdiv i32 %x, 3
- %z = mul i32 %y, 3
- ret i32 %z
-}
-
-; CHECK: i32 @b0
-; CHECK: ret i32 %x
-define i32 @b0(i32 %x) {
- %y = sdiv exact i32 %x, 3
- %z = mul i32 %y, 3
- ret i32 %z
-}
-
-; CHECK: i32 @a1
-; CHECK: %y = srem i32 %x, 3
-; CHECK: %z = sub i32 %y, %x
-; CHECK: ret i32 %z
-define i32 @a1(i32 %x) {
- %y = sdiv i32 %x, 3
- %z = mul i32 %y, -3
- ret i32 %z
-}
-
-; CHECK: i32 @b1
-; CHECK: %z = sub i32 0, %x
-; CHECK: ret i32 %z
-define i32 @b1(i32 %x) {
- %y = sdiv exact i32 %x, 3
- %z = mul i32 %y, -3
- ret i32 %z
-}
--- /dev/null
+; RUN: opt < %s -instcombine -S | FileCheck %s
+
+; CHECK: define i32 @foo
+; CHECK: sdiv i32 %x, 8
+define i32 @foo(i32 %x) {
+ %y = sdiv i32 %x, 8
+ ret i32 %y
+}
+
+; CHECK: define i32 @bar
+; CHECK: ashr i32 %x, 3
+define i32 @bar(i32 %x) {
+ %y = sdiv exact i32 %x, 8
+ ret i32 %y
+}
+
+; CHECK: i32 @a0
+; CHECK: %y = srem i32 %x, 3
+; CHECK: %z = sub i32 %x, %y
+; CHECK: ret i32 %z
+define i32 @a0(i32 %x) {
+ %y = sdiv i32 %x, 3
+ %z = mul i32 %y, 3
+ ret i32 %z
+}
+
+; CHECK: i32 @b0
+; CHECK: ret i32 %x
+define i32 @b0(i32 %x) {
+ %y = sdiv exact i32 %x, 3
+ %z = mul i32 %y, 3
+ ret i32 %z
+}
+
+; CHECK: i32 @a1
+; CHECK: %y = srem i32 %x, 3
+; CHECK: %z = sub i32 %y, %x
+; CHECK: ret i32 %z
+define i32 @a1(i32 %x) {
+ %y = sdiv i32 %x, 3
+ %z = mul i32 %y, -3
+ ret i32 %z
+}
+
+; CHECK: i32 @b1
+; CHECK: %z = sub i32 0, %x
+; CHECK: ret i32 %z
+define i32 @b1(i32 %x) {
+ %y = sdiv exact i32 %x, 3
+ %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
+}