if (isValidDebugInfoIntrinsic(*RSI, CodeGenOpt::None) && DW
&& DW->ShouldEmitDwarfDebug()) {
unsigned ID =
- DW->RecordRegionStart(cast<GlobalVariable>(RSI->getContext()));
+ DW->RecordRegionStart(RSI->getContext());
const TargetInstrDesc &II = TII.get(TargetInstrInfo::DBG_LABEL);
BuildMI(MBB, DL, II).addImm(ID);
}
if (isValidDebugInfoIntrinsic(*REI, CodeGenOpt::None) && DW
&& DW->ShouldEmitDwarfDebug()) {
unsigned ID = 0;
- DISubprogram Subprogram(cast<GlobalVariable>(REI->getContext()));
+ DISubprogram Subprogram(REI->getContext());
if (isInlinedFnEnd(*REI, MF.getFunction())) {
// This is end of an inlined function.
const TargetInstrDesc &II = TII.get(TargetInstrInfo::DBG_LABEL);
BuildMI(MBB, DL, II).addImm(ID);
} else {
const TargetInstrDesc &II = TII.get(TargetInstrInfo::DBG_LABEL);
- ID = DW->RecordRegionEnd(cast<GlobalVariable>(REI->getContext()));
+ ID = DW->RecordRegionEnd(REI->getContext());
BuildMI(MBB, DL, II).addImm(ID);
}
}
setCurDebugLoc(ExtractDebugLocation(*FSI, MF.getDebugLocInfo()));
DebugLocTuple PrevLocTpl = MF.getDebugLocTuple(PrevLoc);
- DISubprogram SP(cast<GlobalVariable>(FSI->getSubprogram()));
+ DISubprogram SP(FSI->getSubprogram());
unsigned LabelID = DW->RecordInlinedFnStart(SP,
DICompileUnit(PrevLocTpl.CompileUnit),
PrevLocTpl.Line,
MF.setDefaultDebugLoc(ExtractDebugLocation(*FSI, MF.getDebugLocInfo()));
// llvm.dbg.func_start also defines beginning of function scope.
- DW->RecordRegionStart(cast<GlobalVariable>(FSI->getSubprogram()));
+ DW->RecordRegionStart(FSI->getSubprogram());
return true;
}
case Intrinsic::dbg_declare: {
if (SI == StaticAllocaMap.end()) break; // VLAs.
int FI = SI->second;
- // Determine the debug globalvariable.
- GlobalValue *GV = cast<GlobalVariable>(Variable);
-
- DW->RecordVariable(cast<GlobalVariable>(GV), FI);
+ DW->RecordVariable(cast<MDNode>(Variable), FI);
return true;
}
case Intrinsic::eh_exception: {
MBB->addSuccessor(MSucc);
}
+/// SelectFNeg - Emit an FNeg operation.
+///
+bool
+FastISel::SelectFNeg(User *I) {
+ unsigned OpReg = getRegForValue(BinaryOperator::getFNegArgument(I));
+ if (OpReg == 0) return false;
+
+ // If the target has ISD::FNEG, use it.
+ EVT VT = TLI.getValueType(I->getType());
+ unsigned ResultReg = FastEmit_r(VT.getSimpleVT(), VT.getSimpleVT(),
+ ISD::FNEG, OpReg);
+ if (ResultReg != 0) {
+ UpdateValueMap(I, ResultReg);
+ return true;
+ }
+
+ // Bitcast the value to integer, twiddle the sign bit with xor,
+ // and then bitcast it back to floating-point.
+ if (VT.getSizeInBits() > 64) return false;
+ EVT IntVT = EVT::getIntegerVT(I->getContext(), VT.getSizeInBits());
+ if (!TLI.isTypeLegal(IntVT))
+ return false;
+
+ unsigned IntReg = FastEmit_r(VT.getSimpleVT(), IntVT.getSimpleVT(),
+ ISD::BIT_CONVERT, OpReg);
+ if (IntReg == 0)
+ return false;
+
+ unsigned IntResultReg = FastEmit_ri_(IntVT.getSimpleVT(), ISD::XOR, IntReg,
+ UINT64_C(1) << (VT.getSizeInBits()-1),
+ IntVT.getSimpleVT());
+ if (IntResultReg == 0)
+ return false;
+
+ ResultReg = FastEmit_r(IntVT.getSimpleVT(), VT.getSimpleVT(),
+ ISD::BIT_CONVERT, IntResultReg);
+ if (ResultReg == 0)
+ return false;
+
+ UpdateValueMap(I, ResultReg);
+ return true;
+}
+
bool
FastISel::SelectOperator(User *I, unsigned Opcode) {
switch (Opcode) {
case Instruction::Sub:
return SelectBinaryOp(I, ISD::SUB);
case Instruction::FSub:
+ // FNeg is currently represented in LLVM IR as a special case of FSub.
+ if (BinaryOperator::isFNeg(I))
+ return SelectFNeg(I);
return SelectBinaryOp(I, ISD::FSUB);
case Instruction::Mul:
return SelectBinaryOp(I, ISD::MUL);