[GlobalISel] Add default action for G_FNEG

Summary: rL297171 introduced G_FNEG for floating-point negation instruction and IRTranslator started to translate `FSUB -0.0, X` to `FNEG X`. This patch adds a default action for G_FNEG to avoid breaking existing targets.

Reviewers: qcolombet, ab, kristof.beyls, t.p.northover, aditya_nandakumar, dsanders

Reviewed By: qcolombet

Subscribers: dberris, rovka, llvm-commits

Differential Revision: https://reviews.llvm.org/D30721

llvm-svn: 297301
This commit is contained in:
Volkan Keles 2017-03-08 18:09:14 +00:00
parent 7d86ee5ab0
commit 5698b2ae6e
3 changed files with 84 additions and 0 deletions

View File

@ -539,6 +539,38 @@ LegalizerHelper::lower(MachineInstr &MI, unsigned TypeIdx, LLT Ty) {
MI.eraseFromParent();
return Legalized;
}
case TargetOpcode::G_FNEG: {
// TODO: Handle vector types once we are able to
// represent them.
if (Ty.isVector())
return UnableToLegalize;
unsigned Res = MI.getOperand(0).getReg();
Type *ZeroTy;
LLVMContext &Ctx = MIRBuilder.getMF().getFunction()->getContext();
switch (Ty.getSizeInBits()) {
case 16:
ZeroTy = Type::getHalfTy(Ctx);
break;
case 32:
ZeroTy = Type::getFloatTy(Ctx);
break;
case 64:
ZeroTy = Type::getDoubleTy(Ctx);
break;
default:
llvm_unreachable("unexpected floating-point type");
}
ConstantFP &ZeroForNegation =
*cast<ConstantFP>(ConstantFP::getZeroValueForNegation(ZeroTy));
unsigned Zero = MRI.createGenericVirtualRegister(Ty);
MIRBuilder.buildFConstant(Zero, ZeroForNegation);
MIRBuilder.buildInstr(TargetOpcode::G_FSUB)
.addDef(Res)
.addUse(Zero)
.addUse(MI.getOperand(1).getReg());
MI.eraseFromParent();
return Legalized;
}
}
}

View File

@ -42,6 +42,7 @@ LegalizerInfo::LegalizerInfo() : TablesInitialized(false) {
DefaultActions[TargetOpcode::G_BRCOND] = WidenScalar;
DefaultActions[TargetOpcode::G_INSERT] = NarrowScalar;
DefaultActions[TargetOpcode::G_FNEG] = Lower;
}
void LegalizerInfo::computeTables() {
@ -96,6 +97,9 @@ LegalizerInfo::getAction(const InstrAspect &Aspect) const {
if (DefaultAction != DefaultActions.end() && DefaultAction->second == Legal)
return std::make_pair(Legal, Ty);
if (DefaultAction != DefaultActions.end() && DefaultAction->second == Lower)
return std::make_pair(Lower, Ty);
if (DefaultAction == DefaultActions.end() ||
DefaultAction->second != NarrowScalar)
return std::make_pair(Unsupported, LLT());

View File

@ -0,0 +1,48 @@
# RUN: llc -O0 -run-pass=legalizer -global-isel %s -o - | FileCheck %s
--- |
target datalayout = "e-m:o-i64:64-i128:128-n32:64-S128"
target triple = "aarch64--"
define void @test_fneg_f32() {
entry:
ret void
}
define void @test_fneg_f64() {
entry:
ret void
}
...
---
name: test_fneg_f32
registers:
- { id: 0, class: _ }
- { id: 1, class: _ }
body: |
bb.1:
liveins: %s0
; CHECK-LABEL: name: test_fneg_f32
; CHECK: [[VAR:%[0-9]+]](s32) = COPY %s0
; CHECK: [[ZERO:%[0-9]+]](s32) = G_FCONSTANT float -0.000000e+00
; CHECK: [[RES:%[0-9]+]](s32) = G_FSUB [[ZERO]], [[VAR]]
; CHECK: %s0 = COPY [[RES]](s32)
%0(s32) = COPY %s0
%1(s32) = G_FNEG %0
%s0 = COPY %1(s32)
...
---
name: test_fneg_f64
registers:
- { id: 0, class: _ }
- { id: 1, class: _ }
body: |
bb.1:
liveins: %d0
; CHECK-LABEL: name: test_fneg_f64
; CHECK: [[VAR:%[0-9]+]](s64) = COPY %d0
; CHECK: [[ZERO:%[0-9]+]](s64) = G_FCONSTANT double -0.000000e+00
; CHECK: [[RES:%[0-9]+]](s64) = G_FSUB [[ZERO]], [[VAR]]
; CHECK: %d0 = COPY [[RES]](s64)
%0(s64) = COPY %d0
%1(s64) = G_FNEG %0
%d0 = COPY %1(s64)
...