commit 7e457b1611c514787ce2f3c7c04b0fc46aa32850
parent 03a906c70a3836ad264de982a5c7fc0bfe9cf0ef
Author: Roberto E. Vargas Caballero <k0ga@shike2.com>
Date: Fri, 4 Sep 2015 22:47:56 +0200
Fix algebraic identities about logical operators
If the right part of a logic operator is a constant (which comes from
the folding of some comparision), then the logic operator can be
changed to a comma operator.
Diffstat:
M | cc1/fold.c | | | 34 | ++++++++++++++++++++++++---------- |
1 file changed, 24 insertions(+), 10 deletions(-)
diff --git a/cc1/fold.c b/cc1/fold.c
@@ -377,8 +377,10 @@ ones(int n)
}
/*
- * i || k => i,k
- * i && k => i,k
+ * 0 || i => i
+ * 1 || i => 1
+ * 0 && i => 0
+ * 1 && i => i
* i >> 0 => i
* i << 0 => i
* i + 0 => i
@@ -394,7 +396,7 @@ ones(int n)
static Node *
identity(int *op, Node *lp, Node *rp)
{
- int iszero, isone, istrue;
+ int iszero, isone, istrue, val;
if (!rp)
return NULL;
@@ -404,11 +406,12 @@ identity(int *op, Node *lp, Node *rp)
istrue = !iszero && rp->constant;
switch (*op) {
- case OAND:
case OOR:
- if (rp->constant)
- goto change_to_comma;
- return NULL;
+ val = 1;
+ goto logic_operator;
+ case OAND:
+ val = 0;
+ goto logic_operator;
case OSHL:
case OSHR:
case OBXOR:
@@ -416,18 +419,18 @@ identity(int *op, Node *lp, Node *rp)
case OBOR:
case OSUB:
if (iszero)
- break;
+ goto free_right;
return NULL;
case OMUL:
if (iszero)
goto change_to_comma;
case ODIV:
if (isone)
- break;
+ goto free_right;
return NULL;
case OBAND:
if (cmpnode(rp, ones(lp->type->size * 8)))
- break;
+ goto free_right;
return NULL;
case OMOD:
if (isone)
@@ -436,6 +439,17 @@ identity(int *op, Node *lp, Node *rp)
return NULL;
}
+logic_operator:
+ if (!lp->constant)
+ return NULL;
+ if (cmpnode(lp, val))
+ goto free_right;
+
+free_left:
+ freetree(lp);
+ return rp;
+
+free_right:
freetree(rp);
return lp;