Propagate fmf in IRTranslate for fneg
authorMichael Berg <michael_c_berg@apple.com>
Mon, 17 Jun 2019 23:19:40 +0000 (23:19 +0000)
committerMichael Berg <michael_c_berg@apple.com>
Mon, 17 Jun 2019 23:19:40 +0000 (23:19 +0000)
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

git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@363631 91177308-0d34-0410-b5e6-96231b3b80d8

lib/CodeGen/GlobalISel/IRTranslator.cpp
test/CodeGen/AArch64/GlobalISel/arm64-irtranslator.ll

index 270341f66801f325df00d0135cb9afc8bfeee91c..3458479b7cdef7cf7a20baee14307c9475beffdc 100644 (file)
@@ -285,8 +285,6 @@ void IRTranslator::addMachineCFGPred(CFGEdge Edge, MachineBasicBlock *NewPred) {
 
 bool IRTranslator::translateBinaryOp(unsigned Opcode, const User &U,
                                      MachineIRBuilder &MIRBuilder) {
-  // FIXME: handle signed/unsigned wrapping flags.
-
   // Get or create a virtual register for each value.
   // Unless the value is a Constant => loadimm cst?
   // or inline constant each time?
@@ -308,18 +306,29 @@ bool IRTranslator::translateFSub(const User &U, MachineIRBuilder &MIRBuilder) {
   // -0.0 - X --> G_FNEG
   if (isa<Constant>(U.getOperand(0)) &&
       U.getOperand(0) == ConstantFP::getZeroValueForNegation(U.getType())) {
-    MIRBuilder.buildInstr(TargetOpcode::G_FNEG)
-        .addDef(getOrCreateVReg(U))
-        .addUse(getOrCreateVReg(*U.getOperand(1)));
+    unsigned Op1 = getOrCreateVReg(*U.getOperand(1));
+    unsigned Res = getOrCreateVReg(U);
+    uint16_t Flags = 0;
+    if (isa<Instruction>(U)) {
+      const Instruction &I = cast<Instruction>(U);
+      Flags = MachineInstr::copyFlagsFromInstruction(I);
+    }
+    // Negate the last operand of the FSUB
+    MIRBuilder.buildInstr(TargetOpcode::G_FNEG, {Res}, {Op1}, Flags);
     return true;
   }
   return translateBinaryOp(TargetOpcode::G_FSUB, U, MIRBuilder);
 }
 
 bool IRTranslator::translateFNeg(const User &U, MachineIRBuilder &MIRBuilder) {
-  MIRBuilder.buildInstr(TargetOpcode::G_FNEG)
-      .addDef(getOrCreateVReg(U))
-      .addUse(getOrCreateVReg(*U.getOperand(0)));
+  unsigned Op0 = getOrCreateVReg(*U.getOperand(0));
+  unsigned Res = getOrCreateVReg(U);
+  uint16_t Flags = 0;
+  if (isa<Instruction>(U)) {
+    const Instruction &I = cast<Instruction>(U);
+    Flags = MachineInstr::copyFlagsFromInstruction(I);
+  }
+  MIRBuilder.buildInstr(TargetOpcode::G_FNEG, {Res}, {Op0}, Flags);
   return true;
 }
 
index 81f29b828afced3ea51a78167d21203da410a3c3..6f2c9dcff1ad45404b582ca6792cf12be7582437 100644 (file)
@@ -834,6 +834,16 @@ define float @test_fneg(float %arg1) {
   ret float %res
 }
 
+; CHECK-LABEL: name: test_fneg_fmf
+; CHECK: [[ARG1:%[0-9]+]]:_(s32) = COPY $s0
+; CHECK-NEXT: [[RES:%[0-9]+]]:_(s32) = nnan ninf nsz arcp contract afn reassoc G_FNEG [[ARG1]]
+; CHECK-NEXT: $s0 = COPY [[RES]]
+; CHECK-NEXT: RET_ReallyLR implicit $s0
+define float @test_fneg_fmf(float %arg1) {
+  %res = fneg fast float %arg1
+  ret float %res
+}
+
 ; CHECK-LABEL: name: test_sadd_overflow
 ; CHECK: [[LHS:%[0-9]+]]:_(s32) = COPY $w0
 ; CHECK: [[RHS:%[0-9]+]]:_(s32) = COPY $w1
@@ -1536,6 +1546,15 @@ define float @test_fneg_f32(float %x) {
   ret float %neg
 }
 
+define float @test_fneg_f32_fmf(float %x) {
+; CHECK-LABEL: name: test_fneg_f32
+; CHECK: [[ARG:%[0-9]+]]:_(s32) = COPY $s0
+; CHECK: [[RES:%[0-9]+]]:_(s32) = nnan ninf nsz arcp contract afn reassoc G_FNEG [[ARG]]
+; CHECK: $s0 = COPY [[RES]](s32)
+  %neg = fsub fast float -0.000000e+00, %x
+  ret float %neg
+}
+
 define double @test_fneg_f64(double %x) {
 ; CHECK-LABEL: name: test_fneg_f64
 ; CHECK: [[ARG:%[0-9]+]]:_(s64) = COPY $d0
@@ -1545,6 +1564,15 @@ define double @test_fneg_f64(double %x) {
   ret double %neg
 }
 
+define double @test_fneg_f64_fmf(double %x) {
+; CHECK-LABEL: name: test_fneg_f64
+; CHECK: [[ARG:%[0-9]+]]:_(s64) = COPY $d0
+; CHECK: [[RES:%[0-9]+]]:_(s64) = nnan ninf nsz arcp contract afn reassoc G_FNEG [[ARG]]
+; CHECK: $d0 = COPY [[RES]](s64)
+  %neg = fsub fast double -0.000000e+00, %x
+  ret double %neg
+}
+
 define void @test_trivial_inlineasm() {
 ; CHECK-LABEL: name: test_trivial_inlineasm
 ; CHECK: INLINEASM &wibble, 1