[PATCH] D49973: [LegalizeDAG] Fix FCOPYSIGN expansion

Lei Liu via Phabricator via llvm-commits llvm-commits at lists.llvm.org
Sun Jul 29 23:32:42 PDT 2018


lliu0 created this revision.
lliu0 added reviewers: MatzeB, ab, bogner.
Herald added a reviewer: javed.absar.
Herald added a subscriber: llvm-commits.

In expansion of FCOPYSIGN, the shift node is missing when the two operands of FCOPYSIGN are of the same size. We should always generate shift node (if the required shift bit is not zero) to put the sign bit into the right position, regardless of the size of underlying types.


Repository:
  rL LLVM

https://reviews.llvm.org/D49973

Files:
  lib/CodeGen/SelectionDAG/LegalizeDAG.cpp
  test/CodeGen/AArch64/fcopysign.ll


Index: test/CodeGen/AArch64/fcopysign.ll
===================================================================
--- test/CodeGen/AArch64/fcopysign.ll
+++ test/CodeGen/AArch64/fcopysign.ll
@@ -5,10 +5,12 @@
 
 declare fp128 @llvm.copysign.f128(fp128, fp128)
 
- at val = global double zeroinitializer, align 8
+ at val_float = global float zeroinitializer, align 4
+ at val_double = global double zeroinitializer, align 8
+ at val_fp128 = global fp128 zeroinitializer, align 16
 
 ; CHECK-LABEL: copysign0
-; CHECK: ldr [[REG:x[0-9]+]], [x8, :lo12:val]
+; CHECK: ldr [[REG:x[0-9]+]], [x8, :lo12:val_double]
 ; CHECK: and [[ANDREG:x[0-9]+]], [[REG]], #0x8000000000000000
 ; CHECK: lsr x[[LSRREGNUM:[0-9]+]], [[ANDREG]], #56
 ; CHECK: bfxil w[[LSRREGNUM]], w{{[0-9]+}}, #0, #7
@@ -16,8 +18,25 @@
 ; CHECK: ldr q{{[0-9]+}},
 define fp128 @copysign0() {
 entry:
-  %v = load double, double* @val, align 8
+  %v = load double, double* @val_double, align 8
   %conv = fpext double %v to fp128
   %call = tail call fp128 @llvm.copysign.f128(fp128 0xL00000000000000007FFF000000000000, fp128 %conv) #2
   ret fp128 %call
 }
+
+; CHECK-LABEL: copysign1
+; CHECK-DAG: ldr [[REG:q[0-9]+]], [x8, :lo12:val_fp128]
+; CHECK-DAG: ldr [[REG:w[0-9]+]], [x8, :lo12:val_float]
+; CHECK: and [[ANDREG:w[0-9]+]], [[REG]], #0x80000000
+; CHECK: lsr w[[LSRREGNUM:[0-9]+]], [[ANDREG]], #24
+; CHECK: bfxil w[[LSRREGNUM]], w{{[0-9]+}}, #0, #7
+; CHECK: strb w[[LSRREGNUM]],
+; CHECK: ldr q{{[0-9]+}},
+define fp128 at copysign1() {
+entry:
+  %v0 = load fp128, fp128* @val_fp128, align 16
+  %v1 = load float, float* @val_float, align 4
+  %conv = fpext float %v1 to fp128
+  %call = tail call fp128 @llvm.copysign.f128(fp128 %v0, fp128 %conv)
+  ret fp128 %call
+}
Index: lib/CodeGen/SelectionDAG/LegalizeDAG.cpp
===================================================================
--- lib/CodeGen/SelectionDAG/LegalizeDAG.cpp
+++ lib/CodeGen/SelectionDAG/LegalizeDAG.cpp
@@ -1489,24 +1489,20 @@
 
   // Get the signbit at the right position for MagAsInt.
   int ShiftAmount = SignAsInt.SignBit - MagAsInt.SignBit;
+  EVT ShiftVT = SignBit.getValueSizeInBits() > ClearedSign.getValueSizeInBits() ?
+                IntVT : MagVT;
+  if (SignBit.getValueSizeInBits() < ClearedSign.getValueSizeInBits()) {
+    SignBit = DAG.getNode(ISD::ZERO_EXTEND, DL, MagVT, SignBit);
+  }
+  if (ShiftAmount > 0) {
+    SDValue ShiftCnst = DAG.getConstant(ShiftAmount, DL, ShiftVT);
+    SignBit = DAG.getNode(ISD::SRL, DL, ShiftVT, SignBit, ShiftCnst);
+  } else if (ShiftAmount < 0) {
+    SDValue ShiftCnst = DAG.getConstant(-ShiftAmount, DL, ShiftVT);
+    SignBit = DAG.getNode(ISD::SHL, DL, ShiftVT, SignBit, ShiftCnst);
+  }
   if (SignBit.getValueSizeInBits() > ClearedSign.getValueSizeInBits()) {
-    if (ShiftAmount > 0) {
-      SDValue ShiftCnst = DAG.getConstant(ShiftAmount, DL, IntVT);
-      SignBit = DAG.getNode(ISD::SRL, DL, IntVT, SignBit, ShiftCnst);
-    } else if (ShiftAmount < 0) {
-      SDValue ShiftCnst = DAG.getConstant(-ShiftAmount, DL, IntVT);
-      SignBit = DAG.getNode(ISD::SHL, DL, IntVT, SignBit, ShiftCnst);
-    }
     SignBit = DAG.getNode(ISD::TRUNCATE, DL, MagVT, SignBit);
-  } else if (SignBit.getValueSizeInBits() < ClearedSign.getValueSizeInBits()) {
-    SignBit = DAG.getNode(ISD::ZERO_EXTEND, DL, MagVT, SignBit);
-    if (ShiftAmount > 0) {
-      SDValue ShiftCnst = DAG.getConstant(ShiftAmount, DL, MagVT);
-      SignBit = DAG.getNode(ISD::SRL, DL, MagVT, SignBit, ShiftCnst);
-    } else if (ShiftAmount < 0) {
-      SDValue ShiftCnst = DAG.getConstant(-ShiftAmount, DL, MagVT);
-      SignBit = DAG.getNode(ISD::SHL, DL, MagVT, SignBit, ShiftCnst);
-    }
   }
 
   // Store the part with the modified sign and convert back to float.


-------------- next part --------------
A non-text attachment was scrubbed...
Name: D49973.157918.patch
Type: text/x-patch
Size: 3733 bytes
Desc: not available
URL: <http://lists.llvm.org/pipermail/llvm-commits/attachments/20180730/ff9d343e/attachment.bin>


More information about the llvm-commits mailing list