LLVM Bugzilla is read-only and represents the historical archive of all LLVM issues filled before November 26, 2021. Use github to submit LLVM bugs

Bug 1385 - [loop unroll] mishandling LCSSA phi of value defined above loop
Summary: [loop unroll] mishandling LCSSA phi of value defined above loop
Status: RESOLVED FIXED
Alias: None
Product: libraries
Classification: Unclassified
Component: Loop Optimizer (show other bugs)
Version: 1.9
Hardware: All All
: P normal
Assignee: Chris Lattner
URL:
Keywords: miscompilation
Depends on:
Blocks:
 
Reported: 2007-05-05 04:16 PDT by Bill Wendling
Modified: 2010-02-22 12:48 PST (History)
2 users (show)

See Also:
Fixed By Commit(s):


Attachments
The C code (reduced from GMP's t-pow.c file) that produces the Bus Error. (759 bytes, text/plain)
2007-05-05 04:18 PDT, Bill Wendling
Details
LLVM's assembly output (2.58 KB, text/plain)
2007-05-05 04:18 PDT, Bill Wendling
Details
GCC's assembly output (2.45 KB, text/plain)
2007-05-05 04:19 PDT, Bill Wendling
Details

Note You need to log in before you can comment on or make changes to this bug.
Description Bill Wendling 2007-05-05 04:16:36 PDT
There seems to be a problem with how code is generated for a call after a loop is unrolled. Consider 
this C code (on a PowerBook G4 machine):

typedef unsigned long int mp_limb_t;

typedef struct {
  int _mp_alloc;
  int _mp_size;
  mp_limb_t *_mp_d;
} __mpz_struct;

typedef __mpz_struct mpz_t[1];
typedef const __mpz_struct *mpz_srcptr;
typedef __mpz_struct *mpz_ptr;

void Foo(mpz_srcptr base) {
  unsigned i;
  mpz_t want;
  __gmpz_init(want);
  for (i = 0; i < 2; i++) {
    __gmpz_mul(want, want, base);
  }
  __gmpz_clear(want);
}

void Bar(mpz_srcptr base) {
  mpz_t want;
  __gmpz_init(want);
  __gmpz_mul(want, want, base);
  __gmpz_mul(want, want, base);
  __gmpz_clear(want);
}

If you look at "testcase.llvm.s", you'll notice that, even though both Foo and Bar functions compute the 
exact same thing, the Foo function, because it's a loop that's been unrolled, has an "implicit def" of R3 
before the gmpz_clear call:

        mr r3, r29
        mr r4, r29
        mr r5, r30
        bl L___gmpz_mul$stub
        ;IMPLICIT_DEF_GPRC r3                                                                             
        bl L___gmpz_clear$stub

while the Bar case has:

        mr r3, r29
        mr r4, r29
        mr r5, r30
        bl L___gmpz_mul$stub
        mr r3, r29
        bl L___gmpz_clear$stub

The Foo case would be fine, if R3 wasn't trashed in the calls, but it appears to be. Though my guess is 
that it probably should be marked as "clobbered" across calls. The "mpz_clear" function's in a library 
and looks like this:

void mpz_clear (mpz_ptr m) {
  (*__gmp_free_func) (m->_mp_d, m->_mp_alloc * BYTES_PER_MP_LIMB);
}

Now, gcc produces code for Foo that looks like this:

L2:
        addi r3,r1,56
        mr r5,r29
        mr r4,r3
        bl L___gmpz_mul$stub
        addic. r30,r30,-1
        bne- cr0,L2
        addi r3,r1,56
        bl L___gmpz_clear$stub

and Bar that looks like this:

        addi r3,r1,56
        mr r5,r29
        mr r4,r3
        bl L___gmpz_mul$stub
        addi r3,r1,56
        bl L___gmpz_clear$stub

So it's doing the correct thing. We should too.

BTW, this is the only test which failed in the GMP testsuite. Woo!

-bw
Comment 1 Bill Wendling 2007-05-05 04:18:15 PDT
Created attachment 824 [details]
The C code (reduced from GMP's t-pow.c file) that produces the Bus Error.
Comment 2 Bill Wendling 2007-05-05 04:18:58 PDT
Created attachment 825 [details]
LLVM's assembly output
Comment 3 Bill Wendling 2007-05-05 04:19:22 PDT
Created attachment 826 [details]
GCC's assembly output
Comment 4 Anton Korobeynikov 2007-05-05 04:24:44 PDT
Bill, thanks for tracking this!

This test fails for me (x86/linux) too. Probably due to same reason.
Comment 5 Bill Wendling 2007-05-05 04:31:17 PDT
No prob :-)

It's pretty onerous. It looks like we *are* marking the R3 register as being clobbered. I now think it's some 
strange loop weirdness. I'm not skilled enough with bugpoint to get it to widdle this down to the pass that 
could be causing the problem.

-bw
Comment 6 Anton Korobeynikov 2007-05-05 04:33:44 PDT
Note, that I'm on x86 :) So, this seems to be some common codegen weirdness.
Comment 7 Chris Lattner 2007-05-05 13:27:55 PDT
This is a bug in loop unroll rewriting LCSSA phi nodes.
Comment 8 Chris Lattner 2007-05-05 13:51:16 PDT
Fixed, patch here:
http://lists.cs.uiuc.edu/pipermail/llvm-commits/Week-of-Mon-20070430/049154.html

testcase here: Transforms/LoopUnroll/2007-05-05-UnrollMiscomp.ll

-Chris
Comment 9 Bill Wendling 2007-05-05 15:50:20 PDT
Quicker next time!

;-)

Thanks!
-bw