Float.isInfinite/Float.isNaN do not get vectorized, even if manually inlined

XMLWordPrintable

    • x86_64
    • linux

      A DESCRIPTION OF THE REQUEST :
      If a Float.isInfinite is in a loop it does not get vectorized. The same behaviour hapens when Float.POSITIVE_INFINITY or Float.NEGATIVE_INFINITY are used directly.
      See example code:
      private void zeroIfInfiniteInlined(float[] samples){
              for (int i = 0; i < samples.length; i++) {
                      if (samples[i] == Float.POSITIVE_INFINITY || samples[i] == Float.NEGATIVE_INFINITY){
                          samples[i] = 0.0f;
                      }
              }
        }

      it could generate vector flags which would then be applied to a store.

      JUSTIFICATION :
      The code as above is pretty common in HPC, often followed by more complex computation. It is important that this call works corectly and fast. Vectorizing it can help.

      EXPECTED VERSUS ACTUAL BEHAVIOR :
      EXPECTED -
      1. Generate mask for 4,8,16 elements (depending on AVX-128,AVX-256,AVX-512)
      2. If mask is not zero, store with mask.
      ACTUAL -
      Scalar instructions are used. Loop is not vectorized.

      ---------- BEGIN SOURCE ----------
      class IsInfinity {
          private void zeroIfInfiniteInlined(float[] samples){
              for (int i = 0; i < samples.length; i++) {
                      if (samples[i] == Float.POSITIVE_INFINITY || samples[i] == Float.NEGATIVE_INFINITY){
                          samples[i] = 0.0f;
                      }
              }
          }
          private void zeroIfInfinite(float[] samples) {
                  for (int i = 0; i < samples.length; i++) {
                      if (Float.isInfinite(samples[i])) {
                          samples[i] = 0.0f;
                      }
              }
          }
          private void zeroIfNaN(float[] samples) {
                  for (int i = 0; i < samples.length; i++) {
                      if (Float.isNaN(samples[i])) {
                          samples[i] = 0.0f;
                      }
              }
          }
          private void zeroIfNaNInlined(float[] samples) {
                  for (int i = 0; i < samples.length; i++) {
                      if (samples[i]!=samples[i]) {
                          samples[i] = 0.0f;
                      }
              }
          }


          public static void main(String[] argv) throws Exception {
              float samples[] = new float[4000];
              for (int i=0;i<samples.length;i++){
                      samples[i] = i;

              }
              IsInfinity inf = new IsInfinity();
              for (int i=0;i<10000;i++){
                      inf.zeroIfInfinite(samples);
                      inf.zeroIfInfiniteInlined(samples);
                      inf.zeroIfNaN(samples);
                      inf.zeroIfNaNInlined(samples);
              }

          }
      }

      ---------- END SOURCE ----------

      CUSTOMER SUBMITTED WORKAROUND :
      None.

            Assignee:
            Jatin Bhateja
            Reporter:
            Webbug Group
            Votes:
            0 Vote for this issue
            Watchers:
            5 Start watching this issue

              Created:
              Updated: