Skip to content
This repository was archived by the owner on Apr 23, 2020. It is now read-only.

Commit 3d464de

Browse files
committed
[SelectionDAG] try harder to convert funnel shift to rotate
Similar to rL337966 - if the DAGCombiner's rotate matching was working as expected, I don't think we'd see any test diffs here. AArch only goes right, and PPC only goes left. x86 has both, so no diffs there. Differential Revision: https://reviews.llvm.org/D50091 git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@339359 91177308-0d34-0410-b5e6-96231b3b80d8
1 parent 6bbc345 commit 3d464de

File tree

3 files changed

+13
-10
lines changed

3 files changed

+13
-10
lines changed

lib/CodeGen/SelectionDAG/SelectionDAGBuilder.cpp

+10-3
Original file line numberDiff line numberDiff line change
@@ -5703,14 +5703,21 @@ SelectionDAGBuilder::visitIntrinsicCall(const CallInst &I, unsigned Intrinsic) {
57035703
if (X == Y && isPowerOf2_32(VT.getScalarSizeInBits())) {
57045704
// TODO: This should also be done if the operation is custom, but we have
57055705
// to make sure targets are handling the modulo shift amount as expected.
5706-
// TODO: If the rotate direction (left or right) corresponding to the
5707-
// shift is not available, adjust the shift value and invert the
5708-
// direction.
57095706
auto RotateOpcode = IsFSHL ? ISD::ROTL : ISD::ROTR;
57105707
if (TLI.isOperationLegal(RotateOpcode, VT)) {
57115708
setValue(&I, DAG.getNode(RotateOpcode, sdl, VT, X, Z));
57125709
return nullptr;
57135710
}
5711+
5712+
// Some targets only rotate one way. Try the opposite direction.
5713+
RotateOpcode = IsFSHL ? ISD::ROTR : ISD::ROTL;
5714+
if (TLI.isOperationLegal(RotateOpcode, VT)) {
5715+
// Negate the shift amount because it is safe to ignore the high bits.
5716+
SDValue NegShAmt = DAG.getNode(ISD::SUB, sdl, VT, Zero, Z);
5717+
setValue(&I, DAG.getNode(RotateOpcode, sdl, VT, X, NegShAmt));
5718+
return nullptr;
5719+
}
5720+
57145721
// fshl (rotl): (X << (Z % BW)) | (X >> ((0 - Z) % BW))
57155722
// fshr (rotr): (X << ((0 - Z) % BW)) | (X >> (Z % BW))
57165723
SDValue NegZ = DAG.getNode(ISD::SUB, sdl, VT, Zero, Z);

test/CodeGen/AArch64/funnel-shift-rot.ll

+2-4
Original file line numberDiff line numberDiff line change
@@ -65,10 +65,8 @@ define i32 @rotl_i32(i32 %x, i32 %z) {
6565
define i64 @rotl_i64(i64 %x, i64 %z) {
6666
; CHECK-LABEL: rotl_i64:
6767
; CHECK: // %bb.0:
68-
; CHECK-NEXT: neg w9, w1
69-
; CHECK-NEXT: lsl x8, x0, x1
70-
; CHECK-NEXT: lsr x9, x0, x9
71-
; CHECK-NEXT: orr x0, x8, x9
68+
; CHECK-NEXT: neg x8, x1
69+
; CHECK-NEXT: ror x0, x0, x8
7270
; CHECK-NEXT: ret
7371
%f = call i64 @llvm.fshl.i64(i64 %x, i64 %x, i64 %z)
7472
ret i64 %f

test/CodeGen/PowerPC/funnel-shift-rot.ll

+1-3
Original file line numberDiff line numberDiff line change
@@ -145,7 +145,6 @@ define i32 @rotr_i32(i32 %x, i32 %z) {
145145
; CHECK-LABEL: rotr_i32:
146146
; CHECK: # %bb.0:
147147
; CHECK-NEXT: neg 4, 4
148-
; CHECK-NEXT: clrlwi 4, 4, 27
149148
; CHECK-NEXT: rlwnm 3, 3, 4, 0, 31
150149
; CHECK-NEXT: blr
151150
%f = call i32 @llvm.fshr.i32(i32 %x, i32 %x, i32 %z)
@@ -156,8 +155,7 @@ define i64 @rotr_i64(i64 %x, i64 %z) {
156155
; CHECK-LABEL: rotr_i64:
157156
; CHECK: # %bb.0:
158157
; CHECK-NEXT: neg 4, 4
159-
; CHECK-NEXT: rlwinm 4, 4, 0, 26, 31
160-
; CHECK-NEXT: rotld 3, 3, 4
158+
; CHECK-NEXT: rldcl 3, 3, 4, 0
161159
; CHECK-NEXT: blr
162160
%f = call i64 @llvm.fshr.i64(i64 %x, i64 %x, i64 %z)
163161
ret i64 %f

0 commit comments

Comments
 (0)