[PATCH] D86449: Summary: [SelectionDAG] Handle non-power-of-2 bitwidths in expandROT
Jay Foad via Phabricator via llvm-commits
llvm-commits at lists.llvm.org
Mon Aug 24 05:34:42 PDT 2020
foad created this revision.
foad added reviewers: RKSimon, lebedev.ri, sunfish.
Herald added subscribers: llvm-commits, hiraditya, jgravelle-google, sbc100, dschuff.
Herald added a project: LLVM.
foad requested review of this revision.
Herald added a subscriber: aheejin.
Repository:
rG LLVM Github Monorepo
https://reviews.llvm.org/D86449
Files:
llvm/lib/CodeGen/SelectionDAG/TargetLowering.cpp
llvm/test/CodeGen/WebAssembly/fshl.ll
Index: llvm/test/CodeGen/WebAssembly/fshl.ll
===================================================================
--- /dev/null
+++ llvm/test/CodeGen/WebAssembly/fshl.ll
@@ -0,0 +1,21 @@
+; NOTE: Assertions have been autogenerated by utils/update_llc_test_checks.py
+; RUN: llc < %s | FileCheck %s
+
+target triple = "wasm32-unknown-unknown"
+
+define i33 @fshr_multi_use(i33 %a) {
+; CHECK-LABEL: fshr_multi_use:
+; CHECK: .functype fshr_multi_use (i64) -> (i64)
+; CHECK-NEXT: # %bb.0:
+; CHECK-NEXT: local.get 0
+; CHECK-NEXT: i64.const 1
+; CHECK-NEXT: i64.shr_u
+; CHECK-NEXT: i64.const 31
+; CHECK-NEXT: i64.and
+; CHECK-NEXT: # fallthrough-return
+ %b = tail call i33 @llvm.fshr.i33(i33 %a, i33 %a, i33 1)
+ %e = and i33 %b, 31
+ ret i33 %e
+}
+
+declare i33 @llvm.fshr.i33(i33, i33, i33)
Index: llvm/lib/CodeGen/SelectionDAG/TargetLowering.cpp
===================================================================
--- llvm/lib/CodeGen/SelectionDAG/TargetLowering.cpp
+++ llvm/lib/CodeGen/SelectionDAG/TargetLowering.cpp
@@ -6221,12 +6221,9 @@
EVT ShVT = Op1.getValueType();
SDValue Zero = DAG.getConstant(0, DL, ShVT);
- assert(isPowerOf2_32(EltSizeInBits) && EltSizeInBits > 1 &&
- "Expecting the type bitwidth to be a power of 2");
-
// If a rotate in the other direction is supported, use it.
unsigned RevRot = IsLeft ? ISD::ROTR : ISD::ROTL;
- if (isOperationLegalOrCustom(RevRot, VT)) {
+ if (isOperationLegalOrCustom(RevRot, VT) && isPowerOf2_32(EltSizeInBits)) {
SDValue Sub = DAG.getNode(ISD::SUB, DL, ShVT, Zero, Op1);
Result = DAG.getNode(RevRot, DL, VT, Op0, Sub);
return true;
@@ -6239,18 +6236,31 @@
!isOperationLegalOrCustomOrPromote(ISD::AND, VT)))
return false;
- // Otherwise,
- // (rotl x, c) -> (or (shl x, (and c, w-1)), (srl x, (and -c, w-1)))
- // (rotr x, c) -> (or (srl x, (and c, w-1)), (shl x, (and -c, w-1)))
- //
unsigned ShOpc = IsLeft ? ISD::SHL : ISD::SRL;
unsigned HsOpc = IsLeft ? ISD::SRL : ISD::SHL;
SDValue BitWidthMinusOneC = DAG.getConstant(EltSizeInBits - 1, DL, ShVT);
- SDValue NegOp1 = DAG.getNode(ISD::SUB, DL, ShVT, Zero, Op1);
- SDValue And0 = DAG.getNode(ISD::AND, DL, ShVT, Op1, BitWidthMinusOneC);
- SDValue And1 = DAG.getNode(ISD::AND, DL, ShVT, NegOp1, BitWidthMinusOneC);
- Result = DAG.getNode(ISD::OR, DL, VT, DAG.getNode(ShOpc, DL, VT, Op0, And0),
- DAG.getNode(HsOpc, DL, VT, Op0, And1));
+ SDValue ShVal;
+ SDValue HsVal;
+ if (isPowerOf2_32(EltSizeInBits)) {
+ // (rotl x, c) -> x << (c & (w - 1)) | x >> (-c & (w - 1))
+ // (rotr x, c) -> x >> (c & (w - 1)) | x << (-c & (w - 1))
+ SDValue NegOp1 = DAG.getNode(ISD::SUB, DL, ShVT, Zero, Op1);
+ SDValue ShAmt = DAG.getNode(ISD::AND, DL, ShVT, Op1, BitWidthMinusOneC);
+ ShVal = DAG.getNode(ShOpc, DL, VT, Op0, ShAmt);
+ SDValue HsAmt = DAG.getNode(ISD::AND, DL, ShVT, NegOp1, BitWidthMinusOneC);
+ HsVal = DAG.getNode(HsOpc, DL, VT, Op0, HsAmt);
+ } else {
+ // (rotl x, c) -> x << (c % w) | x >> 1 >> (w - 1 - (c % w))
+ // (rotr x, c) -> x >> (c % w) | x << 1 << (w - 1 - (c % w))
+ SDValue BitWidthC = DAG.getConstant(EltSizeInBits, DL, ShVT);
+ SDValue ShAmt = DAG.getNode(ISD::UREM, DL, ShVT, Op1, BitWidthC);
+ ShVal = DAG.getNode(ShOpc, DL, VT, Op0, ShAmt);
+ SDValue HsAmt = DAG.getNode(ISD::SUB, DL, ShVT, BitWidthMinusOneC, ShAmt);
+ SDValue One = DAG.getConstant(1, DL, ShVT);
+ HsVal =
+ DAG.getNode(HsOpc, DL, VT, DAG.getNode(HsOpc, DL, VT, Op0, One), HsAmt);
+ }
+ Result = DAG.getNode(ISD::OR, DL, VT, ShVal, HsVal);
return true;
}
-------------- next part --------------
A non-text attachment was scrubbed...
Name: D86449.287350.patch
Type: text/x-patch
Size: 3669 bytes
Desc: not available
URL: <http://lists.llvm.org/pipermail/llvm-commits/attachments/20200824/e3c0d357/attachment.bin>
More information about the llvm-commits
mailing list