[compiler-rt] r371003 - Revert "Revert "[builtins] Rounding mode support for addxf3/subxf3""

Yi Kong via llvm-commits llvm-commits at lists.llvm.org
Wed Sep 4 18:05:06 PDT 2019


Author: kongyi
Date: Wed Sep  4 18:05:05 2019
New Revision: 371003

URL: http://llvm.org/viewvc/llvm-project?rev=371003&view=rev
Log:
Revert "Revert "[builtins] Rounding mode support for addxf3/subxf3""

Test failure fixed.

This reverts commit e204d244badb2e9765a1020f41c773f63da208f4.

Added:
    compiler-rt/trunk/lib/builtins/aarch64/fp_mode.c
    compiler-rt/trunk/lib/builtins/arm/fp_mode.c
    compiler-rt/trunk/lib/builtins/fp_mode.c
    compiler-rt/trunk/lib/builtins/fp_mode.h
Modified:
    compiler-rt/trunk/lib/builtins/CMakeLists.txt
    compiler-rt/trunk/lib/builtins/adddf3.c
    compiler-rt/trunk/lib/builtins/addsf3.c
    compiler-rt/trunk/lib/builtins/addtf3.c
    compiler-rt/trunk/lib/builtins/fp_add_impl.inc
    compiler-rt/trunk/lib/builtins/subdf3.c
    compiler-rt/trunk/lib/builtins/subsf3.c
    compiler-rt/trunk/lib/builtins/subtf3.c
    compiler-rt/trunk/test/builtins/Unit/addtf3_test.c
    compiler-rt/trunk/test/builtins/Unit/subtf3_test.c

