When constant double 0.0 is lowered, make sure 0 is copied directly from an
authorAkira Hatanaka <ahatanak@gmail.com>
Fri, 12 Aug 2011 18:09:59 +0000 (18:09 +0000)
committerAkira Hatanaka <ahatanak@gmail.com>
Fri, 12 Aug 2011 18:09:59 +0000 (18:09 +0000)
integer register to a floating point register. It is not valid to interpret
the value of a floating pointer register as part of a double precision
floating point value after a single precision floating point computational
or move instruction stores its result to the register.

- In the test case, the following code is generated before this patch is
  applied:
mtc1  $zero, $f2    ; unformatted copy to $f2
mov.s $f0, $f2      ; $f0 is in single format
sdc1  $f12, 0($sp)
mov.s $f1, $f2      ; $f1 is in single format
c.eq.d  $f12, $f0   ; $f0 cannot be interpreted as double

- The following code is generated after this patch is applied:
mtc1  $zero, $f0    ; unformatted copy to $f0
mtc1  $zero, $f1    ; unformatted copy to $f1
c.eq.d  $f12, $f0   ; $f0 can be interpreted as double

Bhanu Chetlapalli and Chris Dearman at MIPS technologies reported this bug and
provided the test case.

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

lib/Target/Mips/MipsISelDAGToDAG.cpp

index 90aaeb60d06fe77f32cef579067d01e49f8baaae..47015056e14f74c07fca44a7661fc9dfd916c944 100644 (file)
@@ -417,15 +417,8 @@ SDNode* MipsDAGToDAGISel::Select(SDNode *Node) {
       if (Node->getValueType(0) == MVT::f64 && CN->isExactlyValue(+0.0)) {
         SDValue Zero = CurDAG->getCopyFromReg(CurDAG->getEntryNode(), dl,
                                         Mips::ZERO, MVT::i32);
-        SDValue Undef = SDValue(
-          CurDAG->getMachineNode(TargetOpcode::IMPLICIT_DEF, dl, MVT::f64), 0);
-        SDNode *MTC = CurDAG->getMachineNode(Mips::MTC1, dl, MVT::f32, Zero);
-        SDValue I0 = CurDAG->getTargetInsertSubreg(Mips::sub_fpeven, dl,
-                            MVT::f64, Undef, SDValue(MTC, 0));
-        SDValue I1 = CurDAG->getTargetInsertSubreg(Mips::sub_fpodd, dl,
-                            MVT::f64, I0, SDValue(MTC, 0));
-        ReplaceUses(SDValue(Node, 0), I1);
-        return I1.getNode();
+        return CurDAG->getMachineNode(Mips::BuildPairF64, dl, MVT::f64, Zero,
+                                      Zero);
       }
       break;
     }