Re: gcc 4.6.3 miscompile on ppc32 (was Re: Regression in kernel 4.12-rc1 for Powerpc 32 - bisected to commit 3448890c32c3)

2017-06-26 Thread Michael Ellerman
Al Viro  writes:

> On Sun, Jun 25, 2017 at 04:44:09PM -0500, Segher Boessenkool wrote:
>
>> Do you have a short stand-alone testcase?  4.6 is ancient, of course, but
>> the actual problem may still exist in more recent compilers (if it _is_
>> a compiler problem; if it's not, you *really* want to know :-) )
>
> Enjoy.  At least 6.3 doesn't step into that.  Look for mtctr in the resulting
> asm...
>
> cat <<'EOF' >a.c
...

I pointed creduce at that and got the version below, which I'm pretty
sure still exhibits the weird mtctr behaviour.

cheers

# cat input.c
struct {
  void *iov_base;
  unsigned iov_len;
} * c;
long v;
void *a;
int b;
unsigned bar();
foo(unsigned p1) {
  unsigned d, e = p1;
  if (p1 == 0)
goto out;
  if (p1 > 4)
goto out;
  if (__builtin_expect(!!(0, v && a), 1))
e = bar();
  if (e)
barf(e);
  if (e)
goto out;
  d = 0;
  for (; d < p1; d++) {
int f = c[d].iov_len;
if (__builtin_expect(c[d].iov_base && f, 0))
  b = 4;
  }
out:;
}

$ cat output.s 
.file   "input.c"

 # rs6000/powerpc options: -mcpu=powerpc -msdata=data -G 8
 # GNU C (GCC) version 4.6.3 (powerpc64-linux)
 #  compiled by GNU C version 4.3.2, GMP version 4.3.2, MPFR version 2.4.2, 
MPC version 0.8.2
 # ...

 # Compiler executable checksum: 4b51a6b899110d06c9e3310ac66ad26c

.section".text"
.align 2
.globl foo
.type   foo, @function
foo:
cmpwi 0,3,0  # tmp169, p1
stwu 1,-16(1)#,,
mflr 0   #,
stw 0,20(1)  #,
beq- 0,.L9   #
cmplwi 7,3,4 #, tmp170, p1
bgt- 7,.L9   #
lis 9,v@ha   # tmp172,
lwz 0,v@l(9) # v, v
cmpwi 7,0,0  #, tmp174, v
beq- 7,.L3   #
lis 9,a@ha   # tmp176,
lwz 0,a@l(9) # a, a
cmpwi 7,0,0  #, tmp178, a
beq- 7,.L3   #
bl bar   #
cmpwi 0,3,0  # tmp179, e
beq+ 0,.L4   #
.L3:
bl barf  #
b .L9#
.L4:
lis 8,0x2000 #,
lis 9,c@ha   # tmp181,
mtctr 8  # tmp192,
lwz 11,c@l(9)# c, c.3
lis 10,b@ha  # tmp190,
li 9,0   # ivtmp.12,
li 0,4   # tmp191,
.L6:
lwzx 7,11,9  # MEM[base: c.3_14, index: ivtmp.12_25, offset: 0B], 
MEM[base: c.3_14, index: ivtmp.12_25, offset: 0B]
add 8,11,9   # tmp182, c.3, ivtmp.12
lwz 8,4(8)   # MEM[base: D.1310_21, offset: 4B], D.1287
cmpwi 7,7,0  #, tmp184, MEM[base: c.3_14, index: ivtmp.12_25, 
offset: 0B]
beq+ 7,.L5   #
cmpwi 7,8,0  #, tmp185, D.1287
beq+ 7,.L5   #
stw 0,b@l(10)# b, tmp191
.L5:
addi 9,9,8   # ivtmp.12, ivtmp.12,
bdnz .L6 #
.L2:
.L9:
lwz 0,20(1)  #,
addi 1,1,16  #,,
mtlr 0   #,
blr  #
.size   foo,.-foo
.globl b
.globl a
.globl v
.globl c
.section.sbss,"aw",@nobits
.align 2
.type   b, @object
.size   b, 4
b:
.zero   4
.type   a, @object
.size   a, 4
a:
.zero   4
.type   v, @object
.size   v, 4
v:
.zero   4
.type   c, @object
.size   c, 4
c:
.zero   4
.ident  "GCC: (GNU) 4.6.3"
.section.note.GNU-stack,"",@progbits


Re: gcc 4.6.3 miscompile on ppc32 (was Re: Regression in kernel 4.12-rc1 for Powerpc 32 - bisected to commit 3448890c32c3)

