shithub: scc

Download patch

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;