Commit 33f3393a by Andreas Krebbel Committed by Andreas Krebbel

S/390: Fix flogr RTX.

The flogr instruction uses a 64 bit register pair target operand.  In
the RTX we model this as a write to a TImode register.  Unfortunately
the RTX's being assigned to the two parts of the target operand were
swapped.  This is no problem if in the end the flogr instruction will
be emitted since the instruction still does what the clzdi expander
expects.  However, a problem arises when the RTX is used to optimize
CLZ for a constant input operand.  Even then it matters only if the
expression couldn't be folded on tree level already.

In the testcase this happened thanks to loop unrolling on RTL level.
The iteration variable is used as an argument to the clz
builtin. Due to the loop unrolling it becomes a constant and after
folding the broken RTX leads to a wrong assumption.

gcc/ChangeLog:

2018-11-20  Andreas Krebbel  <krebbel@linux.ibm.com>

	* config/s390/s390.md ("clztidi2"): Swap the RTX's written to the
	DImode parts of the target operand.

gcc/testsuite/ChangeLog:

2018-11-20  Andreas Krebbel  <krebbel@linux.ibm.com>

	* gcc.target/s390/flogr-1.c: New test.

From-SVN: r266321
parent 84bfc732
2018-11-20 Andreas Krebbel <krebbel@linux.ibm.com>
* config/s390/s390.md ("clztidi2"): Swap the RTX's written to the
DImode parts of the target operand.
2018-11-20 Nathan Sidwell <nathan@acm.org>
PR 87926
......@@ -8759,17 +8759,17 @@
DONE;
})
; CLZ result is in hard reg op0 - this is the high part of the target operand
; The source with the left-most one bit cleared is in hard reg op0 + 1 - the low part
(define_insn "clztidi2"
[(set (match_operand:TI 0 "register_operand" "=d")
(ior:TI
(ashift:TI
(zero_extend:TI
(xor:DI (match_operand:DI 1 "register_operand" "d")
(lshiftrt (match_operand:DI 2 "const_int_operand" "")
(subreg:SI (clz:DI (match_dup 1)) 4))))
(const_int 64))
(zero_extend:TI (clz:DI (match_dup 1)))))
(ashift:TI (zero_extend:TI (clz:DI (match_operand:DI 1 "register_operand" "d")))
(const_int 64))
(zero_extend:TI
(xor:DI (match_dup 1)
(lshiftrt (match_operand:DI 2 "const_int_operand" "")
(subreg:SI (clz:DI (match_dup 1)) 4))))))
(clobber (reg:CC CC_REGNUM))]
"UINTVAL (operands[2]) == HOST_WIDE_INT_1U << 63
&& TARGET_EXTIMM && TARGET_ZARCH"
......
2018-11-20 Andreas Krebbel <krebbel@linux.ibm.com>
* gcc.target/s390/flogr-1.c: New test.
2018-11-20 Jan Hubicka <hubicka@ucw.cz>
PR ipa/87706
......
/* { dg-do run } */
/* { dg-options "-O2 -funroll-loops -march=z9-109" } */
/* { dg-require-effective-target stdint_types } */
/* Folding of the FLOGR caused a wrong value to be returned by
__builtin_clz becuase of a problem in the RTX we emit for FLOGR.
The problematic folding can only be triggered with constants inputs
introduced on RTL level. In this case it happens with loop
unrolling. */
#include <stdint.h>
#include <assert.h>
static inline uint32_t pow2_ceil_u32(uint32_t x) {
if (x <= 1) {
return x;
}
int msb_on_index;
msb_on_index = (31 ^ __builtin_clz(x - 1));
assert(msb_on_index < 31);
return 1U << (msb_on_index + 1);
}
void __attribute__((noinline,noclone))
die (int a)
{
if (a)
__builtin_abort ();
}
void test_pow2_ceil_u32(void) {
unsigned i;
for (i = 0; i < 18; i++) {
uint32_t a_ = (pow2_ceil_u32(((uint32_t)1) << i));
if (!(a_ == (((uint32_t)1) << i))) {
die(1);
}
}
}
int
main(void) {
test_pow2_ceil_u32();
return 0;
}
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment