ref: 7e457b1611c514787ce2f3c7c04b0fc46aa32850
parent: 03a906c70a3836ad264de982a5c7fc0bfe9cf0ef
author: Roberto E. Vargas Caballero <[email protected]>
date: Fri Sep 4 18:47:56 EDT 2015
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.
--- a/cc1/fold.c
+++ b/cc1/fold.c
@@ -377,8 +377,10 @@
}
/*
- * 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 @@
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 @@
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,7 +419,7 @@
case OBOR:
case OSUB:
if (iszero)
- break;
+ goto free_right;
return NULL;
case OMUL:
if (iszero)
@@ -423,11 +426,11 @@
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 @@
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;