[Bug target/78857] New: S390: Do not use load-and-test floating-point instruction to compare against 0.0 as SNaN is converted to QNaN.

2016-12-19 Thread stli at linux dot vnet.ibm.com
https://gcc.gnu.org/bugzilla/show_bug.cgi?id=78857

Bug ID: 78857
   Summary: S390: Do not use load-and-test floating-point
instruction to compare against 0.0 as SNaN is
converted to QNaN.
   Product: gcc
   Version: unknown
Status: UNCONFIRMED
  Severity: normal
  Priority: P3
 Component: target
  Assignee: unassigned at gcc dot gnu.org
  Reporter: stli at linux dot vnet.ibm.com
  Target Milestone: ---
Target: S390

On s390, a comparison of e.g. a double value against 0.0 is done with ltdbr 
(load and test long BFP) instruction. If the value is a SNaN, this instruction
converts it to QNaN. This differs to a comparison with cdbr (compare long BFP)
instruction, which keeps the SNaN.
Thus, the usage of load-and-test instruction is not allowed, if the value in
the resulting register is used afterwards.

As information:
This leads to glibc "math/test-double" / "math/test-idouble" test failures
where pow is called with x=1.0 and y=SNaN.
The pow function performs a test against zero and y is later used to determine
the return value:
...
if (y == 0)
  return 1.0;
...
if (...)
  return x == 1.0 && !issignaling (y) ? 1.0 : y + y;
...

[Bug target/80080] New: S390: Isses with emitted cs-instructions for __atomic builtins.

2017-03-17 Thread stli at linux dot vnet.ibm.com
https://gcc.gnu.org/bugzilla/show_bug.cgi?id=80080

Bug ID: 80080
   Summary: S390: Isses with emitted cs-instructions for __atomic
builtins.
   Product: gcc
   Version: 7.0
Status: UNCONFIRMED
  Severity: normal
  Priority: P3
 Component: target
  Assignee: unassigned at gcc dot gnu.org
  Reporter: stli at linux dot vnet.ibm.com
CC: krebbel at gcc dot gnu.org
  Target Milestone: ---
Target: S390

For s390, I am now using the c11 atomic builtins in glibc.
There are now some issues with the emitted cs-instructions.
If __atomic_compare_exchange_n is used within a condition for if/while,
it is sometimes not using the condition code directly to jump away.
Instead it extracts the condition code to a general register via ipm followed
by
further instructions in order to compare it. Afterwards it jumps according to
this comparison.

int foo1 (int *mem)
{
  int val, newval;
  val = __atomic_load_n (mem, __ATOMIC_RELAXED);
  do
{
  newval = val | 123;
}
  while (!__atomic_compare_exchange_n (mem, &val, newval, 1, __ATOMIC_ACQUIRE,
   __ATOMIC_RELAXED));

  /*
 :
   0:   58 10 20 00 l   %r1,0(%r2)
   4:   18 31   lr  %r3,%r1
   6:   a5 3b 00 7b oill%r3,123
   a:   ba 13 20 00 cs  %r1,%r3,0(%r2)
   e:   b2 22 00 30 ipm %r3
  12:   8a 30 00 1c sra %r3,28
  16:   ec 36 ff f7 00 7e   cijne   %r3,0,4 
  1c:   a7 29 00 00 lghi%r2,0
  20:   07 fe   br  %r14
  22:   07 07   nopr%r7
  24:   07 07   nopr%r7
  26:   07 07   nopr%r7
   */
  return 0;
}



For __atomic_exchange_n, s390 has no special instruction and thus a cs-loop is
used. An extra register is needed to save the old-value instead of using the
"old"-register of cs-instruction which is updated if the new value is not
stored
to memory. This extra register is reloaded in every loop.

extern int bar (int *mem);
int foo2 (int *mem)
{
  int old = __atomic_exchange_n (mem, 0, __ATOMIC_ACQUIRE);
  if (old >= 2)
return bar (mem);

  /*
0028 :
  28:   a7 48 00 00 lhi %r4,0
  2c:   58 10 20 00 l   %r1,0(%r2)
  30:   18 31   lr  %r3,%r1
  32:   ba 14 20 00 cs  %r1,%r4,0(%r2)
  36:   a7 74 ff fd jne 30 
  3a:   ec 3c 00 06 01 7e   cijnh   %r3,1,46 
  40:   c0 f4 00 00 00 00   jg  40 
42: R_390_PC32DBL   bar+0x2
  46:   a7 29 00 00 lghi%r2,0
  4a:   07 fe   br  %r14
  4c:   07 07   nopr%r7
  4e:   07 07   nopr%r7
   */
  return 0;
}

In case of exchanging to a zero value, like above, the load-and-and instruction
can be used. Then only one register is needed for the new and old value and
there is no loop.


If the exchanged memory is a global variable, the address of it is loaded
within the loop instead of before the loop.

extern int foo3_mem;
int foo3 (void)
{
  return __atomic_exchange_n (&foo3_mem, 5, __ATOMIC_ACQUIRE);

  /*
0050 :
  50:   c4 1d 00 00 00 00   lrl %r1,50 
52: R_390_PC32DBL   foo3_mem+0x2
  56:   a7 38 00 05 lhi %r3,5
  5a:   18 21   lr  %r2,%r1
  5c:   c0 40 00 00 00 00   larl%r4,5c 
5e: R_390_PC32DBL   foo3_mem+0x2
  62:   ba 13 40 00 cs  %r1,%r3,0(%r4)
  66:   a7 74 ff fa jne 5a 
  6a:   b9 14 00 22 lgfr%r2,%r2
  6e:   07 fe   br  %r14
   */
}

