Quuxplusone / LLVMBugzillaTest

0 stars 0 forks source link

implement __builtin_assume_aligned() #16293

Open Quuxplusone opened 11 years ago

Quuxplusone commented 11 years ago
Bugzilla Link PR16294
Status NEW
Importance P normal
Reported by Conrad (conradsand.arma@gmail.com)
Reported on 2013-06-11 01:58:39 -0700
Last modified on 2019-09-12 09:04:21 -0700
Version trunk
Hardware All All
CC conradsand.arma@gmail.com, dgregor@apple.com, frankhb1989@gmail.com, llvm-bugs@lists.llvm.org, nadav.rotem@me.com, rafael@espindo.la, ryan@igglybob.com
Fixed by commit(s)
Attachments
Blocks
Blocked by
See also
Hello,

Thanks for your work on clang.  It would be very useful to implement the
__builtin_assume_aligned() function, which allows the compiler to assume that
the returned pointer is aligned (to a user specified number of bytes). This can
help in automatic vectorisation, allowing the compiler to use aligned SSE2
instructions.

GCC 4.7+ has this:
http://gcc.gnu.org/onlinedocs/gcc/Other-Builtins.html

The __builtin_assume_aligned() function is used to speed up software such as
the Armadillo C++ linear algebra library:
http://arma.sourceforge.net/
Quuxplusone commented 11 years ago

There is a patch floating around that adds __builtin_assume_aligned to an earlier version of LLVM:

http://llvm-reviews.chandlerc.com/D149

Any reason why this didn't get integrated into LLVM ?

Quuxplusone commented 5 years ago
This bug is outdated, as __builtin_assume_aligned() has been fixed by
https://reviews.llvm.org/rL217349.

However, the current implementation is not same to GCC's, which does not
require the alignment a constant. Actually clang does not accept the GCC's test
case:

void
test2 (double *out1, double *out2, double *out3, double *in1,
       double *in2, int len)
{
  int i, align = 32, misalign = 16;
  out1 = __builtin_assume_aligned (out1, align, misalign);
  out2 = __builtin_assume_aligned (out2, align, 16);
  out3 = __builtin_assume_aligned (out3, 32, misalign);
  in1 = __builtin_assume_aligned (in1, 32, 16);
  in2 = __builtin_assume_aligned (in2, 32, 0);
  for (i = 0; i < len; ++i)
    {
      out1[i] = in1[i] * in2[i];
      out2[i] = in1[i] + in2[i];
      out3[i] = in1[i] - in2[i];
    }
}

a.c:6:10: error: argument to '__builtin_assume_aligned' must be a constant
integer
  out1 = __builtin_assume_aligned (out1, align, misalign);
         ^                               ~~~~~
a.c:7:10: error: argument to '__builtin_assume_aligned' must be a constant
integer
  out2 = __builtin_assume_aligned (out2, align, 16);
         ^                               ~~~~~