diff --git a/lib/Target/SparcV9/SparcV9PreSelection.cpp b/lib/Target/SparcV9/SparcV9PreSelection.cpp index 2e55594b7c1..e3dec4621eb 100644 --- a/lib/Target/SparcV9/SparcV9PreSelection.cpp +++ b/lib/Target/SparcV9/SparcV9PreSelection.cpp @@ -146,6 +146,7 @@ namespace { void visitInstruction(Instruction &I); // common work for every instr. void visitGetElementPtrInst(GetElementPtrInst &I); void visitLoadInst(LoadInst &I); + void visitCastInst(CastInst &I); void visitStoreInst(StoreInst &I); // Helper functions for visiting operands of every instruction @@ -228,6 +229,33 @@ PreSelection::visitStoreInst(StoreInst &I) } +// Cast instructions: make multi-step casts explicit +// -- float/double to uint32_t: +// If target does not have a float-to-unsigned instruction, we +// need to convert to uint64_t and then to uint32_t, or we may +// overflow the signed int representation for legal uint32_t +// values. Expand this without checking target. +// +void +PreSelection::visitCastInst(CastInst &I) +{ + CastInst* castI = NULL; + + // Check for a global and put its address into a register before this instr + if (I.getType() == Type::UIntTy && + I.getOperand(0)->getType()->isFloatingPoint()) + { // insert a cast-fp-to-long before I, and then replace the operand of I + castI = new CastInst(I.getOperand(0), Type::LongTy, "fp2Long2Uint", &I); + I.setOperand(0, castI); // replace fp operand with long + } + + // Perform other transformations common to all instructions + visitInstruction(I); + if (castI) + visitInstruction(*castI); +} + + // visitOperands() transforms individual operands of all instructions: // -- Load "large" int constants into a virtual register. What is large // depends on the type of instruction and on the target architecture.