[Bug target/78857] S390: Do not use load-and-test floating-point instruction to compare against 0.0 as SNaN is converted to QNaN.

2017-03-21 Thread stli at linux dot vnet.ibm.com
https://gcc.gnu.org/bugzilla/show_bug.cgi?id=78857

stli at linux dot vnet.ibm.com  changed:

   What|Removed |Added

 Status|RESOLVED|VERIFIED

--- Comment #3 from stli at linux dot vnet.ibm.com  ---
This fixes the mentioned compare against zero in pow function.
Thanks.

[Bug other/77894] New: Enable GNU indirect function support by default as it will be used in glibc.

2016-10-07 Thread stli at linux dot vnet.ibm.com
https://gcc.gnu.org/bugzilla/show_bug.cgi?id=77894

Bug ID: 77894
   Summary: Enable GNU indirect function support by default as it
will be used in glibc.
   Product: gcc
   Version: unknown
Status: UNCONFIRMED
  Severity: normal
  Priority: P3
 Component: other
  Assignee: unassigned at gcc dot gnu.org
  Reporter: stli at linux dot vnet.ibm.com
  Target Milestone: ---

Starting with glibc-commits "Add configure check to test if gcc supports
attribute ifunc."
(https://sourceware.org/git/?p=glibc.git;a=commit;h=022dfdce000374b60aadfb0a5ed9a5c4c1dbd29b),
"Use gcc attribute ifunc in libc_ifunc macro instead of inline assembly due to
false... "
(https://sourceware.org/git/?p=glibc.git;a=commit;h=00980d845f8f2ec3ed4ad161a1e5b97704be1929)
and further, for glibc with multi-arch support it is recommended to use a GCC
which has been built with support for GNU indirect functions. This ensures that
correct debugging information is generated for functions selected by IFUNC
resolvers. This support can either be enabled by configuring GCC with
'--enable-gnu-indirect-function', or by enabling it by default by setting
'default_gnu_indirect_function' variable for a particular architecture in the
GCC source file 'gcc/config.gcc'.

Currently GNU indirect function support is only enabled by default for few
configurations like intel and s390. Please enable it by default for other
architectures, too. E.g. according to the rpm-spec file fedora/rhel is
configuring gcc with --enable-gnu-indirect-function for the following
architectures: %{ix86} x86_64 ppc ppc64 ppc64le ppc64p7 s390 s390x %{arm}
aarch64.

Perhaps a configure check could test the presence of the non-standard gnu ifunc
support in the assembler, linker and dynamic linker and could automatically
dis/enable the support. But this behaviour should be discussed by the gcc
maintainers.

[Bug target/77918] New: S390: Floating point comparisons don't raise invalid for unordered opperands.

2016-10-10 Thread stli at linux dot vnet.ibm.com
https://gcc.gnu.org/bugzilla/show_bug.cgi?id=77918

Bug ID: 77918
   Summary: S390: Floating point comparisons don't raise invalid
for unordered opperands.
   Product: gcc
   Version: unknown
Status: UNCONFIRMED
  Severity: normal
  Priority: P3
 Component: target
  Assignee: unassigned at gcc dot gnu.org
  Reporter: stli at linux dot vnet.ibm.com
  Target Milestone: ---

The C comparison operators <, >, <=, >= (as opposed to the isgreater, etc.
macros) are specified to raise the invalid exception on comparisons involving a
NaN (quiet or signaling). However, gcc on s390 is generating e.g. the cebr
(Short BFP COMPARE) instruction rather than kebr (Short BFP COMPARE AND
SIGNAL). The first one does not raise the invalid exception unless it
encounters a signaling NaN. The latter one raise the invalid exception if one
operand is quiet or signaling NaN. I haven't checked if invalid is raised if
gcc is using vector instructions.

[Bug go/66303] runtime.Caller() returns infinitely deep stack frames on s390x

2015-06-10 Thread stli at linux dot vnet.ibm.com
https://gcc.gnu.org/bugzilla/show_bug.cgi?id=66303

stli at linux dot vnet.ibm.com  changed:

   What|Removed |Added

 CC||stli at linux dot vnet.ibm.com

--- Comment #11 from stli at linux dot vnet.ibm.com  ---
I have created a bug in glibc
https://sourceware.org/bugzilla/show_bug.cgi?id=18508

and posted a patch
(https://www.sourceware.org/ml/libc-alpha/2015-06/msg00324.html) which omits
the cfi_startproc/cfi_endproc directives for __makecontext_ret. Thus backtrace
do not find any information about __makecontext_ret in .eh_frame and stops
backtrace like it is done with _start and thread_start functions.


[Bug go/66303] runtime.Caller() returns infinitely deep stack frames on s390x

2015-07-07 Thread stli at linux dot vnet.ibm.com
https://gcc.gnu.org/bugzilla/show_bug.cgi?id=66303

--- Comment #12 from stli at linux dot vnet.ibm.com  ---
The glibc bug https://sourceware.org/bugzilla/show_bug.cgi?id=18508
is fixed upstream with commit
https://sourceware.org/git/?p=glibc.git;a=commit;h=890b7a4b33d482b5c768ab47d70758b80227e9bc