Quuxplusone / LLVMBugzillaTest

0 stars 0 forks source link

clang is not knowing using const-attribute for the standard math functions #28932

Open Quuxplusone opened 8 years ago

Quuxplusone commented 8 years ago
Bugzilla Link PR28937
Status NEW
Importance P enhancement
Reported by npl@chello.at
Reported on 2016-08-11 08:07:46 -0700
Last modified on 2017-11-06 10:43:04 -0800
Version 3.8
Hardware PC Linux
CC hfinkel@anl.gov, llvm-bugs@lists.llvm.org, spatel+llvm@rotateright.com
Fixed by commit(s)
Attachments
Blocks
Blocked by
See also
unlike gcc, clang doesn`t seem to have the knowledge about std math functions
builtin.

Similar to knowing memcpy and generating optimized code, clang should know that
all math functions only depend on their arguments.

For the code snippet below, I would expect that
* Clang should only call the function once

What happens is that
* Clang cant deduce that the function is "const" and doesnt remove any call

(apparently this could also be solved in the std library, but I doubt its wise
to depend on this, rather than simply expect that the standard functions are
deterministic)

------------ (code snippet)
#include <math.h>

float failttooptimize(float a)
{
  return sin(a) + sin(a) + sin(a);
}

__attribute__((const)) double cos(double a);
float canoptimize(float a)
{
  return cos(a) + cos(a) + cos(a);
}
------------

clang version 3.8.1-5 (tags/RELEASE_381/final)
Target: x86_64-unknown-linux-gnu
Thread model: posix
InstalledDir: /usr/bin
Found candidate GCC installation: /usr/bin/../lib/gcc/i586-linux-gnu/4.9
Found candidate GCC installation: /usr/bin/../lib/gcc/i586-linux-gnu/4.9.2
Found candidate GCC installation: /usr/bin/../lib/gcc/x86_64-linux-gnu/4.8
Found candidate GCC installation: /usr/bin/../lib/gcc/x86_64-linux-gnu/4.8.4
Found candidate GCC installation: /usr/bin/../lib/gcc/x86_64-linux-gnu/4.9
Found candidate GCC installation: /usr/bin/../lib/gcc/x86_64-linux-gnu/4.9.2
Found candidate GCC installation: /usr/lib/gcc/i586-linux-gnu/4.9
Found candidate GCC installation: /usr/lib/gcc/i586-linux-gnu/4.9.2
Found candidate GCC installation: /usr/lib/gcc/x86_64-linux-gnu/4.8
Found candidate GCC installation: /usr/lib/gcc/x86_64-linux-gnu/4.8.4
Found candidate GCC installation: /usr/lib/gcc/x86_64-linux-gnu/4.9
Found candidate GCC installation: /usr/lib/gcc/x86_64-linux-gnu/4.9.2
Selected GCC installation: /usr/bin/../lib/gcc/x86_64-linux-gnu/4.9
Candidate multilib: .;@m64
Candidate multilib: 32;@m32
Candidate multilib: x32;@mx32
Selected multilib: .;@m64
 "/usr/lib/llvm-3.8/bin/clang" -cc1 -triple x86_64-unknown-linux-gnu -S -disable-free -disable-llvm-verifier -main-file-name test.c -mrelocation-model static -mthread-model posix -fmath-errno -masm-verbose -mconstructor-aliases -munwind-tables -fuse-init-array -target-cpu x86-64 -momit-leaf-frame-pointer -v -dwarf-column-info -debugger-tuning=gdb -coverage-file /tmp/test.c -resource-dir /usr/lib/llvm-3.8/bin/../lib/clang/3.8.1 -internal-isystem /usr/local/include -internal-isystem /usr/lib/llvm-3.8/bin/../lib/clang/3.8.1/include -internal-externc-isystem /usr/include/x86_64-linux-gnu -internal-externc-isystem /include -internal-externc-isystem /usr/include -O3 -fdebug-compilation-dir /tmp -ferror-limit 19 -fmessage-length 211 -fobjc-runtime=gcc -fdiagnostics-show-option -fcolor-diagnostics -vectorize-loops -vectorize-slp -o test.s -x c test.c
clang -cc1 version 3.8.1 based upon LLVM 3.8.1 default target x86_64-unknown-
linux-gnu
ignoring nonexistent directory "/include"
#include "..." search starts here:
#include <...> search starts here:
 /usr/local/include
 /usr/lib/llvm-3.8/bin/../lib/clang/3.8.1/include
 /usr/include/x86_64-linux-gnu
 /usr/include
End of search list.
Quuxplusone commented 8 years ago

This doesn't repro on OSX because OSX -fno-math-errno is the default. Ie, we only fail to optimize it if 'errno' is required to be set.

Quuxplusone commented 8 years ago
You are right, clang can optimize if I add this flag. gcc optimizes even if I
set -fmath-errno.
The attribute "const" is probably not syntactically correct and this is a
harder than I thought.
You`d have to take care to keep the *last* identical function call alive, and
not move them around functions that read/write errno.

double messy(double a)
{
  double A = sin(a); // that can be removed, result is same as C
  double B = log(a);
  double C = sin(a); // that has to stay below other functions modifying errno

  return A + B + C;
}

gcc 4.9 generates incorrect code with this example (with -fmath-errno set).
Quuxplusone commented 7 years ago
I'm trying to clean up the const-ness of library functions/builtins and their
mapping to LLVM intrinsics:
https://reviews.llvm.org/D39204
https://reviews.llvm.org/D39481
https://reviews.llvm.org/D39611

But I think we're already doing the right thing both in the example in the
description and in comment 2. Can we close this bug?