aboutsummaryrefslogtreecommitdiff
path: root/lib/Transforms/NaCl/ExpandArithWithOverflow.cpp
diff options
context:
space:
mode:
authorMark Seaborn <mseaborn@chromium.org>2013-05-30 13:08:26 -0700
committerMark Seaborn <mseaborn@chromium.org>2013-05-30 13:08:26 -0700
commitf72e0b53e25548d6db9220a03a303e589c9773a4 (patch)
treeaaff14bd8167571353c50289b005bd0fe5c98925 /lib/Transforms/NaCl/ExpandArithWithOverflow.cpp
parent663c1c948321264aceb07b86cfadcd06b3386e1e (diff)
PNaCl: Add a pass to expand out Clang's use of registers of struct type
Clang's implementation of C++ method pointers generates IR that uses LLVM registers with struct type -- specifically, loads and stores of struct values, and extractvalue instructions. See lib/CodeGen/ItaniumCXXABI.cpp in Clang. Add a pass, ExpandStructRegs, which expands out those uses. Factor out a function from ExpandArithWithOverflow so that the two passes can share some code. BUG=https://code.google.com/p/nativeclient/issues/detail?id=3343 TEST=*.ll tests + trybots + GCC torture tests Review URL: https://codereview.chromium.org/15692014
Diffstat (limited to 'lib/Transforms/NaCl/ExpandArithWithOverflow.cpp')
-rw-r--r--lib/Transforms/NaCl/ExpandArithWithOverflow.cpp33
1 files changed, 6 insertions, 27 deletions
diff --git a/lib/Transforms/NaCl/ExpandArithWithOverflow.cpp b/lib/Transforms/NaCl/ExpandArithWithOverflow.cpp
index e120b24293..1c879d524c 100644
--- a/lib/Transforms/NaCl/ExpandArithWithOverflow.cpp
+++ b/lib/Transforms/NaCl/ExpandArithWithOverflow.cpp
@@ -94,9 +94,10 @@ static bool ExpandOpForIntSize(Module *M, unsigned Bits, bool Mul) {
"*.with.overflow must be a constant");
}
- Value *ArithResult = BinaryOperator::Create(
+ SmallVector<Value *, 2> Fields;
+ Fields.push_back(BinaryOperator::Create(
(Mul ? Instruction::Mul : Instruction::Add), VariableArg, ConstantArg,
- Call->getName() + ".arith", Call);
+ Call->getName() + ".arith", Call));
uint64_t ArgMax;
if (Mul) {
@@ -104,32 +105,10 @@ static bool ExpandOpForIntSize(Module *M, unsigned Bits, bool Mul) {
} else {
ArgMax = UintTypeMax(Bits) - ConstantArg->getZExtValue();
}
- Value *Overflow = new ICmpInst(
+ Fields.push_back(new ICmpInst(
Call, CmpInst::ICMP_UGT, VariableArg, ConstantInt::get(IntTy, ArgMax),
- Call->getName() + ".overflow");
-
- for (Value::use_iterator FieldIter = Call->use_begin(),
- E = Call->use_end(); FieldIter != E; ) {
- User *U = *FieldIter++;
- ExtractValueInst *Field = dyn_cast<ExtractValueInst>(U);
- if (!Field) {
- errs() << "Use: " << *U << "\n";
- report_fatal_error(
- "ExpandArithWithOverflow: Use is not an extractvalue");
- }
- if (Field->getNumIndices() != 1) {
- report_fatal_error("ExpandArithWithOverflow: Unexpected indices");
- }
- unsigned Index = Field->getIndices()[0];
- if (Index == 0) {
- Field->replaceAllUsesWith(ArithResult);
- } else if (Index == 1) {
- Field->replaceAllUsesWith(Overflow);
- } else {
- report_fatal_error("ExpandArithWithOverflow: Unexpected index");
- }
- Field->eraseFromParent();
- }
+ Call->getName() + ".overflow"));
+ ReplaceUsesOfStructWithFields(Call, Fields);
Call->eraseFromParent();
}
Intrinsic->eraseFromParent();