Modified: compiler-rt/trunk/lib/builtins/CMakeLists.txt
URL: http://llvm.org/viewvc/llvm-project/compiler-rt/trunk/lib/builtins/CMakeLists.txt?rev=371003&r1=371002&r2=371003&view=diff
==============================================================================
--- compiler-rt/trunk/lib/builtins/CMakeLists.txt (original)
+++ compiler-rt/trunk/lib/builtins/CMakeLists.txt Wed Sep  4 18:05:05 2019
@@ -97,6 +97,7 @@ set(GENERIC_SOURCES
   floatunsisf.c
   floatuntidf.c
   floatuntisf.c
+  fp_mode.c
   int_util.c
   lshrdi3.c
   lshrti3.c
@@ -306,6 +307,7 @@ set(i386_SOURCES ${i386_SOURCES} ${x86_A
 set(i686_SOURCES ${i686_SOURCES} ${x86_ARCH_SOURCES})
 
 set(arm_SOURCES
+  arm/fp_mode.c
   arm/bswapdi2.S
   arm/bswapsi2.S
   arm/clzdi2.S
@@ -451,6 +453,7 @@ endif()
 set(aarch64_SOURCES
   ${GENERIC_TF_SOURCES}
   ${GENERIC_SOURCES}
+  aarch64/fp_mode.c
 )
 
 if (MINGW)

Added: compiler-rt/trunk/lib/builtins/aarch64/fp_mode.c
URL: http://llvm.org/viewvc/llvm-project/compiler-rt/trunk/lib/builtins/aarch64/fp_mode.c?rev=371003&view=auto
==============================================================================
--- compiler-rt/trunk/lib/builtins/aarch64/fp_mode.c (added)
+++ compiler-rt/trunk/lib/builtins/aarch64/fp_mode.c Wed Sep  4 18:05:05 2019
@@ -0,0 +1,59 @@
+//===----- lib/aarch64/fp_mode.c - Floaing-point mode utilities ---*- C -*-===//
+//
+// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
+// See https://llvm.org/LICENSE.txt for license information.
+// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
+//
+//===----------------------------------------------------------------------===//
+
+#include <stdint.h>
+
+#include "../fp_mode.h"
+
+#define AARCH64_TONEAREST  0x0
+#define AARCH64_UPWARD     0x1
+#define AARCH64_DOWNWARD   0x2
+#define AARCH64_TOWARDZERO 0x3
+#define AARCH64_RMODE_MASK (AARCH64_TONEAREST | AARCH64_UPWARD | \
+                            AARCH64_DOWNWARD | AARCH64_TOWARDZERO)
+#define AARCH64_RMODE_SHIFT 22
+
+#define AARCH64_INEXACT     0x10
+
+#ifndef __ARM_FP
+// For soft float targets, allow changing rounding mode by overriding the weak
+// __aarch64_fe_default_rmode symbol.
+FE_ROUND_MODE __attribute__((weak)) __aarch64_fe_default_rmode = FE_TONEAREST;
+#endif
+
+FE_ROUND_MODE __fe_getround() {
+#ifdef __ARM_FP
+  uint64_t fpcr;
+  __asm__ __volatile__("mrs  %0, fpcr" : "=r" (fpcr));
+  fpcr = fpcr >> AARCH64_RMODE_SHIFT & AARCH64_RMODE_MASK;
+  switch (fpcr) {
+    case AARCH64_UPWARD:
+      return FE_UPWARD;
+    case AARCH64_DOWNWARD:
+      return FE_DOWNWARD;
+    case AARCH64_TOWARDZERO:
+      return FE_TOWARDZERO;
+    case AARCH64_TONEAREST:
+    default:
+      return FE_TONEAREST;
+  }
+#else
+  return __aarch64_fe_default_rmode;
+#endif
+}
+
+int __fe_raise_inexact() {
+#ifdef __ARM_FP
+  uint64_t fpsr;
+  __asm__ __volatile__("mrs  %0, fpsr" : "=r" (fpsr));
+  __asm__ __volatile__("msr  fpsr, %0" : : "ri" (fpsr | AARCH64_INEXACT));
+  return 0;
+#else
+  return 0;
+#endif
+}

Modified: compiler-rt/trunk/lib/builtins/adddf3.c
URL: http://llvm.org/viewvc/llvm-project/compiler-rt/trunk/lib/builtins/adddf3.c?rev=371003&r1=371002&r2=371003&view=diff
==============================================================================
--- compiler-rt/trunk/lib/builtins/adddf3.c (original)
+++ compiler-rt/trunk/lib/builtins/adddf3.c Wed Sep  4 18:05:05 2019
@@ -6,8 +6,7 @@
 //
 //===----------------------------------------------------------------------===//
 //
-// This file implements double-precision soft-float addition with the IEEE-754
-// default rounding (to nearest, ties to even).
+// This file implements double-precision soft-float addition.
 //
 //===----------------------------------------------------------------------===//
 

Modified: compiler-rt/trunk/lib/builtins/addsf3.c
URL: http://llvm.org/viewvc/llvm-project/compiler-rt/trunk/lib/builtins/addsf3.c?rev=371003&r1=371002&r2=371003&view=diff
==============================================================================
--- compiler-rt/trunk/lib/builtins/addsf3.c (original)
+++ compiler-rt/trunk/lib/builtins/addsf3.c Wed Sep  4 18:05:05 2019
@@ -6,8 +6,7 @@
 //
 //===----------------------------------------------------------------------===//
 //
-// This file implements single-precision soft-float addition with the IEEE-754
-// default rounding (to nearest, ties to even).
+// This file implements single-precision soft-float addition.
 //
 //===----------------------------------------------------------------------===//
 

Modified: compiler-rt/trunk/lib/builtins/addtf3.c
URL: http://llvm.org/viewvc/llvm-project/compiler-rt/trunk/lib/builtins/addtf3.c?rev=371003&r1=371002&r2=371003&view=diff
==============================================================================
--- compiler-rt/trunk/lib/builtins/addtf3.c (original)
+++ compiler-rt/trunk/lib/builtins/addtf3.c Wed Sep  4 18:05:05 2019
@@ -6,8 +6,7 @@
 //
 //===----------------------------------------------------------------------===//
 //
-// This file implements quad-precision soft-float addition with the IEEE-754
-// default rounding (to nearest, ties to even).
+// This file implements quad-precision soft-float addition.
 //
 //===----------------------------------------------------------------------===//
 

Added: compiler-rt/trunk/lib/builtins/arm/fp_mode.c
URL: http://llvm.org/viewvc/llvm-project/compiler-rt/trunk/lib/builtins/arm/fp_mode.c?rev=371003&view=auto
==============================================================================
--- compiler-rt/trunk/lib/builtins/arm/fp_mode.c (added)
+++ compiler-rt/trunk/lib/builtins/arm/fp_mode.c Wed Sep  4 18:05:05 2019
@@ -0,0 +1,59 @@
+//===----- lib/arm/fp_mode.c - Floaing-point mode utilities -------*- C -*-===//
+//
+// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
+// See https://llvm.org/LICENSE.txt for license information.
+// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
+//
+//===----------------------------------------------------------------------===//
+
+#include <stdint.h>
+
+#include "../fp_mode.h"
+
+#define ARM_TONEAREST  0x0
+#define ARM_UPWARD     0x1
+#define ARM_DOWNWARD   0x2
+#define ARM_TOWARDZERO 0x3
+#define ARM_RMODE_MASK (ARM_TONEAREST | ARM_UPWARD | \
+                        ARM_DOWNWARD | ARM_TOWARDZERO)
+#define ARM_RMODE_SHIFT 22
+
+#define ARM_INEXACT     0x1000
+
+#ifndef __ARM_FP
+// For soft float targets, allow changing rounding mode by overriding the weak
+// __arm_fe_default_rmode symbol.
+FE_ROUND_MODE __attribute__((weak)) __arm_fe_default_rmode = FE_TONEAREST;
+#endif
+
+FE_ROUND_MODE __fe_getround() {
+#ifdef __ARM_FP
+  uint32_t fpscr;
+  __asm__ __volatile__("vmrs  %0, fpscr" : "=r" (fpscr));
+  fpscr = fpscr >> ARM_RMODE_SHIFT & ARM_RMODE_MASK;
+  switch (fpscr) {
+    case ARM_UPWARD:
+      return FE_UPWARD;
+    case ARM_DOWNWARD:
+      return FE_DOWNWARD;
+    case ARM_TOWARDZERO:
+      return FE_TOWARDZERO;
+    case ARM_TONEAREST:
+    default:
+      return FE_TONEAREST;
+  }
+#else
+  return __arm_fe_default_rmode;
+#endif
+}
+
+int __fe_raise_inexact() {
+#ifdef __ARM_FP
+  uint32_t fpscr;
+  __asm__ __volatile__("vmrs  %0, fpscr" : "=r" (fpscr));
+  __asm__ __volatile__("vmsr  fpscr, %0" : : "ri" (fpscr | ARM_INEXACT));
+  return 0;
+#else
+  return 0;
+#endif
+}

Modified: compiler-rt/trunk/lib/builtins/fp_add_impl.inc
URL: http://llvm.org/viewvc/llvm-project/compiler-rt/trunk/lib/builtins/fp_add_impl.inc?rev=371003&r1=371002&r2=371003&view=diff
==============================================================================
--- compiler-rt/trunk/lib/builtins/fp_add_impl.inc (original)
+++ compiler-rt/trunk/lib/builtins/fp_add_impl.inc Wed Sep  4 18:05:05 2019
@@ -12,6 +12,7 @@
 //===----------------------------------------------------------------------===//
 
 #include "fp_lib.h"
+#include "fp_mode.h"
 
 static __inline fp_t __addXf3__(fp_t a, fp_t b) {
   rep_t aRep = toRep(a);
@@ -149,9 +150,23 @@ static __inline fp_t __addXf3__(fp_t a,
 
   // Perform the final rounding.  The result may overflow to infinity, but
   // that is the correct result in that case.
-  if (roundGuardSticky > 0x4)
-    result++;
-  if (roundGuardSticky == 0x4)
-    result += result & 1;
+  switch (__fe_getround()) {
+  case FE_TONEAREST:
+    if (roundGuardSticky > 0x4)
+      result++;
+    if (roundGuardSticky == 0x4)
+      result += result & 1;
+    break;
+  case FE_DOWNWARD:
+    if (resultSign && roundGuardSticky) result++;
+    break;
+  case FE_UPWARD:
+    if (!resultSign && roundGuardSticky) result++;
+    break;
+  case FE_TOWARDZERO:
+    break;
+  }
+  if (roundGuardSticky)
+    __fe_raise_inexact();
   return fromRep(result);
 }

Added: compiler-rt/trunk/lib/builtins/fp_mode.c
URL: http://llvm.org/viewvc/llvm-project/compiler-rt/trunk/lib/builtins/fp_mode.c?rev=371003&view=auto
==============================================================================
--- compiler-rt/trunk/lib/builtins/fp_mode.c (added)
+++ compiler-rt/trunk/lib/builtins/fp_mode.c Wed Sep  4 18:05:05 2019
@@ -0,0 +1,24 @@
+//===----- lib/fp_mode.c - Floaing-point environment mode utilities --C -*-===//
+//
+// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
+// See https://llvm.org/LICENSE.txt for license information.
+// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
+//
+//===----------------------------------------------------------------------===//
+//
+// This file provides a default implementation of fp_mode.h for architectures
+// that does not support or does not have an implementation of floating point
+// environment mode.
+//
+//===----------------------------------------------------------------------===//
+
+#include "fp_mode.h"
+
+// IEEE-754 default rounding (to nearest, ties to even).
+FE_ROUND_MODE __fe_getround() {
+  return FE_TONEAREST;
+}
+
+int __fe_raise_inexact() {
+  return 0;
+}

Added: compiler-rt/trunk/lib/builtins/fp_mode.h
URL: http://llvm.org/viewvc/llvm-project/compiler-rt/trunk/lib/builtins/fp_mode.h?rev=371003&view=auto
==============================================================================
--- compiler-rt/trunk/lib/builtins/fp_mode.h (added)
+++ compiler-rt/trunk/lib/builtins/fp_mode.h Wed Sep  4 18:05:05 2019
@@ -0,0 +1,29 @@
+//===----- lib/fp_mode.h - Floaing-point environment mode utilities --C -*-===//
+//
+// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
+// See https://llvm.org/LICENSE.txt for license information.
+// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
+//
+//===----------------------------------------------------------------------===//
+//
+// This file is not part of the interface of this library.
+//
+// This file defines an interface for accessing hardware floating point
+// environment mode.
+//
+//===----------------------------------------------------------------------===//
+
+#ifndef FP_MODE
+#define FP_MODE
+
+typedef enum {
+  FE_TONEAREST,
+  FE_DOWNWARD,
+  FE_UPWARD,
+  FE_TOWARDZERO
+} FE_ROUND_MODE;
+
+FE_ROUND_MODE __fe_getround();
+int __fe_raise_inexact();
+
+#endif // FP_MODE_H

Modified: compiler-rt/trunk/lib/builtins/subdf3.c
URL: http://llvm.org/viewvc/llvm-project/compiler-rt/trunk/lib/builtins/subdf3.c?rev=371003&r1=371002&r2=371003&view=diff
==============================================================================
--- compiler-rt/trunk/lib/builtins/subdf3.c (original)
+++ compiler-rt/trunk/lib/builtins/subdf3.c Wed Sep  4 18:05:05 2019
@@ -6,8 +6,7 @@
 //
 //===----------------------------------------------------------------------===//
 //
-// This file implements double-precision soft-float subtraction with the
-// IEEE-754 default rounding (to nearest, ties to even).
+// This file implements double-precision soft-float subtraction.
 //
 //===----------------------------------------------------------------------===//
 

Modified: compiler-rt/trunk/lib/builtins/subsf3.c
URL: http://llvm.org/viewvc/llvm-project/compiler-rt/trunk/lib/builtins/subsf3.c?rev=371003&r1=371002&r2=371003&view=diff
==============================================================================
--- compiler-rt/trunk/lib/builtins/subsf3.c (original)
+++ compiler-rt/trunk/lib/builtins/subsf3.c Wed Sep  4 18:05:05 2019
@@ -6,8 +6,7 @@
 //
 //===----------------------------------------------------------------------===//
 //
-// This file implements single-precision soft-float subtraction with the
-// IEEE-754 default rounding (to nearest, ties to even).
+// This file implements single-precision soft-float subtraction.
 //
 //===----------------------------------------------------------------------===//
 

Modified: compiler-rt/trunk/lib/builtins/subtf3.c
URL: http://llvm.org/viewvc/llvm-project/compiler-rt/trunk/lib/builtins/subtf3.c?rev=371003&r1=371002&r2=371003&view=diff
==============================================================================
--- compiler-rt/trunk/lib/builtins/subtf3.c (original)
+++ compiler-rt/trunk/lib/builtins/subtf3.c Wed Sep  4 18:05:05 2019
@@ -6,8 +6,7 @@
 //
 //===----------------------------------------------------------------------===//
 //
-// This file implements quad-precision soft-float subtraction with the
-// IEEE-754 default rounding (to nearest, ties to even).
+// This file implements quad-precision soft-float subtraction.
 //
 //===----------------------------------------------------------------------===//
 

Modified: compiler-rt/trunk/test/builtins/Unit/addtf3_test.c
URL: http://llvm.org/viewvc/llvm-project/compiler-rt/trunk/test/builtins/Unit/addtf3_test.c?rev=371003&r1=371002&r2=371003&view=diff
==============================================================================
--- compiler-rt/trunk/test/builtins/Unit/addtf3_test.c (original)
+++ compiler-rt/trunk/test/builtins/Unit/addtf3_test.c Wed Sep  4 18:05:05 2019
@@ -11,11 +11,12 @@
 //
 //===----------------------------------------------------------------------===//
 
-#include "int_lib.h"
+#include <fenv.h>
 #include <stdio.h>
 
 #if __LDBL_MANT_DIG__ == 113
 
+#include "int_lib.h"
 #include "fp_test.h"
 
 // Returns: a + b
@@ -74,6 +75,36 @@ int main()
                      UINT64_C(0x61e58dd6c51eb77c)))
         return 1;
 
+#if (defined(__arm__) || defined(__aarch64__)) && defined(__ARM_FP)
+    // Rounding mode tests on supported architectures
+    const long double m = 1234.0L, n = 0.01L;
+
+    fesetround(FE_UPWARD);
+    if (test__addtf3(m, n,
+                     UINT64_C(0x40093480a3d70a3d),
+                     UINT64_C(0x70a3d70a3d70a3d8)))
+        return 1;
+
+    fesetround(FE_DOWNWARD);
+    if (test__addtf3(m, n,
+                     UINT64_C(0x40093480a3d70a3d),
+                     UINT64_C(0x70a3d70a3d70a3d7)))
+        return 1;
+
+
+    fesetround(FE_TOWARDZERO);
+    if (test__addtf3(m, n,
+                     UINT64_C(0x40093480a3d70a3d),
+                     UINT64_C(0x70a3d70a3d70a3d7)))
+        return 1;
+
+    fesetround(FE_TONEAREST);
+    if (test__addtf3(m, n,
+                     UINT64_C(0x40093480a3d70a3d),
+                     UINT64_C(0x70a3d70a3d70a3d7)))
+        return 1;
+#endif
+
 #else
     printf("skipped\n");
 

Modified: compiler-rt/trunk/test/builtins/Unit/subtf3_test.c
URL: http://llvm.org/viewvc/llvm-project/compiler-rt/trunk/test/builtins/Unit/subtf3_test.c?rev=371003&r1=371002&r2=371003&view=diff
==============================================================================
--- compiler-rt/trunk/test/builtins/Unit/subtf3_test.c (original)
+++ compiler-rt/trunk/test/builtins/Unit/subtf3_test.c Wed Sep  4 18:05:05 2019
@@ -11,6 +11,7 @@
 //
 //===----------------------------------------------------------------------===//
 
+#include <fenv.h>
 #include <stdio.h>
 
 #if __LDBL_MANT_DIG__ == 113
@@ -67,6 +68,35 @@ int main()
                      UINT64_C(0xa44a7bca780a166c)))
         return 1;
 
+#if (defined(__arm__) || defined(__aarch64__)) && defined(__ARM_FP)
+    // Rounding mode tests on supported architectures
+    const long double m = 1234.02L, n = 0.01L;
+
+    fesetround(FE_UPWARD);
+    if (test__subtf3(m, n,
+                     UINT64_C(0x40093480a3d70a3d),
+                     UINT64_C(0x70a3d70a3d70a3d7)))
+        return 1;
+
+    fesetround(FE_DOWNWARD);
+    if (test__subtf3(m, n,
+                     UINT64_C(0x40093480a3d70a3d),
+                     UINT64_C(0x70a3d70a3d70a3d6)))
+        return 1;
+
+    fesetround(FE_TOWARDZERO);
+    if (test__subtf3(m, n,
+                     UINT64_C(0x40093480a3d70a3d),
+                     UINT64_C(0x70a3d70a3d70a3d6)))
+        return 1;
+
+    fesetround(FE_TONEAREST);
+    if (test__subtf3(m, n,
+                     UINT64_C(0x40093480a3d70a3d),
+                     UINT64_C(0x70a3d70a3d70a3d7)))
+        return 1;
+#endif
+
 #else
     printf("skipped\n");
 




More information about the llvm-commits mailing list