diff options
Diffstat (limited to 'gcc')
-rw-r--r-- | gcc/ChangeLog | 6 | ||||
-rw-r--r-- | gcc/simplify-rtx.c | 9 | ||||
-rw-r--r-- | gcc/testsuite/ChangeLog | 2 | ||||
-rw-r--r-- | gcc/testsuite/gcc.c-torture/compile/20020103-1.c | 22 |
4 files changed, 38 insertions, 1 deletions
diff --git a/gcc/ChangeLog b/gcc/ChangeLog index 38ba6c5..ded183f 100644 --- a/gcc/ChangeLog +++ b/gcc/ChangeLog @@ -1,4 +1,10 @@ +2002-01-03 Jakub Jelinek <jakub@redhat.com> + + * simplify-rtx.c (simplify_binary_operation) [DIV]: If + gen_lowpart_common fails, use gen_lowpart_SUBREG. + 2002-01-03 Turly O'Connor <turly@apple.com> + * darwin.c (machopic_output_possible_stub_label): Don't generate stub routines for pseudo-stubs which we've just defined. diff --git a/gcc/simplify-rtx.c b/gcc/simplify-rtx.c index 49c205c..84209cc 100644 --- a/gcc/simplify-rtx.c +++ b/gcc/simplify-rtx.c @@ -1413,8 +1413,15 @@ simplify_binary_operation (code, mode, op0, op1) case DIV: if (trueop1 == CONST1_RTX (mode)) { + /* On some platforms DIV uses narrower mode than its + operands. */ rtx x = gen_lowpart_common (mode, op0); - return x ? x : op0; + if (x) + return x; + else if (mode != GET_MODE (op0) && GET_MODE (op0) != VOIDmode) + return gen_lowpart_SUBREG (mode, op0); + else + return op0; } /* In IEEE floating point, 0/x is not always 0. */ diff --git a/gcc/testsuite/ChangeLog b/gcc/testsuite/ChangeLog index 0fd9701..1838539 100644 --- a/gcc/testsuite/ChangeLog +++ b/gcc/testsuite/ChangeLog @@ -2,6 +2,8 @@ * g++.dg/other/debug2.C: New test. + * gcc.c-torture/compile/20020103-1.c: New test. + 2002-01-02 Jakub Jelinek <jakub@redhat.com> * gcc.dg/gnu89-init-1.c: Added new tests. diff --git a/gcc/testsuite/gcc.c-torture/compile/20020103-1.c b/gcc/testsuite/gcc.c-torture/compile/20020103-1.c new file mode 100644 index 0000000..b986168 --- /dev/null +++ b/gcc/testsuite/gcc.c-torture/compile/20020103-1.c @@ -0,0 +1,22 @@ +/* This testcase failed on Alpha at -O2 when simplifying conditional + expressions. */ + +int foo (void); + +struct A +{ + int a, b, c, d; +}; + +void bar (struct A *x) +{ + int e, f; + + e = foo (); + e = e / x->b; + if (e < 1) + e = 1; + f = (x->a + x->c) / e; + if (f < x->d) + x->d -= (1 << 16) / 8; +} |