aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorRichard Stallman <rms@gnu.org>1993-10-26 08:26:08 +0000
committerRichard Stallman <rms@gnu.org>1993-10-26 08:26:08 +0000
commit05f3fda388756b911406c06368d76fd410d84808 (patch)
treecacbf31471dc97fb173ff13bdd9d49737012f08d
parentfc51af1af8567e1c324e3dd62327b39dee6d1d30 (diff)
downloadgcc-05f3fda388756b911406c06368d76fd410d84808.zip
gcc-05f3fda388756b911406c06368d76fd410d84808.tar.gz
gcc-05f3fda388756b911406c06368d76fd410d84808.tar.bz2
(build_binary_op): For TRUNC_MOD_EXPR and FLOOR_MOD_EXPR,
don't shorten when divisor might be -1. From-SVN: r5893
-rw-r--r--gcc/c-typeck.c9
1 files changed, 8 insertions, 1 deletions
diff --git a/gcc/c-typeck.c b/gcc/c-typeck.c
index 3c6f08b..c12f775 100644
--- a/gcc/c-typeck.c
+++ b/gcc/c-typeck.c
@@ -1982,7 +1982,14 @@ build_binary_op (code, orig_op0, orig_op1, convert_p)
case TRUNC_MOD_EXPR:
case FLOOR_MOD_EXPR:
if (code0 == INTEGER_TYPE && code1 == INTEGER_TYPE)
- shorten = 1;
+ /* Although it would be tempting to shorten always here, doing so loses
+ on some targets, since the modulo instruction is undefined if the
+ quotient can't be represented in the computation mode. We shorten
+ only if unsigned or if dividing by something we know != -1. */
+ shorten = (TREE_UNSIGNED (orig_op0)
+ || (TREE_CODE (op1) == INTEGER_CST
+ && (TREE_INT_CST_LOW (op1) != -1
+ || TREE_INT_CST_HIGH (op1) != -1)));
break;
case TRUTH_ANDIF_EXPR: