Skip to content

Commit d13c2c2

Browse files
committed
Optimizes shiftmask for shl, srl and sra with selectShiftMask
1 parent 0006cd6 commit d13c2c2

File tree

5 files changed

+755
-1034
lines changed

5 files changed

+755
-1034
lines changed

llvm/lib/Target/WebAssembly/WebAssemblyISelDAGToDAG.cpp

Lines changed: 52 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -70,6 +70,15 @@ class WebAssemblyDAGToDAGISel final : public SelectionDAGISel {
7070
bool SelectAddrOperands32(SDValue Op, SDValue &Offset, SDValue &Addr);
7171
bool SelectAddrOperands64(SDValue Op, SDValue &Offset, SDValue &Addr);
7272

73+
bool selectShiftMask(SDValue N, unsigned ShiftWidth, SDValue &ShAmt);
74+
75+
bool selectShiftMask32(SDValue N, SDValue &ShAmt) {
76+
return selectShiftMask(N, 32, ShAmt);
77+
}
78+
79+
bool selectShiftMask64(SDValue N, SDValue &ShAmt) {
80+
return selectShiftMask(N, 64, ShAmt);
81+
}
7382
// Include the pieces autogenerated from the target description.
7483
#include "WebAssemblyGenDAGISel.inc"
7584

@@ -548,6 +557,49 @@ bool WebAssemblyDAGToDAGISel::SelectAddrOperands64(SDValue Op, SDValue &Offset,
548557
return SelectAddrOperands(MVT::i64, WebAssembly::CONST_I64, Op, Offset, Addr);
549558
}
550559

560+
bool WebAssemblyDAGToDAGISel::selectShiftMask(SDValue N, unsigned ShiftWidth,
561+
SDValue &ShAmt) {
562+
563+
ShAmt = N;
564+
565+
bool HasZext = false;
566+
// Peek through zext.
567+
if (ShAmt->getOpcode() == ISD::ZERO_EXTEND) {
568+
ShAmt = ShAmt.getOperand(0);
569+
HasZext = true;
570+
}
571+
572+
if (ShAmt.getOpcode() == ISD::AND &&
573+
isa<ConstantSDNode>(ShAmt.getOperand(1))) {
574+
const APInt &AndMask = ShAmt.getConstantOperandAPInt(1);
575+
576+
// Since the max shift amount is a power of 2 we can subtract 1 to make a
577+
// mask that covers the bits needed to represent all shift amounts.
578+
assert(isPowerOf2_32(ShiftWidth) && "Unexpected max shift amount!");
579+
APInt ShMask(AndMask.getBitWidth(), ShiftWidth - 1);
580+
581+
if (ShMask.isSubsetOf(AndMask)) {
582+
ShAmt = ShAmt.getOperand(0);
583+
} else {
584+
// TODO: port computeKnownBits from riscv in another PR about rotr and
585+
// rotl
586+
return false;
587+
}
588+
589+
// Only reinstate zext if it's i32 -> i64, WebAssembly would have legalize
590+
// i16 to i32 in the dag otherwise.
591+
if (HasZext && ShiftWidth == 64) {
592+
ShAmt = SDValue(CurDAG->getMachineNode(WebAssembly::I64_EXTEND_U_I32,
593+
SDLoc(N), MVT::i64, ShAmt),
594+
0);
595+
}
596+
return true;
597+
}
598+
599+
// TODO: Port rest of riscv if applicable
600+
return false;
601+
}
602+
551603
/// This pass converts a legalized DAG into a WebAssembly-specific DAG, ready
552604
/// for instruction scheduling.
553605
FunctionPass *llvm::createWebAssemblyISelDag(WebAssemblyTargetMachine &TM,

llvm/lib/Target/WebAssembly/WebAssemblyInstrInteger.td

Lines changed: 10 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -44,6 +44,10 @@ multiclass ComparisonInt<CondCode cond, string name, bits<32> i32Inst, bits<32>
4444
!strconcat("i64.", name), i64Inst>;
4545
}
4646

47+
// ComplexPattern
48+
def shiftMask32 : ComplexPattern<i32, 1, "selectShiftMask32", [], [], 0>;
49+
def shiftMask64 : ComplexPattern<i64, 1, "selectShiftMask64", [], [], 0>;
50+
4751
// The spaces after the names are for aesthetic purposes only, to make
4852
// operands line up vertically after tab expansion.
4953
let isCommutable = 1 in
@@ -94,26 +98,19 @@ defm EQZ_I64 : I<(outs I32:$dst), (ins I64:$src), (outs), (ins),
9498
"i64.eqz \t$dst, $src", "i64.eqz", 0x50>;
9599

96100
// Optimize away an explicit mask on a shift count.
97-
def : Pat<(shl I32:$lhs, (and I32:$rhs, 31)), (SHL_I32 I32:$lhs, I32:$rhs)>;
98-
def : Pat<(sra I32:$lhs, (and I32:$rhs, 31)), (SHR_S_I32 I32:$lhs, I32:$rhs)>;
99-
def : Pat<(srl I32:$lhs, (and I32:$rhs, 31)), (SHR_U_I32 I32:$lhs, I32:$rhs)>;
100-
def : Pat<(shl I64:$lhs, (and I64:$rhs, 63)), (SHL_I64 I64:$lhs, I64:$rhs)>;
101-
def : Pat<(sra I64:$lhs, (and I64:$rhs, 63)), (SHR_S_I64 I64:$lhs, I64:$rhs)>;
102-
def : Pat<(srl I64:$lhs, (and I64:$rhs, 63)), (SHR_U_I64 I64:$lhs, I64:$rhs)>;
101+
def : Pat<(shl I32:$lhs, (shiftMask32 I32:$rhs)), (SHL_I32 I32:$lhs, I32:$rhs)>;
102+
def : Pat<(sra I32:$lhs, (shiftMask32 I32:$rhs)), (SHR_S_I32 I32:$lhs, I32:$rhs)>;
103+
def : Pat<(srl I32:$lhs, (shiftMask32 I32:$rhs)), (SHR_U_I32 I32:$lhs, I32:$rhs)>;
104+
def : Pat<(shl I64:$lhs, (shiftMask64 I64:$rhs)), (SHL_I64 I64:$lhs, I64:$rhs)>;
105+
def : Pat<(sra I64:$lhs, (shiftMask64 I64:$rhs)), (SHR_S_I64 I64:$lhs, I64:$rhs)>;
106+
def : Pat<(srl I64:$lhs, (shiftMask64 I64:$rhs)), (SHR_U_I64 I64:$lhs, I64:$rhs)>;
103107

104108
// Optimize away an explicit mask on a rotate count.
105109
def : Pat<(rotl I32:$lhs, (and I32:$rhs, 31)), (ROTL_I32 I32:$lhs, I32:$rhs)>;
106110
def : Pat<(rotr I32:$lhs, (and I32:$rhs, 31)), (ROTR_I32 I32:$lhs, I32:$rhs)>;
107111
def : Pat<(rotl I64:$lhs, (and I64:$rhs, 63)), (ROTL_I64 I64:$lhs, I64:$rhs)>;
108112
def : Pat<(rotr I64:$lhs, (and I64:$rhs, 63)), (ROTR_I64 I64:$lhs, I64:$rhs)>;
109113

110-
def : Pat<(shl I64:$lhs, (zext (and I32:$rhs, 63))),
111-
(SHL_I64 I64:$lhs, (I64_EXTEND_U_I32 I32:$rhs))>;
112-
def : Pat<(sra I64:$lhs, (zext (and I32:$rhs, 63))),
113-
(SHR_S_I64 I64:$lhs, (I64_EXTEND_U_I32 I32:$rhs))>;
114-
def : Pat<(srl I64:$lhs, (zext (and I32:$rhs, 63))),
115-
(SHR_U_I64 I64:$lhs, (I64_EXTEND_U_I32 I32:$rhs))>;
116-
117114
defm SELECT_I32 : I<(outs I32:$dst), (ins I32:$lhs, I32:$rhs, I32:$cond),
118115
(outs), (ins),
119116
[(set I32:$dst, (select I32:$cond, I32:$lhs, I32:$rhs))],

llvm/test/CodeGen/WebAssembly/disable-feature.ll

Lines changed: 0 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -13,8 +13,6 @@ define i8 @not_use_extend8_s(i8 %v, i8 %x) {
1313
; CHECK-NEXT: i32.const 24
1414
; CHECK-NEXT: i32.shr_s
1515
; CHECK-NEXT: local.get 1
16-
; CHECK-NEXT: i32.const 255
17-
; CHECK-NEXT: i32.and
1816
; CHECK-NEXT: i32.shr_s
1917
; CHECK-NEXT: # fallthrough-return
2018
%a = ashr i8 %v, %x

llvm/test/CodeGen/WebAssembly/legalize.ll

Lines changed: 1 addition & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -14,9 +14,7 @@ define i3 @shl_i3(i3 %a, i3 %b, ptr %p) {
1414
}
1515

1616
; CHECK-LABEL: shl_i53:
17-
; CHECK: i64.const $push0=, 9007199254740991{{$}}
18-
; CHECK: i64.and $push1=, $1, $pop0{{$}}
19-
; CHECK: i64.shl $push2=, $0, $pop1{{$}}
17+
; CHECK: i64.shl $push0=, $0, $1
2018
define i53 @shl_i53(i53 %a, i53 %b, ptr %p) {
2119
%t = shl i53 %a, %b
2220
ret i53 %t

0 commit comments

Comments
 (0)