More precisely, treat (0 << x) and so on as constant expressions, but not if const_wanted as we do not want to allow "case (x*0):", ... Do not optimise (0 / x) and (0 % x) here as x might be zero, though for an architecture that does not generate an exception for division by zero the back end might choose to optimise those.
Unified · Split
| @@ -1476,16 +1476,31 @@ static void gen_opic(int op) · 1475 unmodified lines | ||
| 1476 | 1476 | c2 = c1; //c = c1, c1 = c2, c2 = c; |
| 1477 | 1477 | l2 = l1; //l = l1, l1 = l2, l2 = l; |
| 1478 | 1478 | } |
| 1479 | − /* Filter out NOP operations like x*1, x-0, x&-1... */ | |
| 1480 | − if (c2 && (((op == '*' || op == '/' || op == TOK_UDIV || | |
| 1481 | − op == TOK_PDIV) && | |
| 1482 | − l2 == 1) || | |
| 1483 | − ((op == '+' || op == '-' || op == '|' || op == '^' || | |
| 1484 | − op == TOK_SHL || op == TOK_SHR || op == TOK_SAR) && | |
| 1485 | − l2 == 0) || | |
| 1486 | − (op == '&' && | |
| 1487 | − l2 == -1))) { | |
| 1488 | − /* nothing to do */ | |
| 1479 | + if (!const_wanted && | |
| 1480 | + c1 && ((l1 == 0 && | |
| 1481 | + (op == TOK_SHL || op == TOK_SHR || op == TOK_SAR)) || | |
| 1482 | + (l1 == -1 && op == TOK_SAR))) { | |
| 1483 | + /* treat (0 << x), (0 >> x) and (-1 >> x) as constant */ | |
| 1484 | + vtop--; | |
| 1485 | + } else if (!const_wanted && | |
| 1486 | + c2 && ((l2 == 0 && (op == '&' || op == '*')) || | |
| 1487 | + (l2 == -1 && op == '|') || | |
| 1488 | + (l2 == 0xffffffff && t2 != VT_LLONG && op == '|') || | |
| 1489 | + (l2 == 1 && (op == '%' || op == TOK_UMOD)))) { | |
| 1490 | + /* treat (x & 0), (x * 0), (x | -1) and (x % 1) as constant */ | |
| 1491 | + if (l2 == 1) | |
| 1492 | + vtop->c.ll = 0; | |
| 1493 | + vswap(); | |
| 1494 | + vtop--; | |
| 1495 | + } else if (c2 && (((op == '*' || op == '/' || op == TOK_UDIV || | |
| 1496 | + op == TOK_PDIV) && | |
| 1497 | + l2 == 1) || | |
| 1498 | + ((op == '+' || op == '-' || op == '|' || op == '^' || | |
| 1499 | + op == TOK_SHL || op == TOK_SHR || op == TOK_SAR) && | |
| 1500 | + l2 == 0) || | |
| 1501 | + (op == '&' && | |
| 1502 | + l2 == -1))) { | |
| 1503 | + /* filter out NOP operations like x*1, x-0, x&-1... */ | |
| 1489 | 1504 | vtop--; |
| 1490 | 1505 | } else if (c2 && (op == '*' || op == TOK_PDIV || op == TOK_UDIV)) { |
| 1491 | 1506 | /* try to use shifts instead of muls or divs */ |