This is the mail archive of the
gcc-patches@gcc.gnu.org
mailing list for the GCC project.
[PATCH] Fix c++/4574 (take 2)
- From: Jakub Jelinek <jakub at redhat dot com>
- To: Richard Henderson <rth at redhat dot com>
- Cc: gcc-patches at gcc dot gnu dot org
- Date: Thu, 21 Feb 2002 21:22:53 +0100
- Subject: [PATCH] Fix c++/4574 (take 2)
- Reply-to: Jakub Jelinek <jakub at redhat dot com>
Hi!
Here is a reworked patch to fix PR 4574 - expand_and gets mode as its first
arguments and uses it to expand constant bitwise and.
While changing c4x expand_and calls, I have noticed it uses
gen_rtx (CONST_INT, VOIDmode, x)
everywhere instead of GEN_INT (x), so I've changed that too.
Bootstrapped on i386-redhat-linux, no regressions.
Ok to commit?
2002-02-20 Jakub Jelinek <jakub@redhat.com>
PR c++/4574
* expr.h (expand_and): Add mode argument.
* expmed.c (expand_and): Add mode argument.
(expand_mult_highpart_adjust, emit_store_flag): Adjust callers.
* expr.c (store_field, expand_expr, do_store_flag): Likewise.
* except.c (expand_builtin_extract_return_addr): Likewise.
* config/alpha/alpha.c (alpha_initialize_trampoline): Likewise.
* config/sparc/sparc.c (sparc_initialize_trampoline): Likewise.
* config/c4x/c4x.h (INITIALIZE_TRAMPOLINE): Likewise.
Use GEN_INT (x) instead of gen_rtx (CONST_INT, VOIDmode, x).
* config/c4x/c4x.md: Use GEN_INT (x) instead of
gen_rtx (CONST_INT, VOIDmode, x).
* gcc.dg/20020220-1.c: New test.
--- gcc/config/alpha/alpha.c.jj Mon Feb 18 17:44:51 2002
+++ gcc/config/alpha/alpha.c Thu Feb 21 14:22:57 2002
@@ -5503,12 +5503,13 @@ alpha_initialize_trampoline (tramp, fnad
OPTAB_WIDEN);
temp = expand_shift (RSHIFT_EXPR, Pmode, temp,
build_int_2 (2, 0), NULL_RTX, 1);
- temp = expand_and (gen_lowpart (SImode, temp), GEN_INT (0x3fff), 0);
+ temp = expand_and (SImode, gen_lowpart (SImode, temp),
+ GEN_INT (0x3fff), 0);
/* Merge in the hint. */
addr = memory_address (SImode, plus_constant (tramp, jmpofs));
temp1 = force_reg (SImode, gen_rtx_MEM (SImode, addr));
- temp1 = expand_and (temp1, GEN_INT (0xffffc000), NULL_RTX);
+ temp1 = expand_and (SImode, temp1, GEN_INT (0xffffc000), NULL_RTX);
temp1 = expand_binop (SImode, ior_optab, temp1, temp, temp1, 1,
OPTAB_WIDEN);
emit_move_insn (gen_rtx_MEM (SImode, addr), temp1);
--- gcc/config/c4x/c4x.h.jj Tue Jan 22 14:14:52 2002
+++ gcc/config/c4x/c4x.h Thu Feb 21 14:28:46 2002
@@ -2169,32 +2169,26 @@ do { fprintf (asm_out_file, "\t.sdef\t")
tmp1 = expand_shift (RSHIFT_EXPR, QImode, FNADDR, \
size_int (16), 0, 1); \
tmp2 = expand_shift (LSHIFT_EXPR, QImode, \
- gen_rtx (CONST_INT, VOIDmode, 0x5069), \
- size_int (16), 0, 1); \
+ GEN_INT (0x5069), size_int (16), 0, 1); \
emit_insn (gen_iorqi3 (tmp1, tmp1, tmp2)); \
emit_move_insn (gen_rtx (MEM, QImode, \
plus_constant (tramp, 0)), tmp1); \
- tmp1 = expand_and (FNADDR, gen_rtx (CONST_INT, VOIDmode, \
- 0xffff), 0); \
+ tmp1 = expand_and (QImode, FNADDR, GEN_INT (0xffff), 0); \
tmp2 = expand_shift (LSHIFT_EXPR, QImode, \
- gen_rtx (CONST_INT, VOIDmode, 0x1069), \
- size_int (16), 0, 1); \
+ GEN_INT (0x1069), size_int (16), 0, 1); \
emit_insn (gen_iorqi3 (tmp1, tmp1, tmp2)); \
emit_move_insn (gen_rtx (MEM, QImode, \
plus_constant (tramp, 2)), tmp1); \
tmp1 = expand_shift (RSHIFT_EXPR, QImode, CXT, \
size_int (16), 0, 1); \
tmp2 = expand_shift (LSHIFT_EXPR, QImode, \
- gen_rtx (CONST_INT, VOIDmode, 0x5068), \
- size_int (16), 0, 1); \
+ GEN_INT (0x5068), size_int (16), 0, 1); \
emit_insn (gen_iorqi3 (tmp1, tmp1, tmp2)); \
emit_move_insn (gen_rtx (MEM, QImode, \
plus_constant (tramp, 3)), tmp1); \
- tmp1 = expand_and (CXT, gen_rtx (CONST_INT, VOIDmode, \
- 0xffff), 0); \
+ tmp1 = expand_and (QImode, CXT, GEN_INT (0xffff), 0); \
tmp2 = expand_shift (LSHIFT_EXPR, QImode, \
- gen_rtx (CONST_INT, VOIDmode, 0x1068), \
- size_int (16), 0, 1); \
+ GEN_INT (0x1068), size_int (16), 0, 1); \
emit_insn (gen_iorqi3 (tmp1, tmp1, tmp2)); \
emit_move_insn (gen_rtx (MEM, QImode, \
plus_constant (tramp, 6)), tmp1); \
--- gcc/config/c4x/c4x.md.jj Wed Jan 9 14:32:25 2002
+++ gcc/config/c4x/c4x.md Thu Feb 21 14:31:18 2002
@@ -984,8 +984,8 @@
(set (match_dup 0) (ior:QI (match_dup 0) (match_dup 3)))]
"
{
- operands[2] = gen_rtx (CONST_INT, VOIDmode, INTVAL (operands[1]) & ~0xffff);
- operands[3] = gen_rtx (CONST_INT, VOIDmode, INTVAL (operands[1]) & 0xffff);
+ operands[2] = GEN_INT (INTVAL (operands[1]) & ~0xffff);
+ operands[3] = GEN_INT (INTVAL (operands[1]) & 0xffff);
}")
(define_split
@@ -1000,8 +1000,8 @@
(set (match_dup 0) (ior:QI (match_dup 0) (match_dup 3)))]
"
{
- operands[2] = gen_rtx (CONST_INT, VOIDmode, INTVAL (operands[1]) & ~0xffff);
- operands[3] = gen_rtx (CONST_INT, VOIDmode, INTVAL (operands[1]) & 0xffff);
+ operands[2] = GEN_INT (INTVAL (operands[1]) & ~0xffff);
+ operands[3] = GEN_INT (INTVAL (operands[1]) & 0xffff);
}")
(define_split
@@ -1022,8 +1022,8 @@
operands[2] = gen_rtx (CONST_INT, VOIDmode,
(((INTVAL (operands[1]) >> 16) & 0xffff)
- 0x8000) ^ ~0x7fff);
- operands[3] = gen_rtx (CONST_INT, VOIDmode, INTVAL (operands[1]) & 0xffff);
- operands[4] = gen_rtx (CONST_INT, VOIDmode, 16);
+ operands[3] = GEN_INT (INTVAL (operands[1]) & 0xffff);
+ operands[4] = GEN_INT (16);
}")
(define_split
@@ -1043,8 +1043,8 @@
operands[2] = gen_rtx (CONST_INT, VOIDmode,
(((INTVAL (operands[1]) >> 16) & 0xffff)
- 0x8000) ^ ~0x7fff);
- operands[3] = gen_rtx (CONST_INT, VOIDmode, INTVAL (operands[1]) & 0xffff);
- operands[4] = gen_rtx (CONST_INT, VOIDmode, 16);
+ operands[3] = GEN_INT (INTVAL (operands[1]) & 0xffff);
+ operands[4] = GEN_INT (16);
}")
(define_split
@@ -1063,10 +1063,9 @@
/* Generate two's complement value of MSBs. */
int shift = c4x_shiftable_constant (operands[1]);
- operands[2] = gen_rtx (CONST_INT, VOIDmode,
- (((INTVAL (operands[1]) >> shift) & 0xffff)
+ operands[2] = GEN_INT ((((INTVAL (operands[1]) >> shift) & 0xffff)
- 0x8000) ^ ~0x7fff);
- operands[3] = gen_rtx (CONST_INT, VOIDmode, shift);
+ operands[3] = GEN_INT (shift);
}")
(define_split
@@ -1084,10 +1083,9 @@
/* Generate two's complement value of MSBs. */
int shift = c4x_shiftable_constant (operands[1]);
- operands[2] = gen_rtx (CONST_INT, VOIDmode,
- (((INTVAL (operands[1]) >> shift) & 0xffff)
- - 0x8000) ^ ~0x7fff);
- operands[3] = gen_rtx (CONST_INT, VOIDmode, shift);
+ operands[2] = GEN_INT ((((INTVAL (operands[1]) >> shift) & 0xffff)
+ - 0x8000) ^ ~0x7fff);
+ operands[3] = GEN_INT (shift);
}")
(define_split
--- gcc/config/sparc/sparc.c.jj Tue Feb 12 16:19:19 2002
+++ gcc/config/sparc/sparc.c Thu Feb 21 14:32:17 2002
@@ -6292,13 +6292,15 @@ sparc_initialize_trampoline (tramp, fnad
emit_move_insn (gen_rtx_MEM (SImode, plus_constant (tramp, 8)),
expand_binop (SImode, ior_optab,
- expand_and (fnaddr, GEN_INT (0x3ff), NULL_RTX),
+ expand_and (SImode, fnaddr, GEN_INT (0x3ff),
+ NULL_RTX),
GEN_INT (0x81c06000),
NULL_RTX, 1, OPTAB_DIRECT));
emit_move_insn (gen_rtx_MEM (SImode, plus_constant (tramp, 12)),
expand_binop (SImode, ior_optab,
- expand_and (cxt, GEN_INT (0x3ff), NULL_RTX),
+ expand_and (SImode, cxt, GEN_INT (0x3ff),
+ NULL_RTX),
GEN_INT (0x8410a000),
NULL_RTX, 1, OPTAB_DIRECT));
--- gcc/testsuite/gcc.dg/20020220-1.c.jj Wed Feb 20 20:35:39 2002
+++ gcc/testsuite/gcc.dg/20020220-1.c Wed Feb 20 20:35:13 2002
@@ -0,0 +1,19 @@
+/* PR c++/4574
+ This testcase ICEd because expand_and does not handle VOIDmode
+ CONST_DOUBLE arguments. */
+/* { dg-do compile } */
+/* { dg-options "-w" } */
+
+struct A {
+ unsigned long long b : 8;
+ unsigned long long c : 18;
+};
+
+int main()
+{
+ struct A a;
+ long long l;
+
+ l = a.c = 0x123456789aULL;
+ return 0;
+}
--- gcc/expr.h.jj Fri Dec 14 13:05:07 2001
+++ gcc/expr.h Thu Feb 21 13:52:36 2002
@@ -308,7 +308,7 @@ int can_conditionally_move_p PARAMS ((en
extern rtx negate_rtx PARAMS ((enum machine_mode, rtx));
/* Expand a logical AND operation. */
-extern rtx expand_and PARAMS ((rtx, rtx, rtx));
+extern rtx expand_and PARAMS ((enum machine_mode, rtx, rtx, rtx));
/* Emit a store-flag operation. */
extern rtx emit_store_flag PARAMS ((rtx, enum rtx_code, rtx, rtx,
--- gcc/except.c.jj Thu Jan 17 19:26:08 2002
+++ gcc/except.c Thu Feb 21 13:57:51 2002
@@ -3088,7 +3088,7 @@ expand_builtin_extract_return_addr (addr
/* First mask out any unwanted bits. */
#ifdef MASK_RETURN_ADDR
- expand_and (addr, MASK_RETURN_ADDR, addr);
+ expand_and (Pmode, addr, MASK_RETURN_ADDR, addr);
#endif
/* Then adjust to find the real return address. */
--- gcc/expmed.c.jj Tue Feb 19 11:13:09 2002
+++ gcc/expmed.c Thu Feb 21 14:22:01 2002
@@ -2714,7 +2714,7 @@ expand_mult_highpart_adjust (mode, adj_o
tem = expand_shift (RSHIFT_EXPR, mode, op0,
build_int_2 (GET_MODE_BITSIZE (mode) - 1, 0),
NULL_RTX, 0);
- tem = expand_and (tem, op1, NULL_RTX);
+ tem = expand_and (mode, tem, op1, NULL_RTX);
adj_operand
= force_operand (gen_rtx_fmt_ee (adj_code, mode, adj_operand, tem),
adj_operand);
@@ -2722,7 +2722,7 @@ expand_mult_highpart_adjust (mode, adj_o
tem = expand_shift (RSHIFT_EXPR, mode, op1,
build_int_2 (GET_MODE_BITSIZE (mode) - 1, 0),
NULL_RTX, 0);
- tem = expand_and (tem, op0, NULL_RTX);
+ tem = expand_and (mode, tem, op0, NULL_RTX);
target = force_operand (gen_rtx_fmt_ee (adj_code, mode, adj_operand, tem),
target);
@@ -4156,23 +4156,16 @@ expand_mult_add (x, target, mult, add, m
If TARGET is 0, a pseudo-register or constant is returned. */
rtx
-expand_and (op0, op1, target)
+expand_and (mode, op0, op1, target)
+ enum machine_mode mode;
rtx op0, op1, target;
{
- enum machine_mode mode = VOIDmode;
- rtx tem;
-
- if (GET_MODE (op0) != VOIDmode)
- mode = GET_MODE (op0);
- else if (GET_MODE (op1) != VOIDmode)
- mode = GET_MODE (op1);
+ rtx tem = 0;
- if (mode != VOIDmode)
+ if (GET_MODE (op0) == VOIDmode && GET_MODE (op1) == VOIDmode)
+ tem = simplify_binary_operation (AND, mode, op0, op1);
+ if (tem == 0)
tem = expand_binop (mode, and_optab, op0, op1, target, 0, OPTAB_LIB_WIDEN);
- else if (GET_CODE (op0) == CONST_INT && GET_CODE (op1) == CONST_INT)
- tem = GEN_INT (INTVAL (op0) & INTVAL (op1));
- else
- abort ();
if (target == 0)
target = tem;
@@ -4430,7 +4423,7 @@ emit_store_flag (target, code, op0, op1,
subtarget, normalizep == 1);
else if (STORE_FLAG_VALUE & 1)
{
- op0 = expand_and (op0, const1_rtx, subtarget);
+ op0 = expand_and (compare_mode, op0, const1_rtx, subtarget);
if (normalizep == -1)
op0 = expand_unop (compare_mode, neg_optab, op0, op0, 0);
}
--- gcc/expr.c.jj Tue Feb 19 11:13:09 2002
+++ gcc/expr.c Thu Feb 21 14:33:34 2002
@@ -5143,18 +5143,16 @@ store_field (target, bitsize, bitpos, mo
tree count;
enum machine_mode tmode;
- if (unsignedp)
- return expand_and (temp,
- GEN_INT
- (trunc_int_for_mode
- (width_mask,
- GET_MODE (temp) == VOIDmode
- ? value_mode
- : GET_MODE (temp))), NULL_RTX);
-
tmode = GET_MODE (temp);
if (tmode == VOIDmode)
tmode = value_mode;
+
+ if (unsignedp)
+ return expand_and (tmode, temp,
+ GEN_INT (trunc_int_for_mode (width_mask,
+ tmode)),
+ NULL_RTX);
+
count = build_int_2 (GET_MODE_BITSIZE (tmode) - bitsize, 0);
temp = expand_shift (LSHIFT_EXPR, tmode, temp, count, 0, 0);
return expand_shift (RSHIFT_EXPR, tmode, temp, count, 0, 0);
@@ -6785,16 +6783,16 @@ expand_expr (exp, target, tmode, modifie
{
HOST_WIDE_INT bitsize
= TREE_INT_CST_LOW (DECL_SIZE (TREE_PURPOSE (elt)));
+ enum machine_mode imode
+ = TYPE_MODE (TREE_TYPE (TREE_PURPOSE (elt)));
if (TREE_UNSIGNED (TREE_TYPE (TREE_PURPOSE (elt))))
{
op1 = GEN_INT (((HOST_WIDE_INT) 1 << bitsize) - 1);
- op0 = expand_and (op0, op1, target);
+ op0 = expand_and (imode, op0, op1, target);
}
else
{
- enum machine_mode imode
- = TYPE_MODE (TREE_TYPE (TREE_PURPOSE (elt)));
tree count
= build_int_2 (GET_MODE_BITSIZE (imode) - bitsize,
0);
@@ -10222,7 +10220,7 @@ do_store_flag (exp, target, mode, only_c
/* Put the AND last so it can combine with more things. */
if (bitnum != TYPE_PRECISION (type) - 1)
- op0 = expand_and (op0, const1_rtx, subtarget);
+ op0 = expand_and (mode, op0, const1_rtx, subtarget);
return op0;
}
Jakub