title: Logical operations on multiple modulus operations optimised?
body: <p>It is easy to see that:</p>
  
  <pre><code>(i % 3 == 0) &amp;&amp; (i % 5 == 0)
  </code></pre>
  
  <p>Can be simplified to:</p>
  
  <pre><code>(i % 15 == 0)
  </code></pre>
  
  <p>Yet looking into the output of GCC, it seems this is not done even at high optimisation levels.</p>
  
  <p>Do any compilers do these sorts of optimisations, or is there a good reason why those two tests are not semantically equivalent?</p>
  
  <p>Edit: In response to those who say this is a fringe case, the following is a similar case:</p>
  
  <pre><code>(i &lt; 3) &amp;&amp; (i &lt; 5)
  </code></pre>
  
  <p>Any number less than 3, must always be less than 5. Second test is redundant.</p>
  
  <p>I would also like to add the following in response to the answer that the compiler cannot know if the environment is affected... Look at this code:</p>
  
  <pre><code>void foo(void)
  {
      int i;
      for (i = 0; i &lt;= 10; i++)
      {
          if (i &gt; 20)
          {
              puts("Hi");
          }
      }
  }
  </code></pre>
  
  <p>Whole function is reduced to "repz ret" by GCC with <code>-O2</code>. That is far more complex than anything I am talking about.</p>