Skip to content

Commit f9bff2a

Browse files
author
Michael Berg
committed
Propagate fmf in IRTranslate for fneg
Summary: This case is related to D63405 in that we need to be propagating FMF on negates. Reviewers: volkan, spatel, arsenm Reviewed By: arsenm Subscribers: wdng, javed.absar Differential Revision: https://reviews.llvm.org/D63458 llvm-svn: 363631
1 parent 971ad74 commit f9bff2a

File tree

2 files changed

+45
-8
lines changed

2 files changed

+45
-8
lines changed

llvm/lib/CodeGen/GlobalISel/IRTranslator.cpp

Lines changed: 17 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -285,8 +285,6 @@ void IRTranslator::addMachineCFGPred(CFGEdge Edge, MachineBasicBlock *NewPred) {
285285

286286
bool IRTranslator::translateBinaryOp(unsigned Opcode, const User &U,
287287
MachineIRBuilder &MIRBuilder) {
288-
// FIXME: handle signed/unsigned wrapping flags.
289-
290288
// Get or create a virtual register for each value.
291289
// Unless the value is a Constant => loadimm cst?
292290
// or inline constant each time?
@@ -308,18 +306,29 @@ bool IRTranslator::translateFSub(const User &U, MachineIRBuilder &MIRBuilder) {
308306
// -0.0 - X --> G_FNEG
309307
if (isa<Constant>(U.getOperand(0)) &&
310308
U.getOperand(0) == ConstantFP::getZeroValueForNegation(U.getType())) {
311-
MIRBuilder.buildInstr(TargetOpcode::G_FNEG)
312-
.addDef(getOrCreateVReg(U))
313-
.addUse(getOrCreateVReg(*U.getOperand(1)));
309+
unsigned Op1 = getOrCreateVReg(*U.getOperand(1));
310+
unsigned Res = getOrCreateVReg(U);
311+
uint16_t Flags = 0;
312+
if (isa<Instruction>(U)) {
313+
const Instruction &I = cast<Instruction>(U);
314+
Flags = MachineInstr::copyFlagsFromInstruction(I);
315+
}
316+
// Negate the last operand of the FSUB
317+
MIRBuilder.buildInstr(TargetOpcode::G_FNEG, {Res}, {Op1}, Flags);
314318
return true;
315319
}
316320
return translateBinaryOp(TargetOpcode::G_FSUB, U, MIRBuilder);
317321
}
318322

319323
bool IRTranslator::translateFNeg(const User &U, MachineIRBuilder &MIRBuilder) {
320-
MIRBuilder.buildInstr(TargetOpcode::G_FNEG)
321-
.addDef(getOrCreateVReg(U))
322-
.addUse(getOrCreateVReg(*U.getOperand(0)));
324+
unsigned Op0 = getOrCreateVReg(*U.getOperand(0));
325+
unsigned Res = getOrCreateVReg(U);
326+
uint16_t Flags = 0;
327+
if (isa<Instruction>(U)) {
328+
const Instruction &I = cast<Instruction>(U);
329+
Flags = MachineInstr::copyFlagsFromInstruction(I);
330+
}
331+
MIRBuilder.buildInstr(TargetOpcode::G_FNEG, {Res}, {Op0}, Flags);
323332
return true;
324333
}
325334

llvm/test/CodeGen/AArch64/GlobalISel/arm64-irtranslator.ll

Lines changed: 28 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -834,6 +834,16 @@ define float @test_fneg(float %arg1) {
834834
ret float %res
835835
}
836836

837+
; CHECK-LABEL: name: test_fneg_fmf
838+
; CHECK: [[ARG1:%[0-9]+]]:_(s32) = COPY $s0
839+
; CHECK-NEXT: [[RES:%[0-9]+]]:_(s32) = nnan ninf nsz arcp contract afn reassoc G_FNEG [[ARG1]]
840+
; CHECK-NEXT: $s0 = COPY [[RES]]
841+
; CHECK-NEXT: RET_ReallyLR implicit $s0
842+
define float @test_fneg_fmf(float %arg1) {
843+
%res = fneg fast float %arg1
844+
ret float %res
845+
}
846+
837847
; CHECK-LABEL: name: test_sadd_overflow
838848
; CHECK: [[LHS:%[0-9]+]]:_(s32) = COPY $w0
839849
; CHECK: [[RHS:%[0-9]+]]:_(s32) = COPY $w1
@@ -1536,6 +1546,15 @@ define float @test_fneg_f32(float %x) {
15361546
ret float %neg
15371547
}
15381548

1549+
define float @test_fneg_f32_fmf(float %x) {
1550+
; CHECK-LABEL: name: test_fneg_f32
1551+
; CHECK: [[ARG:%[0-9]+]]:_(s32) = COPY $s0
1552+
; CHECK: [[RES:%[0-9]+]]:_(s32) = nnan ninf nsz arcp contract afn reassoc G_FNEG [[ARG]]
1553+
; CHECK: $s0 = COPY [[RES]](s32)
1554+
%neg = fsub fast float -0.000000e+00, %x
1555+
ret float %neg
1556+
}
1557+
15391558
define double @test_fneg_f64(double %x) {
15401559
; CHECK-LABEL: name: test_fneg_f64
15411560
; CHECK: [[ARG:%[0-9]+]]:_(s64) = COPY $d0
@@ -1545,6 +1564,15 @@ define double @test_fneg_f64(double %x) {
15451564
ret double %neg
15461565
}
15471566

1567+
define double @test_fneg_f64_fmf(double %x) {
1568+
; CHECK-LABEL: name: test_fneg_f64
1569+
; CHECK: [[ARG:%[0-9]+]]:_(s64) = COPY $d0
1570+
; CHECK: [[RES:%[0-9]+]]:_(s64) = nnan ninf nsz arcp contract afn reassoc G_FNEG [[ARG]]
1571+
; CHECK: $d0 = COPY [[RES]](s64)
1572+
%neg = fsub fast double -0.000000e+00, %x
1573+
ret double %neg
1574+
}
1575+
15481576
define void @test_trivial_inlineasm() {
15491577
; CHECK-LABEL: name: test_trivial_inlineasm
15501578
; CHECK: INLINEASM &wibble, 1

0 commit comments

Comments
 (0)