Skip to content

Commit 1d7ed94

Browse files
committed
[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 llvm-svn: 334628
1 parent 4d1c854 commit 1d7ed94

File tree

2 files changed

+27
-25
lines changed

2 files changed

+27
-25
lines changed

clang/include/clang/Basic/Builtins.def

Lines changed: 8 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -137,14 +137,14 @@ BUILTIN(__builtin_ldexpl, "LdLdi", "Fne")
137137
BUILTIN(__builtin_modf , "ddd*" , "Fn")
138138
BUILTIN(__builtin_modff, "fff*" , "Fn")
139139
BUILTIN(__builtin_modfl, "LdLdLd*", "Fn")
140-
BUILTIN(__builtin_nan, "dcC*" , "ncF")
141-
BUILTIN(__builtin_nanf, "fcC*" , "ncF")
142-
BUILTIN(__builtin_nanl, "LdcC*", "ncF")
143-
BUILTIN(__builtin_nanf128, "LLdcC*", "ncF")
144-
BUILTIN(__builtin_nans, "dcC*" , "ncF")
145-
BUILTIN(__builtin_nansf, "fcC*" , "ncF")
146-
BUILTIN(__builtin_nansl, "LdcC*", "ncF")
147-
BUILTIN(__builtin_nansf128, "LLdcC*", "ncF")
140+
BUILTIN(__builtin_nan, "dcC*" , "FnU")
141+
BUILTIN(__builtin_nanf, "fcC*" , "FnU")
142+
BUILTIN(__builtin_nanl, "LdcC*", "FnU")
143+
BUILTIN(__builtin_nanf128, "LLdcC*", "FnU")
144+
BUILTIN(__builtin_nans, "dcC*" , "FnU")
145+
BUILTIN(__builtin_nansf, "fcC*" , "FnU")
146+
BUILTIN(__builtin_nansl, "LdcC*", "FnU")
147+
BUILTIN(__builtin_nansf128, "LLdcC*", "FnU")
148148
BUILTIN(__builtin_powi , "ddi" , "Fnc")
149149
BUILTIN(__builtin_powif, "ffi" , "Fnc")
150150
BUILTIN(__builtin_powil, "LdLdi", "Fnc")

clang/test/CodeGen/math-builtins.c

Lines changed: 19 additions & 17 deletions
Original file line numberDiff line numberDiff line change
@@ -90,25 +90,25 @@ void foo(double *d, float f, float *fp, long double *l, int *i, const char *c) {
9090

9191
__builtin_nan(c); __builtin_nanf(c); __builtin_nanl(c); __builtin_nanf128(c);
9292

93-
// NO__ERRNO: declare double @nan(i8*) [[READNONE]]
94-
// NO__ERRNO: declare float @nanf(i8*) [[READNONE]]
95-
// NO__ERRNO: declare x86_fp80 @nanl(i8*) [[READNONE]]
96-
// NO__ERRNO: declare fp128 @nanf128(i8*) [[READNONE]]
97-
// HAS_ERRNO: declare double @nan(i8*) [[READNONE:#[0-9]+]]
98-
// HAS_ERRNO: declare float @nanf(i8*) [[READNONE]]
99-
// HAS_ERRNO: declare x86_fp80 @nanl(i8*) [[READNONE]]
100-
// HAS_ERRNO: declare fp128 @nanf128(i8*) [[READNONE]]
93+
// NO__ERRNO: declare double @nan(i8*) [[PURE:#[0-9]+]]
94+
// NO__ERRNO: declare float @nanf(i8*) [[PURE]]
95+
// NO__ERRNO: declare x86_fp80 @nanl(i8*) [[PURE]]
96+
// NO__ERRNO: declare fp128 @nanf128(i8*) [[PURE]]
97+
// HAS_ERRNO: declare double @nan(i8*) [[PURE:#[0-9]+]]
98+
// HAS_ERRNO: declare float @nanf(i8*) [[PURE]]
99+
// HAS_ERRNO: declare x86_fp80 @nanl(i8*) [[PURE]]
100+
// HAS_ERRNO: declare fp128 @nanf128(i8*) [[PURE]]
101101

102102
__builtin_nans(c); __builtin_nansf(c); __builtin_nansl(c); __builtin_nansf128(c);
103103

104-
// NO__ERRNO: declare double @nans(i8*) [[READNONE]]
105-
// NO__ERRNO: declare float @nansf(i8*) [[READNONE]]
106-
// NO__ERRNO: declare x86_fp80 @nansl(i8*) [[READNONE]]
107-
// NO__ERRNO: declare fp128 @nansf128(i8*) [[READNONE]]
108-
// HAS_ERRNO: declare double @nans(i8*) [[READNONE]]
109-
// HAS_ERRNO: declare float @nansf(i8*) [[READNONE]]
110-
// HAS_ERRNO: declare x86_fp80 @nansl(i8*) [[READNONE]]
111-
// HAS_ERRNO: declare fp128 @nansf128(i8*) [[READNONE]]
104+
// NO__ERRNO: declare double @nans(i8*) [[PURE]]
105+
// NO__ERRNO: declare float @nansf(i8*) [[PURE]]
106+
// NO__ERRNO: declare x86_fp80 @nansl(i8*) [[PURE]]
107+
// NO__ERRNO: declare fp128 @nansf128(i8*) [[PURE]]
108+
// HAS_ERRNO: declare double @nans(i8*) [[PURE]]
109+
// HAS_ERRNO: declare float @nansf(i8*) [[PURE]]
110+
// HAS_ERRNO: declare x86_fp80 @nansl(i8*) [[PURE]]
111+
// HAS_ERRNO: declare fp128 @nansf128(i8*) [[PURE]]
112112

113113
__builtin_pow(f,f); __builtin_powf(f,f); __builtin_powl(f,f);
114114

@@ -188,7 +188,7 @@ void foo(double *d, float f, float *fp, long double *l, int *i, const char *c) {
188188
// NO__ERRNO: declare double @cbrt(double) [[READNONE]]
189189
// NO__ERRNO: declare float @cbrtf(float) [[READNONE]]
190190
// NO__ERRNO: declare x86_fp80 @cbrtl(x86_fp80) [[READNONE]]
191-
// HAS_ERRNO: declare double @cbrt(double) [[READNONE]]
191+
// HAS_ERRNO: declare double @cbrt(double) [[READNONE:#[0-9]+]]
192192
// HAS_ERRNO: declare float @cbrtf(float) [[READNONE]]
193193
// HAS_ERRNO: declare x86_fp80 @cbrtl(x86_fp80) [[READNONE]]
194194

@@ -581,9 +581,11 @@ void foo(double *d, float f, float *fp, long double *l, int *i, const char *c) {
581581
// NO__ERRNO: attributes [[READNONE]] = { {{.*}}readnone{{.*}} }
582582
// NO__ERRNO: attributes [[READNONE_INTRINSIC]] = { {{.*}}readnone{{.*}} }
583583
// NO__ERRNO: attributes [[NOT_READNONE]] = { nounwind "correctly{{.*}} }
584+
// NO__ERRNO: attributes [[PURE]] = { {{.*}}readonly{{.*}} }
584585

585586
// HAS_ERRNO: attributes [[NOT_READNONE]] = { nounwind "correctly{{.*}} }
586587
// HAS_ERRNO: attributes [[READNONE_INTRINSIC]] = { {{.*}}readnone{{.*}} }
588+
// HAS_ERRNO: attributes [[PURE]] = { {{.*}}readonly{{.*}} }
587589
// HAS_ERRNO: attributes [[READNONE]] = { {{.*}}readnone{{.*}} }
588590

589591
// HAS_ERRNO_GNU: attributes [[READNONE_INTRINSIC]] = { {{.*}}readnone{{.*}} }

0 commit comments

Comments
 (0)