mirror of
https://github.com/c64scene-ar/llvm-6502.git
synced 2025-06-29 13:24:25 +00:00
LLVM currently represents floating-point negation as -0.0 - x. Fix
FastISel to recognize this pattern and emit a floating-point negation using xor. git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@80963 91177308-0d34-0410-b5e6-96231b3b80d8
This commit is contained in:
@ -300,6 +300,8 @@ protected:
|
|||||||
private:
|
private:
|
||||||
bool SelectBinaryOp(User *I, ISD::NodeType ISDOpcode);
|
bool SelectBinaryOp(User *I, ISD::NodeType ISDOpcode);
|
||||||
|
|
||||||
|
bool SelectFNeg(User *I);
|
||||||
|
|
||||||
bool SelectGetElementPtr(User *I);
|
bool SelectGetElementPtr(User *I);
|
||||||
|
|
||||||
bool SelectCall(User *I);
|
bool SelectCall(User *I);
|
||||||
|
@ -608,6 +608,26 @@ FastISel::FastEmitBranch(MachineBasicBlock *MSucc) {
|
|||||||
MBB->addSuccessor(MSucc);
|
MBB->addSuccessor(MSucc);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/// SelectFNeg - Emit an FNeg operation.
|
||||||
|
///
|
||||||
|
bool
|
||||||
|
FastISel::SelectFNeg(User *I) {
|
||||||
|
unsigned OpReg = getRegForValue(BinaryOperator::getFNegArgument(I));
|
||||||
|
if (OpReg == 0) return false;
|
||||||
|
|
||||||
|
// Twiddle the sign bit with xor.
|
||||||
|
EVT VT = TLI.getValueType(I->getType());
|
||||||
|
if (VT.getSizeInBits() > 64) return false;
|
||||||
|
unsigned ResultReg = FastEmit_ri_(VT.getSimpleVT(), ISD::XOR, OpReg,
|
||||||
|
UINT64_C(1) << (VT.getSizeInBits()-1),
|
||||||
|
VT.getSimpleVT());
|
||||||
|
if (ResultReg == 0)
|
||||||
|
return false;
|
||||||
|
|
||||||
|
UpdateValueMap(I, ResultReg);
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
bool
|
bool
|
||||||
FastISel::SelectOperator(User *I, unsigned Opcode) {
|
FastISel::SelectOperator(User *I, unsigned Opcode) {
|
||||||
switch (Opcode) {
|
switch (Opcode) {
|
||||||
@ -618,6 +638,9 @@ FastISel::SelectOperator(User *I, unsigned Opcode) {
|
|||||||
case Instruction::Sub:
|
case Instruction::Sub:
|
||||||
return SelectBinaryOp(I, ISD::SUB);
|
return SelectBinaryOp(I, ISD::SUB);
|
||||||
case Instruction::FSub:
|
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);
|
return SelectBinaryOp(I, ISD::FSUB);
|
||||||
case Instruction::Mul:
|
case Instruction::Mul:
|
||||||
return SelectBinaryOp(I, ISD::MUL);
|
return SelectBinaryOp(I, ISD::MUL);
|
||||||
|
15
test/CodeGen/X86/fast-isel-fneg.ll
Normal file
15
test/CodeGen/X86/fast-isel-fneg.ll
Normal file
@ -0,0 +1,15 @@
|
|||||||
|
; RUN: llvm-as < %s | llc -fast-isel -march=x86-64 | FileCheck %s
|
||||||
|
|
||||||
|
; CHECK: doo:
|
||||||
|
; CHECK: xorpd
|
||||||
|
define double @doo(double %x) nounwind {
|
||||||
|
%y = fsub double -0.0, %x
|
||||||
|
ret double %y
|
||||||
|
}
|
||||||
|
|
||||||
|
; CHECK: foo:
|
||||||
|
; CHECK: xorps
|
||||||
|
define float @foo(float %x) nounwind {
|
||||||
|
%y = fsub float -0.0, %x
|
||||||
|
ret float %y
|
||||||
|
}
|
Reference in New Issue
Block a user