Bug 52900 - Apache 2.4.1 build fails for core.c on Solaris 10 with GCC 4.6.x
Summary: Apache 2.4.1 build fails for core.c on Solaris 10 with GCC 4.6.x
Status: RESOLVED FIXED
Alias: None
Product: Apache httpd-2
Classification: Unclassified
Component: Build (show other bugs)
Version: 2.4.4
Hardware: Sun Solaris
: P2 normal (vote)
Target Milestone: ---
Assignee: Apache HTTPD Bugs Mailing List
URL:
Keywords: FixedInTrunk
Depends on:
Blocks:
 
Reported: 2012-03-13 15:01 UTC by Martin
Modified: 2013-04-26 11:43 UTC (History)
1 user (show)



Attachments
add workaround on sparc/64 (784 bytes, patch)
2013-04-08 19:45 UTC, Stefan Fritsch
Details | Diff
Minimal test case (239 bytes, text/plain)
2013-04-09 07:59 UTC, Rainer Jung
Details
Slightly bigger test case, showing errors even with O1 on Sparc 64 Bits. (381 bytes, text/plain)
2013-04-09 08:08 UTC, Rainer Jung
Details
Workaround for sparc/64 on gcc < 4.8 (867 bytes, patch)
2013-04-20 10:37 UTC, Stefan Fritsch
Details | Diff

Note You need to log in before you can comment on or make changes to this bug.
Description Martin 2012-03-13 15:01:46 UTC
Hi!

Preface: this seems to be a bug in the GCC compiler/optimizer, but it could easily be solved by changing the Apache 2.4 source code, so you may want to consider to integrate it. Also the workaround I found may help others, therfore I'm posting it here.

The compilation of Apache 2.4.1 on Solaris 10 SPARC with GCC 4.6.3 and 64 bit mode fails with an assembler error:

/var/tmp//cc8T9vzx.s: Assembler messages:
/var/tmp//cc8T9vzx.s:12254: Error: Illegal operands

The line stated contains
  fdtox   %f8, %f9
which - as far as some research indicates - is an illegal operation in 64 bit mode with an odd numbered register. Details are available if needed.

Anyway. Some analysis revealed that the root cause is an optimization (?) to use apr_uint16_t in ap_random_pick in core.c. Removing this solves the problem.

--- httpd-2.4.1/server/core.c   2012-02-04 11:04:59.000000000 +0100
+++ patched_core.c      2012-03-12 15:22:27.075035399 +0100
@@ -4722,16 +4722,20 @@ AP_DECLARE(void) ap_random_insecure_byte
 AP_DECLARE(apr_uint32_t) ap_random_pick(apr_uint32_t min, apr_uint32_t max)
 {
     apr_uint32_t number;
-    if (max < 16384) {
-        apr_uint16_t num16;
-        ap_random_insecure_bytes(&num16, sizeof(num16));
-        RAND_RANGE(num16, min, max, APR_UINT16_MAX);
-        number = num16;
-    }
-    else {
+/* Workaround for GCC 4.6.x producing illegal assembler code on SPARC
+ * if (max < 16384) {
+ *      apr_uint16_t num16;
+ *      ap_random_insecure_bytes(&num16, sizeof(num16));
+ *      RAND_RANGE(num16, min, max, APR_UINT16_MAX);
+ *      number = num16;
+ *  }
+ *  else {
+ */
         ap_random_insecure_bytes(&number, sizeof(number));
         RAND_RANGE(number, min, max, APR_UINT32_MAX);
-    }
+/*
+ *  }
+ */
     return number;
 }

I don't think this could have any negative side effects, but would appreciate your feedback.

Cheers,
Martin
Comment 1 Michael Moll 2013-04-06 18:55:37 UTC
I'm having the same problem on FreeBSD/sparc64.

NetBSD is affected, too:
http://gnats.netbsd.org/cgi-bin/query-pr-single.pl?number=47025
Comment 2 Stefan Fritsch 2013-04-07 09:30:51 UTC
Has someone tested this with a more recent version of gcc? If it is fixed there, we could add some #ifdef magic to apply the workaround only on older gcc's.

If it isn't fixed, then a bug should be filed on gcc.

Always using the 32bit type uses more output from the RNG than necessary. And the RNG is relatively expensive (it uses sha256 internally).
Comment 3 Rainer Jung 2013-04-07 20:14:00 UTC
I tried to reproduce on Solaris 10 Sparc, using the following compilers:

gcc-4.1.2
gcc-4.5.4
gcc-4.6.3
gcc-4.7.1
gcc-4.7.2

and CFLAGS "-mcpu=v9 -m64 -O2" source code was httpd 2.4.4.

Unfortunately in my tests compilation succeeds for gcc-4.1.2, gcc-4.5.4 and gcc-4.6.3. For the two 4.7 versions I get a failure in as:

/usr/ccs/bin/as -V -Qy -s -xarch=v9 -o core.o /var/tmp//cclu5H3f.s
/usr/ccs/bin/as: SunOS 5.10 118683-08 Patch 07/05/2012
/usr/ccs/bin/as: "/var/tmp//cclu5H3f.s", line 10402: error: invalid (misaligned) register

The assembler line number varies depending on the exact compilation flags.

When using CFLAGS only "-m64" there's no problem.

32 Bit compilations always succeed.

Here's an excerpt from the assembler code, error is in line 10402:

10378 .LL1698:
10379         add     %fp, 2041, %o0
10380         call    ap_random_insecure_bytes, 0
10381          mov    2, %o1
10382         sub     %i1, %i0, %i1
10383         lduh    [%fp+2041], %g1
10384         srl     %i1, 0, %i1
10385         st      %g1, [%fp+2011]
10386         stx     %i1, [%fp+2023]
10387         mov     1023, %g1
10388         ldd     [%fp+2023], %f10
10389         sllx    %g1, 52, %g1
10390         fxtod   %f10, %f12
10391         stx     %g1, [%fp+1999]
10392         mov     1007, %g1
10393         ldd     [%fp+1999], %f10
10394         sllx    %g1, 52, %g1
10395         faddd   %f12, %f10, %f10
10396         ld      [%fp+2011], %f8
10397         stx     %g1, [%fp+1999]
10398         fitod   %f8, %f8
10399         ldd     [%fp+1999], %f12
10400         fmuld   %f8, %f12, %f8
10401         fmuld   %f10, %f8, %f8
10402         fdtox   %f8, %f9                    <===========
10403         st      %f10, [%fp+2011]
10404         lduw    [%fp+2011], %g1
10405         add     %g1, %i0, %i0
10406         sll     %i0, 16, %i0
10407         srl     %i0, 16, %i0
10408         return  %i7+8
10409          srl    %o0, 0, %o0
10410         .size   ap_random_pick, .-ap_random_pick
10411         .global core_module
10412         .section        ".data"
10413         .align 8
10414         .type   core_module, #object
10415         .size   core_module, 104
10416 core_module:

This looks like an old bug that was fixed in gcc 3.x times. Although my Solaris assembler gives another error text, the problematic assembler line is the same as reported by the OP.

Strange that it compiles for me with 4.6 but not with 4.6. Unfortunately we don't know the exact flags used by the OP.

Regards,

Rainer
Comment 4 Rainer Jung 2013-04-07 20:35:55 UTC
Since there's not a strict relation with the compiler version, maybe it is one of the helper libs, like gmp, which also contains assembler. My gcc 4.7 was build using gmp 5.0.5.
Comment 5 Martin 2013-04-08 10:34:29 UTC
> and CFLAGS "-mcpu=v9 -m64 -O2" source code was httpd 2.4.4.
My CFLAGS were
"-m64 -O3 -mcpu=niagara -pthreads -fexceptions -fstack-protector --param=ssp-buffer-size=4"

The build succeeds if I omit the optimization flag, which matches Rainer's findings. If I remember correctly the optimization level does not matter, even with O1 the error occurs.

Maybe even the bintuils version matters, so maybe we should post these versions as well. I'm currently running a test with gcc 4.7.2, GMP 5.1.1 and binutils 2.23.1 and will post the result. Trying gcc 4.8.0 will take a day or two more.

Cheers,

Martin
Comment 6 Martin 2013-04-08 12:18:11 UTC
> I'm currently running a test with gcc 4.7.2, GMP 5.1.1 and
> binutils 2.23.1 and will post the result.
/var/tmp//ccMYi3X2.s: Assembler messages:
/var/tmp//ccMYi3X2.s:12710: Error: Illegal operands

Bug still there.

Cheers,

Martin
Comment 7 Stefan Fritsch 2013-04-08 19:45:10 UTC
Created attachment 30163 [details]
add workaround on sparc/64

We could disable the if block on gcc/sparc/64bit explicitly. This patch should do that.

But it would still be good if someone with a sparc machine would also file a bug report with gcc and add its URL here.
Comment 8 Rainer Jung 2013-04-09 07:59:37 UTC
Created attachment 30164 [details]
Minimal test case

Minimal test case showing gcc bug.
Compilation on Sparc with gcc 4.7 (for some builds also 4.6) fails for -m64 when any optimization is enabled.
Comment 9 Rainer Jung 2013-04-09 08:08:48 UTC
Created attachment 30165 [details]
Slightly bigger test case, showing errors even with O1 on Sparc 64 Bits.
Comment 10 Rainer Jung 2013-04-09 08:17:42 UTC
The minimal test case and the slightly larger one fail with -O2 when compiling for 64 Bits on Sparc with recent GCC (4.7.1 and 4.7.2 for me, *not* 4.6.3 for me, but likely also 4.6.3 for the OP, maybe due to the version of GMP, MPC or MPFR used?).

Error is

error: invalid (misaligned) register

due to the line

fdtox   %f8, %f9

It seems the second register must have an even number.

The slightly bigger test case also fails for O1 and for simple -O with a different error:

test.c: In function 'buggy':
test.c:13:1: error: insn does not satisfy its constraints:
(insn 126 42 43 3 (set (reg:HI 40 %f8 [orig:120 D.1367 ] [120])
        (reg:HI 42 %f10)) test.c:6 58 {*movhi_insn}
     (nil))
test.c:13:1: internal compiler error: in reload_cse_simplify_operands, at postreload.c:403
Please submit a full bug report,
with preprocessed source if appropriate.
See <http://gcc.gnu.org/bugs.html> for instructions.

This minimal test case does not fail with "-O1" or "-O", probably because of another register allocation strategy due to the missing second code path.

I'll open a GCC bug report.
Comment 11 Rainer Jung 2013-04-09 08:41:55 UTC
Filed GCC bug:

http://gcc.gnu.org/bugzilla/show_bug.cgi?id=56890
Comment 12 Martin 2013-04-10 10:00:07 UTC
(In reply to comment #5)
> Trying gcc 4.8.0 will take a day or two more.
Compilation of 2.4.4 with gcc 4.8.0 and CFLAGS including "-m64 -O3 -mcpu=niagara" works without any patch.

Cheers,

Martin
Comment 13 Rainer Jung 2013-04-10 17:27:01 UTC
Could you please try gcc 4.8.0 with my two very simple to compile test cases, once with only "-m64 -O" and once with "-m64 -O2" so that we get comparable results? I will then rpeort back to the gcc bug.

Thanks!
Comment 14 Martin 2013-04-11 09:26:10 UTC
(In reply to comment #13)
> Could you please try gcc 4.8.0 with my two very simple to compile test
> cases, once with only "-m64 -O" and once with "-m64 -O2" so that we get
> comparable results? I will then rpeort back to the gcc bug.
Done. Added a tarball to the gcc bug.
Bottom line: gcc 4.8.0 compiles the source fine, most likely any older version would need a workaround if CFLAGS include -m64 and -Ox (x>=1) .

Cheers,

Martin
Comment 15 Rainer Jung 2013-04-14 09:05:10 UTC
I have not yet checked httpd compilation, but I can confirm, that the test cases compile fine with GCC 4.8.0.

Problem still exists with 4.7.3.
Comment 16 Rainer Jung 2013-04-15 15:36:25 UTC
A patch has been applied to gcc trunk and 4.7 and 4.8 branches.
I tried the patch on top of gcc 4.7.3 and it does compile then.

So:

- we didn't see a problem with 4.8
- we had a problem with 4.7 which should be fixed in 4.7.4 (not yet released)
- some of us had a problem in 4.6.3.No patch was applied to that branch.
- It seems there was no problem before 4.6.

Rainer
Comment 17 Michael Moll 2013-04-15 16:30:08 UTC
> - It seems there was no problem before 4.6.
         
I can't confirm that. On FreeBSD/sparc64 we're using:
gcc version 4.2.1 20070831 patched [FreeBSD]                                              
and I ran into the problem.
Comment 18 Stefan Fritsch 2013-04-20 10:37:14 UTC
Created attachment 30217 [details]
Workaround for sparc/64 on gcc < 4.8

So, since we don't know an exact version where the bug was introduced, I think we should simply add the workaround for all gccs < 4.8. Can someone verify that this patch does the trick?
Comment 19 Michael Moll 2013-04-20 12:13:33 UTC
Works for me[tm] :)
Comment 20 Stefan Fritsch 2013-04-20 16:24:29 UTC
thanks.

trunk commit: r1470183
Comment 21 Ruediger Pluem 2013-04-26 11:43:24 UTC
Backported to 2.4.x as r1470183.