shithub: scc

Download patch

ref: 4343d4491f8251b0af5065d3898a2dc7cf8abf2f
parent: 198b6ea63a13382db039b8cf21a5b4798d62c659
author: Roberto E. Vargas Caballero <[email protected]>
date: Sat Sep 5 15:54:51 EDT 2015

Add more identities for logic operators

--- a/cc1/fold.c
+++ b/cc1/fold.c
@@ -376,42 +376,51 @@
 	return v;
 }
 
-/*
- * 0 || i => i
- * 1 || i => 1
- * 0 && i => 0
- * 1 && i => i
- * i >> 0 => i
- * i << 0 => i
- * i + 0  => i
- * i - 0  => i
- * i | 0  => i
- * i ^ 0  => i
- * i * 0  => i,0
- * i * 1  => i
- * i / 1  => i
- * i & ~0 => i
- * i % 1  => i,1
- */
 static Node *
 identity(int *op, Node *lp, Node *rp)
 {
-	int iszero, isone, istrue, val;
+	int iszeror, isoner, istruer, val;
+	int iszerol, isonel, istruel;
 
 	if (!rp)
 		return NULL;
 
-	iszero = cmpnode(rp, 0);
-	isone = cmpnode(rp, 1),
-	istrue = !iszero && rp->constant;
+	iszeror = cmpnode(rp, 0);
+	isoner = cmpnode(rp, 1),
+	istruer = !iszeror && rp->constant;
+	iszerol = cmpnode(lp, 0);
+	isonel = cmpnode(lp, 1),
+	istruel = !iszerol && lp->constant;
 
 	switch (*op) {
 	case OOR:
-		val = 1;
-		goto logic_operator;
+		/*
+		 * 1 || i => 1    (free right)
+		 * i || 0 => i    (free right)
+		 * 0 || i => i    (free left)
+		 * i || 1 => i,1  (comma)
+		 */
+		if (isonel | iszeror)
+			goto free_right;
+		if (iszerol)
+			goto free_left;
+		if (isoner)
+			goto change_to_comma;
+		return NULL;
 	case OAND:
-		val = 0;
-		goto logic_operator;
+		/*
+		 * 0 && i => 0    (free right)
+		 * i && 1 => i    (free right)
+		 * 1 && i => i    (free left)
+		 * i && 0 => i,0  (comma)
+		 */
+		if (iszerol | isoner)
+			goto free_right;
+		if (isonel)
+			goto free_left;
+		if (iszeror)
+			goto change_to_comma;
+		return NULL;
 	case OSHL:
 	case OSHR:
 	case OBXOR:
@@ -418,40 +427,52 @@
 	case OADD:
 	case OBOR:
 	case OSUB:
-		if (iszero)
+		/*
+		 * i >> 0 => i
+		 * i << 0 => i
+		 * i + 0  => i
+		 * i - 0  => i
+		 * i | 0  => i
+		 * i ^ 0  => i
+		 */
+		if (iszeror)
 			goto free_right;
 		return NULL;
 	case OMUL:
-		if (iszero)
+		/*
+		 * i * 0  => i,0
+		 * i * 1  => i
+		 */
+		if (iszeror)
 			goto change_to_comma;
+		if (isoner)
+			goto free_right;
+		return NULL;
 	case ODIV:
-		if (isone)
+		/* i / 1  => i */
+		if (isoner)
 			goto free_right;
 		return NULL;
 	case OBAND:
+		/* i & ~0 => i */
 		if (cmpnode(rp, ones(lp->type->size * 8)))
 			goto free_right;
 		return NULL;
 	case OMOD:
-		if (isone)
+		/* i % 1  => i,1 */
+		if (isoner)
 			goto change_to_comma;
 	default:
 		return NULL;
 	}
 
-logic_operator:
-	if (!lp->constant)
-		return NULL;
-	if (cmpnode(lp, val))
-		goto free_right;
+free_right:
+	freetree(rp);
+	return lp;
 
 free_left:
 	freetree(lp);
 	return rp;
-
-free_right:
-	freetree(rp);
-	return lp;
 
 change_to_comma:
 	*op = OCOMMA;