2017-06-25 Thread Al Viro
On Sun, Jun 25, 2017 at 04:44:09PM -0500, Segher Boessenkool wrote:

> Do you have a short stand-alone testcase?  4.6 is ancient, of course, but
> the actual problem may still exist in more recent compilers (if it _is_
> a compiler problem; if it's not, you *really* want to know :-) )

Enjoy.  At least 6.3 doesn't step into that.  Look for mtctr in the resulting
asm...

cat <<'EOF' >a.c
struct iovec
{
 void *iov_base;
 unsigned iov_len;
};

unsigned long v;

extern void * barf(void *,int,unsigned);

extern unsigned long bar(void *to, const void *from, unsigned long size);

static inline unsigned long __bar(void *to, const void *from, unsigned long n)
{
 unsigned long res = n;
 if (__builtin_expect(!!(((void)0,  unsigned long)(from)) <= v) && n)) 
== 0) || n)) - 1) <= (v - (( unsigned long)(from, 1))
  res = bar(to, from, n);
 if (res)
  barf(to + (n - res), 0, res);
 return res;
}

int foo(int type, const struct iovec * uvector,
 unsigned long nr_segs, unsigned long fast_segs,
 struct iovec *iov,
 struct iovec **ret_pointer)
{
 unsigned long seg;
 int ret;
 if (nr_segs == 0) {
  ret = 0;
  goto out;
 }
 if (nr_segs > 1024) {
  ret = -22;
  goto out;
 }
 if (__bar(iov, uvector, nr_segs*sizeof(*uvector))) {
  ret = -14;
  goto out;
 }
 ret = 0;
 for (seg = 0; seg < nr_segs; seg++) {
  void *buf = iov[seg].iov_base;
  int len = (int)iov[seg].iov_len;
  if (len < 0) {
   ret = -22;
   goto out;
  }
  if (type >= 0
  && __builtin_expect(!!(!((void)0,  unsigned long)(buf)) <= v) && 
len)) == 0) || len)) - 1) <= (v - (( unsigned long)(buf, 0)) {
   ret = -14;
   goto out;
  }
  ret += len;
 }
out:
 *ret_pointer = iov;
 return ret;
}
EOF
powerpc-linux-gcc -m32 -fno-strict-aliasing -fno-common -std=gnu89 -fno-PIE 
-msoft-float -pipe -ffixed-r2 -mmultiple -mno-altivec -mno-vsx -mno-spe 
-mspe=no -funit-at-a-time -fno-dwarf2-cfi-asm -mno-string -mcpu=powerpc 
-Wa,-maltivec -mbig-endian -fno-delete-null-pointer-checks -Os 
-fno-stack-protector -Wno-unused-but-set-variable -fomit-frame-pointer 
-fno-var-tracking-assignments -femit-struct-debug-baseonly -fno-var-tracking 
-fno-strict-overflow -fconserve-stack -fverbose-asm -S a.c


Re: gcc 4.6.3 miscompile on ppc32 (was Re: Regression in kernel 4.12-rc1 for Powerpc 32 - bisected to commit 3448890c32c3)

2017-06-25 Thread Segher Boessenkool
On Sun, Jun 25, 2017 at 09:53:24PM +0100, Al Viro wrote:
> Confirmed.  It manages to bugger the loop immediately after the (successful)
> copying of iovec array in rw_copy_check_uvector(); both with and without
> INLINE_COPY_FROM_USER it has (just before the call of copy_from_user()) r27
> set to nr_segs * sizeof(struct iovec).  The call is made, we check that it
> has succeeded and that's when it hits the fan: without INLINE_COPY_FROM_USER
> we have (interleaved with unrelated insns)
> addi 27,27,-8
> srwi 27,27,3
> addi 27,27,1
> mtctr 27
> Weird, but manages to pass nr_segs to mtctr.

This weirdosity is https://gcc.gnu.org/PR67288 .  Those three instructions
are not the same as just  srwi 27,27,3  in case r27 is 0; GCC does not
figure out this cannot happen here.

> _With_ INLINE_COPY_FROM_USER we
> get this:
> lis 9,0x2000
> mtctr 9
> In other words, the loop will try to go through 8192 iterations.  No idea 
> where
> that number has come from, but it sure as hell is wrong.

8192*65535, even.  This is as if r27 was 0 always.

Do you have a short stand-alone testcase?  4.6 is ancient, of course, but
the actual problem may still exist in more recent compilers (if it _is_
a compiler problem; if it's not, you *really* want to know :-) )


Segher