summaryrefslogtreecommitdiffstats
path: root/llvm/lib/CodeGen/SelectionDAG/SelectionDAGBuilder.cpp
diff options
context:
space:
mode:
authorSanjay Patel <spatel@rotateright.com>2018-08-09 17:26:22 +0000
committerSanjay Patel <spatel@rotateright.com>2018-08-09 17:26:22 +0000
commit15d1501aaefc0d8c86bf90e0abe6cb8d315031f2 (patch)
treea81552f999708e63d9a6aeefd5b385c1334b67e5 /llvm/lib/CodeGen/SelectionDAG/SelectionDAGBuilder.cpp
parenta42dec7a1b905fff024fad2c4e02f5b070e3d0c7 (diff)
downloadbcm5719-llvm-15d1501aaefc0d8c86bf90e0abe6cb8d315031f2.tar.gz
bcm5719-llvm-15d1501aaefc0d8c86bf90e0abe6cb8d315031f2.zip
[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 llvm-svn: 339359
Diffstat (limited to 'llvm/lib/CodeGen/SelectionDAG/SelectionDAGBuilder.cpp')
-rw-r--r--llvm/lib/CodeGen/SelectionDAG/SelectionDAGBuilder.cpp13
1 files changed, 10 insertions, 3 deletions
diff --git a/llvm/lib/CodeGen/SelectionDAG/SelectionDAGBuilder.cpp b/llvm/lib/CodeGen/SelectionDAG/SelectionDAGBuilder.cpp
index 24e6289fcba..4fb10fadc3c 100644
--- a/llvm/lib/CodeGen/SelectionDAG/SelectionDAGBuilder.cpp
+++ b/llvm/lib/CodeGen/SelectionDAG/SelectionDAGBuilder.cpp
@@ -5703,14 +5703,21 @@ SelectionDAGBuilder::visitIntrinsicCall(const CallInst &I, unsigned Intrinsic) {
if (X == Y && isPowerOf2_32(VT.getScalarSizeInBits())) {
// TODO: This should also be done if the operation is custom, but we have
// to make sure targets are handling the modulo shift amount as expected.
- // TODO: If the rotate direction (left or right) corresponding to the
- // shift is not available, adjust the shift value and invert the
- // direction.
auto RotateOpcode = IsFSHL ? ISD::ROTL : ISD::ROTR;
if (TLI.isOperationLegal(RotateOpcode, VT)) {
setValue(&I, DAG.getNode(RotateOpcode, sdl, VT, X, Z));
return nullptr;
}
+
+ // Some targets only rotate one way. Try the opposite direction.
+ RotateOpcode = IsFSHL ? ISD::ROTR : ISD::ROTL;
+ if (TLI.isOperationLegal(RotateOpcode, VT)) {
+ // Negate the shift amount because it is safe to ignore the high bits.
+ SDValue NegShAmt = DAG.getNode(ISD::SUB, sdl, VT, Zero, Z);
+ setValue(&I, DAG.getNode(RotateOpcode, sdl, VT, X, NegShAmt));
+ return nullptr;
+ }
+
// fshl (rotl): (X << (Z % BW)) | (X >> ((0 - Z) % BW))
// fshr (rotr): (X << ((0 - Z) % BW)) | (X >> (Z % BW))
SDValue NegZ = DAG.getNode(ISD::SUB, sdl, VT, Zero, Z);
OpenPOWER on IntegriCloud