Author: spatel Date: Wed Jun 13 10:54:52 2018 New Revision: 334628 URL: http://llvm.org/viewvc/llvm-project?rev=334628&view=rev Log: [CodeGen] make nan builtins pure rather than const (PR37778)
https://bugs.llvm.org/show_bug.cgi?id=37778 ...shows a miscompile resulting from marking nan builtins as 'const'. The nan libcalls/builtins take a pointer argument: http://www.cplusplus.com/reference/cmath/nan-function/ ...and the chars dereferenced by that arg are used to fill in the NaN constant payload bits. "const" means that the pointer argument isn't dereferenced. That's translated to "readnone" in LLVM. "pure" means that the pointer argument may be dereferenced. That's translated to "readonly" in LLVM. This change prevents the IR optimizer from killing the lead-up to the nan call here: double a() { char buf[4]; buf[0] = buf[1] = buf[2] = '9'; buf[3] = '\0'; return __builtin_nan(buf); } ...the optimizer isn't currently able to simplify this to a constant as we might hope, but this patch should solve the miscompile. Differential Revision: https://reviews.llvm.org/D48134 Modified: cfe/trunk/include/clang/Basic/Builtins.def cfe/trunk/test/CodeGen/math-builtins.c Modified: cfe/trunk/include/clang/Basic/Builtins.def URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/include/clang/Basic/Builtins.def?rev=334628&r1=334627&r2=334628&view=diff ============================================================================== --- cfe/trunk/include/clang/Basic/Builtins.def (original) +++ cfe/trunk/include/clang/Basic/Builtins.def Wed Jun 13 10:54:52 2018 @@ -137,14 +137,14 @@ BUILTIN(__builtin_ldexpl, "LdLdi", "Fne" BUILTIN(__builtin_modf , "ddd*" , "Fn") BUILTIN(__builtin_modff, "fff*" , "Fn") BUILTIN(__builtin_modfl, "LdLdLd*", "Fn") -BUILTIN(__builtin_nan, "dcC*" , "ncF") -BUILTIN(__builtin_nanf, "fcC*" , "ncF") -BUILTIN(__builtin_nanl, "LdcC*", "ncF") -BUILTIN(__builtin_nanf128, "LLdcC*", "ncF") -BUILTIN(__builtin_nans, "dcC*" , "ncF") -BUILTIN(__builtin_nansf, "fcC*" , "ncF") -BUILTIN(__builtin_nansl, "LdcC*", "ncF") -BUILTIN(__builtin_nansf128, "LLdcC*", "ncF") +BUILTIN(__builtin_nan, "dcC*" , "FnU") +BUILTIN(__builtin_nanf, "fcC*" , "FnU") +BUILTIN(__builtin_nanl, "LdcC*", "FnU") +BUILTIN(__builtin_nanf128, "LLdcC*", "FnU") +BUILTIN(__builtin_nans, "dcC*" , "FnU") +BUILTIN(__builtin_nansf, "fcC*" , "FnU") +BUILTIN(__builtin_nansl, "LdcC*", "FnU") +BUILTIN(__builtin_nansf128, "LLdcC*", "FnU") BUILTIN(__builtin_powi , "ddi" , "Fnc") BUILTIN(__builtin_powif, "ffi" , "Fnc") BUILTIN(__builtin_powil, "LdLdi", "Fnc") Modified: cfe/trunk/test/CodeGen/math-builtins.c URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/test/CodeGen/math-builtins.c?rev=334628&r1=334627&r2=334628&view=diff ============================================================================== --- cfe/trunk/test/CodeGen/math-builtins.c (original) +++ cfe/trunk/test/CodeGen/math-builtins.c Wed Jun 13 10:54:52 2018 @@ -90,25 +90,25 @@ void foo(double *d, float f, float *fp, __builtin_nan(c); __builtin_nanf(c); __builtin_nanl(c); __builtin_nanf128(c); -// NO__ERRNO: declare double @nan(i8*) [[READNONE]] -// NO__ERRNO: declare float @nanf(i8*) [[READNONE]] -// NO__ERRNO: declare x86_fp80 @nanl(i8*) [[READNONE]] -// NO__ERRNO: declare fp128 @nanf128(i8*) [[READNONE]] -// HAS_ERRNO: declare double @nan(i8*) [[READNONE:#[0-9]+]] -// HAS_ERRNO: declare float @nanf(i8*) [[READNONE]] -// HAS_ERRNO: declare x86_fp80 @nanl(i8*) [[READNONE]] -// HAS_ERRNO: declare fp128 @nanf128(i8*) [[READNONE]] +// NO__ERRNO: declare double @nan(i8*) [[PURE:#[0-9]+]] +// NO__ERRNO: declare float @nanf(i8*) [[PURE]] +// NO__ERRNO: declare x86_fp80 @nanl(i8*) [[PURE]] +// NO__ERRNO: declare fp128 @nanf128(i8*) [[PURE]] +// HAS_ERRNO: declare double @nan(i8*) [[PURE:#[0-9]+]] +// HAS_ERRNO: declare float @nanf(i8*) [[PURE]] +// HAS_ERRNO: declare x86_fp80 @nanl(i8*) [[PURE]] +// HAS_ERRNO: declare fp128 @nanf128(i8*) [[PURE]] __builtin_nans(c); __builtin_nansf(c); __builtin_nansl(c); __builtin_nansf128(c); -// NO__ERRNO: declare double @nans(i8*) [[READNONE]] -// NO__ERRNO: declare float @nansf(i8*) [[READNONE]] -// NO__ERRNO: declare x86_fp80 @nansl(i8*) [[READNONE]] -// NO__ERRNO: declare fp128 @nansf128(i8*) [[READNONE]] -// HAS_ERRNO: declare double @nans(i8*) [[READNONE]] -// HAS_ERRNO: declare float @nansf(i8*) [[READNONE]] -// HAS_ERRNO: declare x86_fp80 @nansl(i8*) [[READNONE]] -// HAS_ERRNO: declare fp128 @nansf128(i8*) [[READNONE]] +// NO__ERRNO: declare double @nans(i8*) [[PURE]] +// NO__ERRNO: declare float @nansf(i8*) [[PURE]] +// NO__ERRNO: declare x86_fp80 @nansl(i8*) [[PURE]] +// NO__ERRNO: declare fp128 @nansf128(i8*) [[PURE]] +// HAS_ERRNO: declare double @nans(i8*) [[PURE]] +// HAS_ERRNO: declare float @nansf(i8*) [[PURE]] +// HAS_ERRNO: declare x86_fp80 @nansl(i8*) [[PURE]] +// HAS_ERRNO: declare fp128 @nansf128(i8*) [[PURE]] __builtin_pow(f,f); __builtin_powf(f,f); __builtin_powl(f,f); @@ -188,7 +188,7 @@ void foo(double *d, float f, float *fp, // NO__ERRNO: declare double @cbrt(double) [[READNONE]] // NO__ERRNO: declare float @cbrtf(float) [[READNONE]] // NO__ERRNO: declare x86_fp80 @cbrtl(x86_fp80) [[READNONE]] -// HAS_ERRNO: declare double @cbrt(double) [[READNONE]] +// HAS_ERRNO: declare double @cbrt(double) [[READNONE:#[0-9]+]] // HAS_ERRNO: declare float @cbrtf(float) [[READNONE]] // HAS_ERRNO: declare x86_fp80 @cbrtl(x86_fp80) [[READNONE]] @@ -581,9 +581,11 @@ void foo(double *d, float f, float *fp, // NO__ERRNO: attributes [[READNONE]] = { {{.*}}readnone{{.*}} } // NO__ERRNO: attributes [[READNONE_INTRINSIC]] = { {{.*}}readnone{{.*}} } // NO__ERRNO: attributes [[NOT_READNONE]] = { nounwind "correctly{{.*}} } +// NO__ERRNO: attributes [[PURE]] = { {{.*}}readonly{{.*}} } // HAS_ERRNO: attributes [[NOT_READNONE]] = { nounwind "correctly{{.*}} } // HAS_ERRNO: attributes [[READNONE_INTRINSIC]] = { {{.*}}readnone{{.*}} } +// HAS_ERRNO: attributes [[PURE]] = { {{.*}}readonly{{.*}} } // HAS_ERRNO: attributes [[READNONE]] = { {{.*}}readnone{{.*}} } // HAS_ERRNO_GNU: attributes [[READNONE_INTRINSIC]] = { {{.*}}readnone{{.*}} } _______________________________________________ cfe-commits mailing list cfe-commits@lists.llvm.org http://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits