Re-merge patch and fixes (was: x86_64 gcc build failure with 2011.01-0)
Affects | Status | Importance | Assigned to | Milestone | |
---|---|---|---|---|---|
Linaro GCC |
Fix Released
|
Medium
|
Andrew Stubbs | ||
gcc-4.5 (Ubuntu) |
Fix Released
|
High
|
Unassigned |
Bug Description
From the Ubuntu build log:
http://
../../src/
../../src/
(insn 25 7 26 2 ../../src/
(mem/s:SI (plus:DI (reg/v/f:DI 5 di [orig:64 of ] [64])
../../src/
Please submit a full bug report,
with preprocessed source if appropriate.
See <file:/
On closer inspection, our own build log shows the problem, but in a different place, and it did not affect the test run, apparently:
http://
We should probably check the build status in addition to the test results!
Changed in gcc-4.5 (Ubuntu): | |
importance: | Undecided → High |
status: | New → Confirmed |
Changed in gcc-linaro: | |
status: | New → Triaged |
importance: | Critical → Medium |
The invalid RTL was introduced by the following peephole in i386.md:
;; After splitting up read-modify operations, array accesses with memory
;; operands might end up in form:
;; sall $2, %eax
;; movl 4(%esp), %edx
;; addl %edx, %eax
;; instead of pre-splitting:
;; sall $2, %eax
;; addl 4(%esp), %eax
;; Turn it into:
;; movl 4(%esp), %edx
;; leal (%edx,%eax,4), %eax
(define_peephole2 scratch: SI 5 "r")
(ashift (match_operand 1 "register_operand" "")
( match_operand 2 "const_int_operand" "")))
(clobber (reg:CC FLAGS_REG))])
(plus (match_dup 0)
(match_ operand 4 "x86_64_ general_ operand" "")))
(clobber (reg:CC FLAGS_REG))])] PARTIAL_ REG_STALL mentioned_ p (operands[0], operands[4])"
[(match_
(parallel [(set (match_operand 0 "register_operand" "")
(parallel [(set (match_operand 3 "register_operand" "")
"INTVAL (operands[2]) >= 0 && INTVAL (operands[2]) <= 3
/* Validate MODE for lea. */
&& ((!TARGET_
&& (GET_MODE (operands[0]) == QImode
|| GET_MODE (operands[0]) == HImode))
|| GET_MODE (operands[0]) == SImode
|| (TARGET_64BIT && GET_MODE (operands[0]) == DImode))
/* We reorder load and the shift. */
&& !reg_overlap_
[(set (match_dup 5) (match_dup 4))
(set (match_dup 0) (match_dup 1))]
{
enum machine_mode mode = GET_MODE (operands[1]) == DImode ? DImode : SImode;
int scale = 1 << INTVAL (operands[2]);
rtx index = gen_lowpart (Pmode, operands[1]);
rtx base = gen_lowpart (Pmode, operands[5]);
rtx dest = gen_lowpart (mode, operands[3]);
operands[1] = gen_rtx_PLUS (Pmode, base,
gen_rtx_ MULT (Pmode, index, GEN_INT (scale)));
if (mode != Pmode)
operands[1] = gen_rtx_SUBREG (mode, operands[1], 0);
operands[5] = base;
operands[0] = dest;
})
Note how operands[5] is always DImode, while operands[4] may be some other mode.