[llvm] ffa2dce - [PowerPC] Fix FLT_ROUNDS_ on little endian

Qiu Chaofan via llvm-commits llvm-commits at lists.llvm.org
Wed Dec 2 01:16:51 PST 2020


Author: Qiu Chaofan
Date: 2020-12-02T17:16:32+08:00
New Revision: ffa2dce59070636e0d83d2797fb80c4ca2d7ea2d

URL: https://github.com/llvm/llvm-project/commit/ffa2dce59070636e0d83d2797fb80c4ca2d7ea2d
DIFF: https://github.com/llvm/llvm-project/commit/ffa2dce59070636e0d83d2797fb80c4ca2d7ea2d.diff

LOG: [PowerPC] Fix FLT_ROUNDS_ on little endian

In lowering of FLT_ROUNDS_, FPSCR content will be moved into FP register
and then GPR, and then truncated into word.

For subtargets without direct move support, it will store and then load.
The load address needs adjustment (+4) only on big-endian targets. This
patch fixes it on using generic opcodes on little-endian and subtargets
with direct-move.

Reviewed By: steven.zhang

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

Added: 
    

Modified: 
    llvm/lib/Target/PowerPC/PPCISelLowering.cpp
    llvm/test/CodeGen/PowerPC/frounds.ll

Removed: 
    


################################################################################
diff  --git a/llvm/lib/Target/PowerPC/PPCISelLowering.cpp b/llvm/lib/Target/PowerPC/PPCISelLowering.cpp
index 1864dc7f3113..f9f84aa668bc 100644
--- a/llvm/lib/Target/PowerPC/PPCISelLowering.cpp
+++ b/llvm/lib/Target/PowerPC/PPCISelLowering.cpp
@@ -8975,16 +8975,24 @@ SDValue PPCTargetLowering::LowerFLT_ROUNDS_(SDValue Op,
   SDValue MFFS = DAG.getNode(PPCISD::MFFS, dl, {MVT::f64, MVT::Other}, Chain);
   Chain = MFFS.getValue(1);
 
-  // Save FP register to stack slot
-  int SSFI = MF.getFrameInfo().CreateStackObject(8, Align(8), false);
-  SDValue StackSlot = DAG.getFrameIndex(SSFI, PtrVT);
-  Chain = DAG.getStore(Chain, dl, MFFS, StackSlot, MachinePointerInfo());
-
-  // Load FP Control Word from low 32 bits of stack slot.
-  SDValue Four = DAG.getConstant(4, dl, PtrVT);
-  SDValue Addr = DAG.getNode(ISD::ADD, dl, PtrVT, StackSlot, Four);
-  SDValue CWD = DAG.getLoad(MVT::i32, dl, Chain, Addr, MachinePointerInfo());
-  Chain = CWD.getValue(1);
+  SDValue CWD;
+  if (isTypeLegal(MVT::i64)) {
+    CWD = DAG.getNode(ISD::TRUNCATE, dl, MVT::i32,
+                      DAG.getNode(ISD::BITCAST, dl, MVT::i64, MFFS));
+  } else {
+    // Save FP register to stack slot
+    int SSFI = MF.getFrameInfo().CreateStackObject(8, Align(8), false);
+    SDValue StackSlot = DAG.getFrameIndex(SSFI, PtrVT);
+    Chain = DAG.getStore(Chain, dl, MFFS, StackSlot, MachinePointerInfo());
+
+    // Load FP Control Word from low 32 bits of stack slot.
+    assert(hasBigEndianPartOrdering(MVT::i64, MF.getDataLayout()) &&
+           "Stack slot adjustment is valid only on big endian subtargets!");
+    SDValue Four = DAG.getConstant(4, dl, PtrVT);
+    SDValue Addr = DAG.getNode(ISD::ADD, dl, PtrVT, StackSlot, Four);
+    CWD = DAG.getLoad(MVT::i32, dl, Chain, Addr, MachinePointerInfo());
+    Chain = CWD.getValue(1);
+  }
 
   // Transform as necessary
   SDValue CWD1 =

diff  --git a/llvm/test/CodeGen/PowerPC/frounds.ll b/llvm/test/CodeGen/PowerPC/frounds.ll
index df339ceb3a09..277423f6e2b5 100644
--- a/llvm/test/CodeGen/PowerPC/frounds.ll
+++ b/llvm/test/CodeGen/PowerPC/frounds.ll
@@ -42,7 +42,7 @@ define i32 @foo() {
 ; PPC64LE:       # %bb.0: # %entry
 ; PPC64LE-NEXT:    mffs 0
 ; PPC64LE-NEXT:    stfd 0, -16(1)
-; PPC64LE-NEXT:    lwz 3, -12(1)
+; PPC64LE-NEXT:    lwz 3, -16(1)
 ; PPC64LE-NEXT:    not 4, 3
 ; PPC64LE-NEXT:    clrlwi 3, 3, 30
 ; PPC64LE-NEXT:    rlwinm 4, 4, 31, 31, 31
@@ -54,8 +54,7 @@ define i32 @foo() {
 ; DM-LABEL: foo:
 ; DM:       # %bb.0: # %entry
 ; DM-NEXT:    mffs 0
-; DM-NEXT:    stfd 0, -16(1)
-; DM-NEXT:    lwz 3, -12(1)
+; DM-NEXT:    mffprd 3, 0
 ; DM-NEXT:    not 4, 3
 ; DM-NEXT:    clrlwi 3, 3, 30
 ; DM-NEXT:    rlwinm 4, 4, 31, 31, 31


        


More information about the llvm-commits mailing list