]> granicus.if.org Git - clang/commit
[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)
commit1d6049b739c78b327ed25599c19ed7764cb21947
tree1bf96d3695bcf067e1e32dff8ece19497526d16a
parent4f482660272cb79d5bec53291b043b0b9b19c29e
[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

git-svn-id: https://llvm.org/svn/llvm-project/cfe/trunk@331943 91177308-0d34-0410-b5e6-96231b3b80d8
lib/CodeGen/CGBuiltin.cpp
test/CodeGen/ms-intrinsics-rotations.c