tree-ssa-threadbackward.c (profitable_jump_thread_path): Do not allow __builtin_constant_p.

Linux Kernel (specifically, drivers/leds/trigger/ledtrig-cpu.c) build
with GCC 10 fails on s390 with "impossible constraint".

Explanation by Jeff Law:

```
So what we have is a b_c_p at the start of an if-else chain.  Subsequent
tests on the "true" arm of the the b_c_p test may throw us off the
constant path (because the constants are out of range).  Once all the
tests are passed (it's constant and the constant is in range) the true
arm's terminal block has a special asm that requires a constant
argument.   In the case where we get to the terminal block on the true
arm, the argument to the b_c_p is used as the constant argument to the
special asm.

At first glace jump threading seems to be doing the right thing.  Except
that we end up with two paths to that terminal block with the special
asm, one for each of the two constant arguments to the b_c_p call.
Naturally since that same value is used in the asm, we have to introduce
a PHI to select between them at the head of the terminal block.   Now
the argument in the asm is no longer constant and boom we fail.
```

Fix by disallowing __builtin_constant_p on threading paths.

gcc/ChangeLog:

2020-06-03  Ilya Leoshkevich  <iii@linux.ibm.com>

	* tree-ssa-threadbackward.c (thread_jumps::profitable_jump_thread_path):
	Do not allow __builtin_constant_p on a threading path.

gcc/testsuite/ChangeLog:

2020-06-03  Ilya Leoshkevich  <iii@linux.ibm.com>

	* gcc.target/s390/builtin-constant-p-threading.c: New test.
This commit is contained in:
Ilya Leoshkevich 2020-06-03 20:55:20 +02:00
parent 11860cf440
commit 70a6200918
2 changed files with 52 additions and 1 deletions

View File

@ -0,0 +1,46 @@
/* { dg-do compile } */
/* { dg-options "-O2 -march=z196 -mzarch" } */
typedef struct
{
int counter;
} atomic_t;
static inline __attribute__ ((__gnu_inline__)) int
__atomic_add (int val, int *ptr)
{
int old;
asm volatile("laa %[old],%[val],%[ptr]\n"
: [old] "=d" (old), [ptr] "+Q"(*ptr)
: [val] "d" (val)
: "cc", "memory");
return old;
}
static inline __attribute__ ((__gnu_inline__)) void
__atomic_add_const (int val, int *ptr)
{
asm volatile("asi %[ptr],%[val]\n"
: [ptr] "+Q" (*ptr)
: [val] "i" (val)
: "cc", "memory");
}
static inline __attribute__ ((__gnu_inline__)) void
atomic_add (int i, atomic_t *v)
{
if (__builtin_constant_p (i) && (i > -129) && (i < 128))
{
__atomic_add_const (i, &v->counter);
return;
}
__atomic_add (i, &v->counter);
}
static atomic_t num_active_cpus = { (0) };
void
ledtrig_cpu (_Bool is_active)
{
atomic_add (is_active ? 1 : -1, &num_active_cpus);
}

View File

@ -259,8 +259,13 @@ thread_jumps::profitable_jump_thread_path (basic_block bbi, tree name,
!gsi_end_p (gsi);
gsi_next_nondebug (&gsi))
{
/* Do not allow OpenACC loop markers and __builtin_constant_p on
threading paths. The latter is disallowed, because an
expression might be constant on two threading paths, and
become non-constant (i.e.: phi) when they merge. */
gimple *stmt = gsi_stmt (gsi);
if (gimple_call_internal_p (stmt, IFN_UNIQUE))
if (gimple_call_internal_p (stmt, IFN_UNIQUE)
|| gimple_call_builtin_p (stmt, BUILT_IN_CONSTANT_P))
{
m_path.pop ();
return NULL;