Path: utzoo!utgpu!jarvis.csri.toronto.edu!mailrus!purdue!bu-cs!ncsuvx!mcnc!rti!xyzzy!wood From: wood@dg-rtp.dg.com (Tom Wood) Newsgroups: gnu.gcc.bug Subject: Re: Is (subreg:SI (mem:QI ...)) valid or what Message-ID: <2025@xyzzy.UUCP> Date: 20 Oct 89 21:49:13 GMT References: <2012@xyzzy.UUCP> Sender: usenet@xyzzy.UUCP Reply-To: wood@bert.dg.com (Tom Wood) Distribution: na Organization: Data General Corporation, Research Triangle Park, NC Lines: 101 I found more about what is causing the widening subreg problem. A change to expand_binop\optabs.c attempts to use widening subreg around narrow operands to logical operators instead of only using convert_move as was the case in 1.35. This works fine, and in fact saves instructions in the non-optimized case. The trouble is that combine is unable to deal with this construct in the same way it deals with sign_extend & zero_extend. Here again is the test case: typedef struct { unsigned int a:5; double b; } T; void set_T(p) T *p; { p->a = 5; p->b = 2.0; } Here's the RTL after flow analysis (just before combine): (insn 8 6 9 (set (reg:QI 33) (mem:QI (reg/v:SI 32))) -1 (insn_list 4 (nil)) (nil)) (insn 9 8 10 (set (reg:SI 34) (and:SI (subreg:SI (reg:QI 33) 0) (const_int 7))) -1 (insn_list 8 (nil)) (expr_list:REG_DEAD (reg:QI 33) (nil))) (insn 10 9 11 (set (reg:QI 35) (subreg:QI (reg:SI 34) 0)) -1 (insn_list 9 (nil)) (expr_list:REG_DEAD (reg:SI 34) (nil))) Combine produces this: (insn 8 6 9 (set (reg:QI 33) (mem:QI (reg/v:SI 32))) -1 (insn_list 4 (nil)) (nil)) (insn 9 8 10 (set (reg:SI 34) (and:SI (subreg:SI (reg:QI 33) 0) (const_int 7))) -1 (insn_list 8 (nil)) (expr_list:REG_DEAD (reg:QI 33) (nil))) The trouble is that unless these are combined further, later passes go wrong. The RTL wants to look like this. (insn 12 11 13 (set (reg:SI 38) (and:SI (subreg:SI (mem:QI (reg/v:SI 32)) 0) (const_int 7))) 236 (insn_list 11 (insn_list 10 (insn_list 9 (insn_list 8 (insn_list 4 (nil)))))) (nil)) My fix is truly a kludge. If you're not optimizing, go ahead with the widening subreg form. Otherwise, explictitly use zero_extend or sign_extend which combine is able to deal with. Here's the patch: *** optabs.c.orig Fri Oct 20 17:37:58 1989 --- optabs.c Fri Oct 20 17:41:17 1989 *************** *** 308,314 **** if (no_extend) { temp = force_reg (GET_MODE (xop0), xop0); ! xop0 = gen_rtx (optimize ? unsignedp ? ZERO_EXTEND : SIGN_EXTEND : SUBREG, wider_mode, temp, 0); } else { --- 308,314 ---- if (no_extend) { temp = force_reg (GET_MODE (xop0), xop0); ! xop0 = gen_rtx (SUBREG, wider_mode, temp, 0); } else { *************** *** 322,328 **** if (no_extend) { temp = force_reg (GET_MODE (xop1), xop1); ! xop1 = gen_rtx (optimize ? unsignedp ? ZERO_EXTEND : SIGN_EXTEND : SUBREG, wider_mode, temp, 0); } else { --- 322,328 ---- if (no_extend) { temp = force_reg (GET_MODE (xop1), xop1); ! xop1 = gen_rtx (SUBREG, wider_mode, temp, 0); } else { Comments? --- Tom Wood (919) 248-6067 Data General, Research Triangle Park, NC {the known world}!rti!xyzzy!wood