Include optional subclass flags, such as inbounds, nsw, etc., in the

Constant uniquing tables. This allows distinct ConstantExpr objects
with the same operation and different flags.

Even though a ConstantExpr "a + b" is either always overflowing or
never overflowing (due to being a ConstantExpr), it's still necessary
to be able to represent it both with and without overflow flags at
the same time within the IR, because the safety of the flag may
depend on the context of the use. If the constant really does overflow,
it wouldn't ever be safe to use with the flag set, however the use
may be in code that is never actually executed.

This also makes it possible to merge all the flags tests into a single test.


git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@80998 91177308-0d34-0410-b5e6-96231b3b80d8
This commit is contained in:
Dan Gohman
2009-09-04 12:08:11 +00:00
parent 70327dabb4
commit 859fff476d
16 changed files with 349 additions and 243 deletions

View File

@ -2095,13 +2095,11 @@ bool LLParser::ParseValID(ValID &ID) {
if (!Val0->getType()->isIntOrIntVector() &&
!Val0->getType()->isFPOrFPVector())
return Error(ID.Loc,"constexpr requires integer, fp, or vector operands");
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);
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);
ID.ConstantVal = C;
ID.Kind = ValID::t_Constant;
return false;
@ -2157,10 +2155,12 @@ bool LLParser::ParseValID(ValID &ID) {
(Value**)(Elts.data() + 1),
Elts.size() - 1))
return Error(ID.Loc, "invalid indices for getelementptr");
ID.ConstantVal = ConstantExpr::getGetElementPtr(Elts[0],
Elts.data() + 1, Elts.size() - 1);
if (InBounds)
cast<GEPOperator>(ID.ConstantVal)->setIsInBounds(true);
ID.ConstantVal = InBounds ?
ConstantExpr::getInBoundsGetElementPtr(Elts[0],
Elts.data() + 1,
Elts.size() - 1) :
ConstantExpr::getGetElementPtr(Elts[0],
Elts.data() + 1, Elts.size() - 1);
} 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<OverflowingBinaryOperator>(Inst)->setHasNoUnsignedWrap(true);
cast<BinaryOperator>(Inst)->setHasNoUnsignedWrap(true);
if (NSW)
cast<OverflowingBinaryOperator>(Inst)->setHasNoSignedWrap(true);
cast<BinaryOperator>(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<SDivOperator>(Inst)->setIsExact(true);
cast<BinaryOperator>(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<GEPOperator>(Inst)->setIsInBounds(true);
cast<GetElementPtrInst>(Inst)->setIsInBounds(true);
return false;
}