title: Under what conditions does a C++ compiler use floating-point pipelines to do integer division with run-time-known values for higher performance?
body: <p>For example,</p>
  <p><a href="https://godbolt.org/z/W5GbYxo7o" rel="nofollow noreferrer">https://godbolt.org/z/W5GbYxo7o</a></p>
  <pre><code>#include&lt;cstdint&gt;
  
  void divTest1(int *  const __restrict__  val1, int *  const __restrict__  val2, int *  const __restrict__  val3)
  {
      for(int i=0;i&lt;1024;i++)
      {
          val3[i] = val1[i]/val2[i]; // scalar idiv
      }
  }
  
  void divTest2(uint32_t *  const __restrict__  val1, uint32_t *  const __restrict__  val2, uint32_t *  const __restrict__  val3)
  {
      for(int i=0;i&lt;1024;i++)
      {
          val3[i] = val1[i]/val2[i]; // scalar div
      }
  }
  
  void divTest3(uint32_t *  const __restrict__  val1, uint32_t *  const __restrict__  val3)
  {
      for(int i=0;i&lt;1024;i++)
      {
          val3[i] = val1[i]/(uint32_t)10; // shifting + permutation + multiplication
      }
  }
  
  void divTest4ExplicitFloatOptimization(int *  const __restrict__  val1, int *  const __restrict__  val2, int *  const __restrict__  val3)
  {
      for(int i=0;i&lt;1024;i++)
      {
          val3[i] = ((float)val1[i])/((float)val2[i]); // divps
      }
  }
  
  void divTest5ExplicitFloatOptimization(int * const __restrict__ val1, int * const __restrict__ val3)
  {
      for(int i=0;i&lt;1024;i++)
      {
          val3[i] = ((float)val1[i])/10.0f; // divps (or *0.1f)
      }
  }
  
  // lowering bits to 16
  void divTest6(uint16_t *  const __restrict__  val1, uint16_t *  const __restrict__  val3)
  {
      for(int i=0;i&lt;1024;i++)
      {
          val3[i] = val1[i]/(uint16_t)10; // shifting + multiplication
      }
  }
  
  // lowering bits to 8
  void divTest7(uint8_t *  const __restrict__  val1, uint8_t *  const __restrict__  val3)
  {
      for(int i=0;i&lt;1024;i++)
      {
          val3[i] = val1[i]/(uint8_t)10; //  still no float pipeline
      }
  }
  </code></pre>
  <p>Out of all functions above, only the two with explicit floating-point casting functions force the compiler to do floating-point division SIMD instructions and looks like it may not be doing the same work as  idiv for all values of inputs.</p>
  <p>Is there a way to tell the compiler that it can assume the integers to be computed are in acceptable range for use of floating-point math? Something like:</p>
  <pre><code>int val = std::assume_30bits_precision(ptr[i]);
  int var = std::assume_30bits_precision(ptr2[i]);
  ptrInt[i] = val / var;
  </code></pre>
  <p>or this:</p>
  <pre><code>int val = std::assume_positive_24bits(ptr[i]);
  int var = std::assume_positive_24bits(ptr2[i]);
  ptrInt[i] = val / var;
  </code></pre>
  <p>If there is no such way, can I use 1-2 Newton-Raphson or similar methods with floats to do same thing but faster than idiv (non-compile-time-known integer values dividing non-compile-time-known integer values) that always does one operation at a time?</p>
  <p>Can the float-to-int and int-to-float casting/conversion latency be hidden behind the said method(i.e. Newton Raphson)'s instructions' latency?</p>