On Mon, Apr 30, 2012 at 3:10 PM, Jakub Jelinek <ja...@redhat.com> wrote: > On Mon, Apr 30, 2012 at 02:54:05PM +0200, Uros Bizjak wrote: >> > My recent changes to zero_extend expanders should handle this >> > automatically, and will undo generation of zero_extend pattern. Please >> > see zero_extend<mode>si2_and expander, and how it handles >> > TARGET_ZERO_EXTEND_WITH_AND targets. >> >> Attached patch implements this idea. In addition, it fixes the >> splitter to not change output mode of zero_extension from HImode and >> QImode from DImode to SImode. Although they generate the same >> instruction, I think we should better keep original mode here. > > Thanks. I was trying this morning slightly different patch for the same, > but strangely it failed bootstrap, and didn't get around to analysing > why a mem store had (zero_extend (subreg (reg))) on a RHS. > >> + operands[1] = gen_lowpart (mode, operands[1]); >> + >> + if (GET_MODE (operands[0]) == DImode) >> + insn = (mode == SImode) >> + ? gen_zero_extendsidi2 >> + : (mode == HImode) >> + ? gen_zero_extendhidi2 >> + : gen_zero_extendqidi2; >> + else if (GET_MODE (operands[0]) == SImode) >> + insn = (mode == HImode) >> + ? gen_zero_extendhisi2 >> + : gen_zero_extendqisi2; >> + else if (GET_MODE (operands[0]) == HImode) >> + insn = gen_zero_extendqihi2; >> else >> - ix86_expand_binary_operator (AND, <MODE>mode, operands); >> + gcc_unreachable (); >> + >> + emit_insn (insn (operands[0], operands[1])); > > IMHO you should use <MODE>mode instead of GET_MODE (operands[0]) > in all of the above, then the compiler can actually optimize > it at compile time.
2012-04-30 Uros Bizjak <ubiz...@gmail.com> * config/i386/i386.md (and<mode>3): Change runtime operand mode checks to compile-time "mode == <MODE>mode" checks. (and splitter): Ditto. Tested on x86_64-pc-linux-gnu, committed to mainline SVN. Uros.
Index: config/i386/i386.md =================================================================== --- config/i386/i386.md (revision 186992) +++ config/i386/i386.md (working copy) @@ -7695,7 +7695,7 @@ (match_operand:SWIM 2 "<general_szext_operand>")))] "" { - enum machine_mode mode = GET_MODE (operands[1]); + enum machine_mode mode = <MODE>mode; rtx (*insn) (rtx, rtx); if (CONST_INT_P (operands[2]) && REG_P (operands[0])) @@ -7710,30 +7710,28 @@ mode = QImode; } - if (mode == GET_MODE (operands[1])) + if (mode == <MODE>mode) { ix86_expand_binary_operator (AND, <MODE>mode, operands); DONE; } - operands[1] = gen_lowpart (mode, operands[1]); - - if (GET_MODE (operands[0]) == DImode) + if (<MODE>mode == DImode) insn = (mode == SImode) ? gen_zero_extendsidi2 : (mode == HImode) ? gen_zero_extendhidi2 : gen_zero_extendqidi2; - else if (GET_MODE (operands[0]) == SImode) + else if (<MODE>mode == SImode) insn = (mode == HImode) ? gen_zero_extendhisi2 : gen_zero_extendqisi2; - else if (GET_MODE (operands[0]) == HImode) + else if (<MODE>mode == HImode) insn = gen_zero_extendqihi2; else gcc_unreachable (); - emit_insn (insn (operands[0], operands[1])); + emit_insn (insn (operands[0], gen_lowpart (mode, operands[1]))); DONE; }) @@ -7884,9 +7882,7 @@ mode = QImode; } - operands[1] = gen_lowpart (mode, operands[1]); - - if (GET_MODE (operands[0]) == DImode) + if (<MODE>mode == DImode) insn = (mode == SImode) ? gen_zero_extendsidi2 : (mode == HImode) @@ -7894,14 +7890,15 @@ : gen_zero_extendqidi2; else { - /* Zero extend to SImode to avoid partial register stalls. */ - operands[0] = gen_lowpart (SImode, operands[0]); + if (<MODE>mode != SImode) + /* Zero extend to SImode to avoid partial register stalls. */ + operands[0] = gen_lowpart (SImode, operands[0]); insn = (mode == HImode) ? gen_zero_extendhisi2 : gen_zero_extendqisi2; } - emit_insn (insn (operands[0], operands[1])); + emit_insn (insn (operands[0], gen_lowpart (mode, operands[1]))); DONE; })