Workaround for GCC aarch64 compiler bug
authorPyry Haulos <phaulos@google.com>
Wed, 8 Oct 2014 22:01:09 +0000 (15:01 -0700)
committerPyry Haulos <phaulos@google.com>
Wed, 8 Oct 2014 22:09:53 +0000 (15:09 -0700)
Current prebuilt GCC toolchain has a bug in shift right when
targeting ARMv8 / aarch64.

If compiler wants to perform logical shift by variable/register
in fp/vector registers it uses USHL that selects shift direction
based on shift operand value. Thus for right shifts the shift
operand needs to be negated.

The bug is in right shift pattern; it doesn't mark shift operand
as clobbered and thus later code using that same register may
see the negated value.

Workaround is to disable optimization for this function.

See https://gcc.gnu.org/bugzilla/show_bug.cgi?id=61633

Change-Id: I02477b0fb383ead1d35136261fb8969a02d1031e

modules/gles3/functional/es3fShaderPrecisionTests.cpp

index c05b763..e4ae760 100644 (file)
@@ -187,7 +187,28 @@ public:
        IterateResult                           iterate                                         (void);
 
 protected:
-       bool                                            compare                                         (float in0, float in1, double reference, float result);
+       bool                                            compare                                         (float in0, float in1, double reference, float result)
+#if (DE_COMPILER == DE_COMPILER_GCC) && (DE_CPU == DE_CPU_ARM_64)
+#      if (__GNUC__ == 4) && (__GNUC_MINOR__ == 9) && (__GNUC_PATCHLEVEL__ == 0)
+               // Some prerelease GCC 4.9 versions have a bug in shift right when
+               // targeting ARMv8.
+               //
+               // If compiler wants to perform logical shift by variable/register
+               // in fp/vector registers it uses USHL that selects shift direction
+               // based on shift operand value. Thus for right shifts the shift
+               // operand needs to be negated.
+               //
+               // The bug is in right shift pattern; it doesn't mark shift operand
+               // as clobbered and thus later code using that same register may
+               // see the negated value.
+               //
+               // Workaround is to disable optimization for this function.
+               //
+               // See https://gcc.gnu.org/bugzilla/show_bug.cgi?id=61633
+               __attribute__((optimize(0)))
+#      endif
+#endif
+       ;
 
 private:
                                                                ShaderFloatPrecisionCase        (const ShaderFloatPrecisionCase& other);