public inbox for gcc-bugs@sourceware.org help / color / mirror / Atom feed
From: "zack at codesourcery dot com" <gcc-bugzilla@gcc.gnu.org> To: gcc-bugs@gcc.gnu.org Subject: [Bug optimization/13772] [tree-ssa] ICE in get_expr_operands Date: Thu, 22 Jan 2004 10:41:00 -0000 [thread overview] Message-ID: <20040122104113.4359.qmail@sources.redhat.com> (raw) In-Reply-To: <20040120162056.13772.reichelt@gcc.gnu.org> ------- Additional Comments From zack at codesourcery dot com 2004-01-22 10:40 ------- Subject: PR 13772 candidate fix This is my candidate patch for the ia64/ada bootstrap failure introduced by my TI/TFmode changes last week. It takes the entire problem off reload's hands, by careful use of postincrement so that the scratch register becomes unnecessary. Richard - I didn't use peephole2 as we discussed because that's only effective in an optimizing compilation; so I had to make the splitters do the work, and then it seemed silly to do it again. It might be worthwhile adding a bit more smarts about when the pointer is dead and therefore doesn't need to be postmodified the second time; it might also be worthwhile to add a peep2 to convert ld8 r12 = [r14], 8 ;; ld8 r13 = [r14], -8 to adds r15 = r14, 8 ;; ld8 r12 = [r14] ld8 r13 = [r15] when a scratch register is available; this exposes a smidge more parallelism. I am bootstrapping this on ia64-hpux, C and C++ only. I would appreciate help testing ia64-linux and/or Ada. I can confirm that a cross-gnat1 built with this patch can compile a-elchha.adb at both -O2 and -O0 without aborting. zw * config/ia64/ia64.c (ia64_split_tmode, ia64_split_tmode_move): Rewrite using POST_INC/POST_DEC/POST_MODIFY and no scratch registers. (ia64_secondary_reload_class): Remove GR_REGS TImode/TFmode clause. * config/ia64/ia64.md (movti, *movti_internal, movtf, *movtf_internal): Remove scratch from pattern. (reload_inti, reload_outti, reload_intf, reload_outtf): Delete. =================================================================== Index: config/ia64/ia64.c --- config/ia64/ia64.c 16 Jan 2004 01:27:37 -0000 1.265 +++ config/ia64/ia64.c 22 Jan 2004 10:37:36 -0000 @@ -1362,62 +1362,28 @@ ia64_emit_cond_move (rtx op0, rtx op1, r } /* Split a post-reload TImode or TFmode reference into two DImode - components. */ + components. This is made extra difficult by the fact that we do + not get any scratch registers to work with, because reload cannot + be prevented from giving us a scratch that overlaps the register + pair involved. So instead, when addressing memory, we tweak the + pointer register up and back down with POST_INCs. Or up and not + back down when we can get away with it. */ -static rtx -ia64_split_tmode (rtx out[2], rtx in, rtx scratch) +static void +ia64_split_tmode (rtx out[2], rtx in, bool reversed) { switch (GET_CODE (in)) { case REG: - out[0] = gen_rtx_REG (DImode, REGNO (in)); - out[1] = gen_rtx_REG (DImode, REGNO (in) + 1); - return NULL_RTX; - - case MEM: - { - rtx base = XEXP (in, 0); - - switch (GET_CODE (base)) - { - case REG: - out[0] = adjust_address (in, DImode, 0); - break; - case POST_MODIFY: - base = XEXP (base, 0); - out[0] = adjust_address (in, DImode, 0); - break; - - /* Since we're changing the mode, we need to change to POST_MODIFY - as well to preserve the size of the increment. Either that or - do the update in two steps, but we've already got this scratch - register handy so let's use it. */ - case POST_INC: - base = XEXP (base, 0); - out[0] - = change_address (in, DImode, - gen_rtx_POST_MODIFY - (Pmode, base, plus_constant (base, 16))); - break; - case POST_DEC: - base = XEXP (base, 0); - out[0] - = change_address (in, DImode, - gen_rtx_POST_MODIFY - (Pmode, base, plus_constant (base, -16))); - break; - default: - abort (); - } - - if (scratch == NULL_RTX) - abort (); - out[1] = change_address (in, DImode, scratch); - return gen_adddi3 (scratch, base, GEN_INT (8)); - } + out[reversed] = gen_rtx_REG (DImode, REGNO (in)); + out[!reversed] = gen_rtx_REG (DImode, REGNO (in) + 1); + break; case CONST_INT: case CONST_DOUBLE: + /* Cannot occur reversed. */ + if (reversed) abort (); + if (GET_MODE (in) != TFmode) split_double (in, &out[0], &out[1]); else @@ -1444,7 +1410,74 @@ ia64_split_tmode (rtx out[2], rtx in, rt out[0] = GEN_INT (p[0]); out[1] = GEN_INT (p[1]); } - return NULL_RTX; + break; + + case MEM: + { + rtx base = XEXP (in, 0); + rtx offset; + + switch (GET_CODE (base)) + { + case REG: + /* Pointer expected to remain unchanged - post_inc it up, + post_dec it back down. If reversed, it means this + pointer dies here, so we must load the second field + first. This requires the emission of an extra addition + insn. */ + if (!reversed) + { + out[0] = change_address (in, DImode, + gen_rtx_POST_INC (Pmode, base)); + out[1] = change_address (in, DImode, + gen_rtx_POST_DEC (Pmode, base)); + } + else + { + emit_insn (gen_adddi3 (base, base, GEN_INT (8))); + out[0] = change_address (in, DImode, + gen_rtx_POST_DEC (Pmode, base)); + out[1] = adjust_address (in, DImode, 0); + } + break; + + case POST_INC: + if (reversed) abort (); + /* Do the increment in two steps. */ + out[0] = change_address (in, DImode, + gen_rtx_POST_INC (Pmode, base)); + out[1] = change_address (in, DImode, + gen_rtx_POST_INC (Pmode, base)); + break; + + case POST_DEC: + if (reversed) abort (); + /* Add 8, subtract 24. */ + out[0] = change_address (in, DImode, + gen_rtx_POST_INC (Pmode, base)); + out[1] = change_address (in, DImode, + gen_rtx_POST_MODIFY + (Pmode, base, plus_constant (base, -24))); + break; + + case POST_MODIFY: + if (reversed) abort (); + /* Extract and adjust the modification. */ + offset = XEXP (base, 1); + base = XEXP (base, 0); + + out[0] = change_address (in, DImode, + gen_rtx_POST_INC (Pmode, base)); + out[1] = change_address (in, DImode, + gen_rtx_POST_MODIFY + (Pmode, base, plus_constant (offset, -8))); + break; + + default: + abort (); + } + break; + } default: abort (); @@ -1456,37 +1489,32 @@ ia64_split_tmode (rtx out[2], rtx in, rt void ia64_split_tmode_move (rtx operands[]) { - rtx adj1, adj2, in[2], out[2], insn; - int first; + rtx in[2], out[2], insn; + bool reversed = false; - adj1 = ia64_split_tmode (in, operands[1], operands[2]); - adj2 = ia64_split_tmode (out, operands[0], operands[2]); - - first = 0; - if (reg_overlap_mentioned_p (out[0], in[1])) - { - if (reg_overlap_mentioned_p (out[1], in[0])) - abort (); - first = 1; - } - - if (adj1 && adj2) - abort (); - if (adj1) - emit_insn (adj1); - if (adj2) - emit_insn (adj2); - insn = emit_insn (gen_rtx_SET (VOIDmode, out[first], in[first])); - if (GET_CODE (out[first]) == MEM - && GET_CODE (XEXP (out[first], 0)) == POST_MODIFY) + /* It is possible for reload to decide to overwrite a pointer with + the value it points to. In that case we have to do the loads in + the opposite order so that the pointer is not destroyed too early. + Also we must not generate a postmodify for that second load, or + rws_access_regno will abort. */ + if (GET_CODE (operands[1]) == MEM + && reg_overlap_mentioned_p (operands[0], operands[1])) + reversed = true; + + ia64_split_tmode (in, operands[1], reversed); + ia64_split_tmode (out, operands[0], reversed); + + insn = emit_insn (gen_rtx_SET (VOIDmode, out[0], in[0])); + if (GET_CODE (out[0]) == MEM + && GET_CODE (XEXP (out[0], 0)) == POST_MODIFY) REG_NOTES (insn) = gen_rtx_EXPR_LIST (REG_INC, - XEXP (XEXP (out[first], 0), 0), + XEXP (XEXP (out[0], 0), 0), REG_NOTES (insn)); - insn = emit_insn (gen_rtx_SET (VOIDmode, out[!first], in[!first])); - if (GET_CODE (out[!first]) == MEM - && GET_CODE (XEXP (out[!first], 0)) == POST_MODIFY) + insn = emit_insn (gen_rtx_SET (VOIDmode, out[1], in[1])); + if (GET_CODE (out[1]) == MEM + && GET_CODE (XEXP (out[1], 0)) == POST_MODIFY) REG_NOTES (insn) = gen_rtx_EXPR_LIST (REG_INC, - XEXP (XEXP (out[!first], 0), 0), + XEXP (XEXP (out[1], 0), 0), REG_NOTES (insn)); } @@ -4451,13 +4479,6 @@ ia64_secondary_reload_class (enum reg_cl /* This can happen when we take a BImode subreg of a DImode value, and that DImode value winds up in some non-GR register. */ if (regno >= 0 && ! GENERAL_REGNO_P (regno) && ! PR_REGNO_P (regno)) - return GR_REGS; - break; - - case GR_REGS: - /* Since we have no offsettable memory addresses, we need a temporary - to hold the address of the second word. */ - if (mode == TImode || mode == TFmode) return GR_REGS; break; =================================================================== Index: config/ia64/ia64.md --- config/ia64/ia64.md 16 Jan 2004 01:27:38 -0000 1.119 +++ config/ia64/ia64.md 22 Jan 2004 10:37:36 -0000 @@ -584,11 +584,12 @@ [(set_attr "itanium_class" "ialu")]) ;; With no offsettable memory references, we've got to have a scratch -;; around to play with the second word. +;; around to play with the second word. However, in order to avoid a +;; reload nightmare we lie, claim we don't need one, and fix it up +;; in ia64_split_tmode_move. (define_expand "movti" - [(parallel [(set (match_operand:TI 0 "general_operand" "") - (match_operand:TI 1 "general_operand" "")) - (clobber (match_scratch:DI 2 ""))])] + [(set (match_operand:TI 0 "general_operand" "") + (match_operand:TI 1 "general_operand" ""))] "" { rtx op1 = ia64_expand_move (operands[0], operands[1]); @@ -599,8 +600,7 @@ (define_insn_and_split "*movti_internal" [(set (match_operand:TI 0 "nonimmediate_operand" "=r,r,m") - (match_operand:TI 1 "general_operand" "ri,m,r")) - (clobber (match_scratch:DI 2 "=X,&r,&r"))] + (match_operand:TI 1 "general_operand" "ri,m,r"))] "ia64_move_ok (operands[0], operands[1])" "#" "reload_completed" @@ -612,20 +612,6 @@ [(set_attr "itanium_class" "unknown") (set_attr "predicable" "no")]) -(define_expand "reload_inti" - [(parallel [(set (match_operand:TI 0 "register_operand" "=r") - (match_operand:TI 1 "memory_operand" "m")) - (clobber (match_operand:DI 2 "register_operand" "=&r"))])] - "" - "") - -(define_expand "reload_outti" - [(parallel [(set (match_operand:TI 0 "memory_operand" "=m") - (match_operand:TI 1 "register_operand" "r")) - (clobber (match_operand:DI 2 "register_operand" "=&r"))])] - "" - "") - ;; Floating Point Moves ;; ;; Note - Patterns for SF mode moves are compulsory, but @@ -764,13 +750,10 @@ [(set_attr "itanium_class" "fmisc,fld,stf")]) ;; Better code generation via insns that deal with TFmode register pairs -;; directly. -;; With no offsettable memory references, we've got to have a scratch -;; around to play with the second word. +;; directly. Same concerns apply as for TImode. (define_expand "movtf" - [(parallel [(set (match_operand:TF 0 "general_operand" "") - (match_operand:TF 1 "general_operand" "")) - (clobber (match_scratch:DI 2 ""))])] + [(set (match_operand:TF 0 "general_operand" "") + (match_operand:TF 1 "general_operand" ""))] "" { rtx op1 = ia64_expand_move (operands[0], operands[1]); @@ -781,8 +764,7 @@ (define_insn_and_split "*movtf_internal" [(set (match_operand:TF 0 "nonimmediate_operand" "=r,r,m") - (match_operand:TF 1 "general_operand" "ri,m,r")) - (clobber (match_scratch:DI 2 "=X,&r,&r"))] + (match_operand:TF 1 "general_operand" "ri,m,r"))] "ia64_move_ok (operands[0], operands[1])" "#" "reload_completed" @@ -794,19 +776,6 @@ [(set_attr "itanium_class" "unknown") (set_attr "predicable" "no")]) -(define_expand "reload_intf" - [(parallel [(set (match_operand:TF 0 "register_operand" "=r") - (match_operand:TF 1 "memory_operand" "m")) - (clobber (match_operand:DI 2 "register_operand" "=&r"))])] - "" - "") - -(define_expand "reload_outtf" - [(parallel [(set (match_operand:TF 0 "memory_operand" "=m") - (match_operand:TF 1 "register_operand" "r")) - (clobber (match_operand:DI 2 "register_operand" "=&r"))])] - "" - "") \f ;; :::::::::::::::::::: ;; :: -- http://gcc.gnu.org/bugzilla/show_bug.cgi?id=13772
next prev parent reply other threads:[~2004-01-22 10:41 UTC|newest] Thread overview: 8+ messages / expand[flat|nested] mbox.gz Atom feed top 2004-01-20 16:20 [Bug c++/13772] New: " reichelt at gcc dot gnu dot org 2004-01-20 16:25 ` [Bug optimization/13772] " pinskia at gcc dot gnu dot org 2004-01-22 10:41 ` zack at codesourcery dot com [this message] 2004-01-22 11:02 ` zack at codesourcery dot com 2004-01-22 13:07 ` schwab at suse dot de 2004-01-22 16:06 ` bangerth at dealii dot org 2004-01-22 19:45 ` rth at redhat dot com 2004-01-23 14:51 ` reichelt at gcc dot gnu dot org
Reply instructions: You may reply publicly to this message via plain-text email using any one of the following methods: * Save the following mbox file, import it into your mail client, and reply-to-all from there: mbox Avoid top-posting and favor interleaved quoting: https://en.wikipedia.org/wiki/Posting_style#Interleaved_style * Reply using the --to, --cc, and --in-reply-to switches of git-send-email(1): git send-email \ --in-reply-to=20040122104113.4359.qmail@sources.redhat.com \ --to=gcc-bugzilla@gcc.gnu.org \ --cc=gcc-bugs@gcc.gnu.org \ /path/to/YOUR_REPLY https://kernel.org/pub/software/scm/git/docs/git-send-email.html * If your mail client supports setting the In-Reply-To header via mailto: links, try the mailto: linkBe sure your reply has a Subject: header at the top and a blank line before the message body.
This is a public inbox, see mirroring instructions for how to clone and mirror all data and code used for this inbox; as well as URLs for read-only IMAP folder(s) and NNTP newsgroup(s).