This is the mail archive of the libc-alpha@sourceware.org mailing list for the glibc project.


Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]
Other format: [Raw text]

Fix bad shift in soft-fp (bug 7006)


glibc bug 7006 describes a soft-fp issue where a shift count of 0
passed to _FP_FRAC_SRS_2 results in a shift by _FP_W_TYPE_SIZE
(undefined behavior in C).

Neither Richard Henderson nor I have, in the discussions in that bug,
found any cases where a shift count of 0 can actually be passed to
this macro.  However, the bug report from November 2008 says "I hit
this bug two years ago" and, if in fact that refers to February 2006
or earlier, it appears that the old version of _FP_TO_INT, removed by
my speedup patch
<http://sourceware.org/ml/libc-alpha/2006-02/msg00028.html>, could do
such a shift.

It seems reasonable to interpret the glibc bug as concerning all such
cases of invalid C shifts arising from shift counts of 0 passed to
shift macros in soft-fp (there are several definitions of one or other
of those macros where passing a shift of 0 to the macro would result
in a bad C shift).  Examining the existing code, I have found only one
such case, in _FP_FROM_INT.  This turns out to have an existing GCC
bug report for its consequences for soft-fp used to implement
__float128 support in libgcc:
<http://gcc.gnu.org/bugzilla/show_bug.cgi?id=53317>.

My conclusion for this glibc bug is that it's best to disallow shift
counts of 0 for these soft-fp macros, since almost all calls to them
cannot have such a count, but it may not always be possible for GCC to
optimize away any workaround to avoid shifting by _FP_W_TYPE_SIZE in
cases where the shift count is not a constant.  This patch accordingly
changes the one case I found could use a shift count of 0 to check at
the call site.

Tested by GCC bootstrap on x86_64 in conjunction with a soft-fp update
in libgcc and a GCC testcase for the __float128 bug.  I'll commit that
GCC patch subject to the glibc soft-fp change being agreed.

I'd welcome review of the conclusion that none of the other calls to
the shift macros in soft-fp can actually have an argument of 0, as
well as of this specific patch.

2013-06-18  Joseph Myers  <joseph@codesourcery.com>

	[BZ #7006]
	* soft-fp/op-common.h (_FP_FROM_INT): Do not call _FP_FRAC_SLL
	with a shift of 0 bits.

diff --git a/soft-fp/op-common.h b/soft-fp/op-common.h
index ce472e0..c4acb99 100644
--- a/soft-fp/op-common.h
+++ b/soft-fp/op-common.h
@@ -1163,8 +1163,9 @@ do {									\
 	  {								     \
 	    /* Exactly representable; shift left.  */			     \
 	    _FP_FRAC_DISASSEMBLE_##wc(X, ur_, rsize);			     \
-	    _FP_FRAC_SLL_##wc(X, (_FP_EXPBIAS_##fs			     \
-				  + _FP_FRACBITS_##fs - 1 - X##_e));	     \
+	    if (_FP_EXPBIAS_##fs + _FP_FRACBITS_##fs - 1 - X##_e > 0)	     \
+	      _FP_FRAC_SLL_##wc(X, (_FP_EXPBIAS_##fs			     \
+				    + _FP_FRACBITS_##fs - 1 - X##_e));	     \
 	  }								     \
 	else								     \
 	  {								     \

-- 
Joseph S. Myers
joseph@codesourcery.com


Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]