[Builtins] Improve the IR emitted for MSVC compatible rotr/rotl builtins to match...
authorCraig Topper <craig.topper@intel.com>
Thu, 10 May 2018 00:05:13 +0000 (00:05 +0000)
committerCraig Topper <craig.topper@intel.com>
Thu, 10 May 2018 00:05:13 +0000 (00:05 +0000)
commit2b248849aecbfd726348f320e80e12a3b91c9f48
tree24a002de727174e27309a8ef81f71e94d456bde2
parent069a1eb3bbcb9d959ae8d61738c8b98a5398096a
[Builtins] Improve the IR emitted for MSVC compatible rotr/rotl builtins to match what the middle and backends understand

Previously we emitted something like

rotl(x, n) {
  n &= bitwidth-1;
  return n != 0 ? ((x << n) | (x >> (bitwidth - n)) : x;
}

We use a select to avoid the undefined behavior on the (bitwidth - n) shift.

The middle and backend don't really recognize this as a rotate and end up emitting a cmov or control flow because of the select.

A better pattern is (x << (n & mask)) | (x << (-n & mask)) where mask is bitwidth - 1.

Fixes the main complaint in PR37387. There's still some work to be done if the user writes that sequence directly on a short or char where type promotion rules can prevent it from being recognized. The builtin is emitting direct IR with unpromoted types so that isn't a problem for it.

Differential Revision: https://reviews.llvm.org/D46656

llvm-svn: 331943
clang/lib/CodeGen/CGBuiltin.cpp
clang/test/CodeGen/ms-intrinsics-rotations.c