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 | c2 = c1; //c = c1, c1 = c2, c2 = c; | 1476 | c2 = c1; //c = c1, c1 = c2, c2 = c; |
| 1477 | l2 = l1; //l = l1, l1 = l2, l2 = l; | 1477 | l2 = l1; //l = l1, l1 = l2, l2 = l; |
| 1478 | } | 1478 | } |
| 1479 | /* Filter out NOP operations like x*1, x-0, x&-1... */ | 1479 | if (!const_wanted && |
| 1480 | if (c2 && (((op == '*' || op == '/' || op == TOK_UDIV || | 1480 | c1 && ((l1 == 0 && |
| 1481 | op == TOK_PDIV) && | 1481 | (op == TOK_SHL || op == TOK_SHR || op == TOK_SAR)) || |
| 1482 | l2 == 1) || | 1482 | (l1 == -1 && op == TOK_SAR))) { |
| 1483 | ((op == '+' || op == '-' || op == '|' || op == '^' || | 1483 | /* treat (0 << x), (0 >> x) and (-1 >> x) as constant */ |
| 1484 | op == TOK_SHL || op == TOK_SHR || op == TOK_SAR) && | 1484 | vtop--; |
| 1485 | l2 == 0) || | 1485 | } else if (!const_wanted && |
| 1486 | (op == '&' && | 1486 | c2 && ((l2 == 0 && (op == '&' || op == '*')) || |
| 1487 | l2 == -1))) { | 1487 | (l2 == -1 && op == '|') || |
| 1488 | /* nothing to do */ | 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 | vtop--; | 1504 | vtop--; |
| 1490 | } else if (c2 && (op == '*' || op == TOK_PDIV || op == TOK_UDIV)) { | 1505 | } else if (c2 && (op == '*' || op == TOK_PDIV || op == TOK_UDIV)) { |
| 1491 | /* try to use shifts instead of muls or divs */ | 1506 | /* try to use shifts instead of muls or divs */ |