[llvm] e4e7bde - [AArch64]Combine BFXIL to ORR with right shift for ISD::OR instruction selection
Mingming Liu via llvm-commits
llvm-commits at lists.llvm.org
Tue Nov 8 11:20:52 PST 2022
Author: Mingming Liu
Date: 2022-11-08T11:20:43-08:00
New Revision: e4e7bdebb180ea81aa7927797c20e694ed18bee8
URL: https://github.com/llvm/llvm-project/commit/e4e7bdebb180ea81aa7927797c20e694ed18bee8
DIFF: https://github.com/llvm/llvm-project/commit/e4e7bdebb180ea81aa7927797c20e694ed18bee8.diff
LOG: [AArch64]Combine BFXIL to ORR with right shift for ISD::OR instruction selection
- This extends the existing helper function 'isWorthFoldingIntoOrrWithLeftShift' into
'isWorthFoldingIntoOrrWithShift', and encode right-shift imm (the
encoding of left-shift imm is no-op).
Reviewed By: dmgreen
Differential Revision: https://reviews.llvm.org/D137465
Added:
Modified:
llvm/lib/Target/AArch64/AArch64ISelDAGToDAG.cpp
llvm/test/CodeGen/AArch64/fcopysign.ll
Removed:
################################################################################
diff --git a/llvm/lib/Target/AArch64/AArch64ISelDAGToDAG.cpp b/llvm/lib/Target/AArch64/AArch64ISelDAGToDAG.cpp
index 42aad756fcd2..04966b8e1375 100644
--- a/llvm/lib/Target/AArch64/AArch64ISelDAGToDAG.cpp
+++ b/llvm/lib/Target/AArch64/AArch64ISelDAGToDAG.cpp
@@ -2803,11 +2803,10 @@ static bool tryBitfieldInsertOpFromOrAndImm(SDNode *N, SelectionDAG *CurDAG) {
return true;
}
-static bool isWorthFoldingIntoOrrWithLeftShift(SDValue Dst,
- SelectionDAG *CurDAG,
- SDValue &LeftShiftedOperand,
- uint64_t &LeftShiftAmount) {
- // Avoid folding Dst into ORR-with-left-shift if Dst has other uses than ORR.
+static bool isWorthFoldingIntoOrrWithShift(SDValue Dst, SelectionDAG *CurDAG,
+ SDValue &ShiftedOperand,
+ uint64_t &ShiftAmount) {
+ // Avoid folding Dst into ORR-with-shift if Dst has other uses than ORR.
if (!Dst.hasOneUse())
return false;
@@ -2852,23 +2851,32 @@ static bool isWorthFoldingIntoOrrWithLeftShift(SDValue Dst,
VT),
CurDAG->getTargetConstant(
SrlImm + NumTrailingZeroInShiftedMask + MaskWidth - 1, DL, VT));
- LeftShiftedOperand = SDValue(UBFMNode, 0);
- LeftShiftAmount = NumTrailingZeroInShiftedMask;
+ ShiftedOperand = SDValue(UBFMNode, 0);
+ ShiftAmount = NumTrailingZeroInShiftedMask;
return true;
}
}
- } else if (isOpcWithIntImmediate(Dst.getNode(), ISD::SHL, ShlImm)) {
- LeftShiftedOperand = Dst.getOperand(0);
- LeftShiftAmount = ShlImm;
+ return false;
+ }
+
+ if (isOpcWithIntImmediate(Dst.getNode(), ISD::SHL, ShlImm)) {
+ ShiftedOperand = Dst.getOperand(0);
+ ShiftAmount = ShlImm;
+ return true;
+ }
+
+ uint64_t SrlImm;
+ if (isOpcWithIntImmediate(Dst.getNode(), ISD::SRL, SrlImm)) {
+ ShiftedOperand = Dst.getOperand(0);
+ ShiftAmount = AArch64_AM::getShifterImm(AArch64_AM::LSR, SrlImm);
return true;
}
- // FIXME: Extend the implementation to optimize if Dst is an SRL node.
return false;
}
-static bool tryOrrWithLeftShift(SDNode *N, SDValue OrOpd0, SDValue OrOpd1,
- SDValue Src, SDValue Dst, SelectionDAG *CurDAG,
- const bool BiggerPattern) {
+static bool tryOrrWithShift(SDNode *N, SDValue OrOpd0, SDValue OrOpd1,
+ SDValue Src, SDValue Dst, SelectionDAG *CurDAG,
+ const bool BiggerPattern) {
EVT VT = N->getValueType(0);
assert((VT == MVT::i32 || VT == MVT::i64) &&
"Expect result type to be i32 or i64 since N is combinable to BFM");
@@ -2890,13 +2898,13 @@ static bool tryOrrWithLeftShift(SDNode *N, SDValue OrOpd0, SDValue OrOpd1,
// one node (from Rd), ORR is better since it has higher throughput and
// smaller latency than BFM on many AArch64 processors (and for the rest
// ORR is at least as good as BFM).
- SDValue LeftShiftedOperand;
- uint64_t LeftShiftAmount;
- if (isWorthFoldingIntoOrrWithLeftShift(Dst, CurDAG, LeftShiftedOperand,
- LeftShiftAmount)) {
+ SDValue ShiftedOperand;
+ uint64_t ShiftAmount;
+ if (isWorthFoldingIntoOrrWithShift(Dst, CurDAG, ShiftedOperand,
+ ShiftAmount)) {
unsigned OrrOpc = (VT == MVT::i32) ? AArch64::ORRWrs : AArch64::ORRXrs;
- SDValue Ops[] = {OrOpd0, LeftShiftedOperand,
- CurDAG->getTargetConstant(LeftShiftAmount, DL, VT)};
+ SDValue Ops[] = {OrOpd0, ShiftedOperand,
+ CurDAG->getTargetConstant(ShiftAmount, DL, VT)};
CurDAG->SelectNodeTo(N, OrrOpc, VT, Ops);
return true;
}
@@ -2907,7 +2915,6 @@ static bool tryOrrWithLeftShift(SDNode *N, SDValue OrOpd0, SDValue OrOpd1,
assert((!BiggerPattern) && "BiggerPattern should be handled above");
uint64_t ShlImm;
- // FIXME: Extend the implementation if OrOpd0 is an SRL node.
if (isOpcWithIntImmediate(OrOpd0.getNode(), ISD::SHL, ShlImm) &&
OrOpd0.getOperand(0) == Src && OrOpd0.hasOneUse()) {
unsigned OrrOpc = (VT == MVT::i32) ? AArch64::ORRWrs : AArch64::ORRXrs;
@@ -3022,11 +3029,9 @@ static bool tryBitfieldInsertOpFromOr(SDNode *N, const APInt &UsefulBits,
Dst = OrOpd1Val;
// Before selecting ISD::OR node to AArch64::BFM, see if an AArch64::ORR
- // with left-shifted operand is more efficient.
- // FIXME: Extend this to compare AArch64::BFM and AArch64::ORR with
- // right-shifted operand as well.
- if (tryOrrWithLeftShift(N, OrOpd0Val, OrOpd1Val, Src, Dst, CurDAG,
- BiggerPattern))
+ // with shifted operand is more efficient.
+ if (tryOrrWithShift(N, OrOpd0Val, OrOpd1Val, Src, Dst, CurDAG,
+ BiggerPattern))
return true;
// both parts match
diff --git a/llvm/test/CodeGen/AArch64/fcopysign.ll b/llvm/test/CodeGen/AArch64/fcopysign.ll
index d633b641e0fe..74d1818b6a4a 100644
--- a/llvm/test/CodeGen/AArch64/fcopysign.ll
+++ b/llvm/test/CodeGen/AArch64/fcopysign.ll
@@ -63,8 +63,8 @@ define fp128 at copysign1() {
; CHECK-NEXT: ldr w8, [x8, :lo12:val_float]
; CHECK-NEXT: ldrb w9, [sp, #15]
; CHECK-NEXT: and w8, w8, #0x80000000
-; CHECK-NEXT: lsr w8, w8, #24
-; CHECK-NEXT: bfxil w8, w9, #0, #7
+; CHECK-NEXT: and w9, w9, #0x7f
+; CHECK-NEXT: orr w8, w9, w8, lsr #24
; CHECK-NEXT: strb w8, [sp, #15]
; CHECK-NEXT: ldr q0, [sp], #16
; CHECK-NEXT: ret
@@ -79,8 +79,8 @@ define fp128 at copysign1() {
; CHECK-NONEON-NEXT: ldr w8, [x8, :lo12:val_float]
; CHECK-NONEON-NEXT: ldrb w9, [sp, #15]
; CHECK-NONEON-NEXT: and w8, w8, #0x80000000
-; CHECK-NONEON-NEXT: lsr w8, w8, #24
-; CHECK-NONEON-NEXT: bfxil w8, w9, #0, #7
+; CHECK-NONEON-NEXT: and w9, w9, #0x7f
+; CHECK-NONEON-NEXT: orr w8, w9, w8, lsr #24
; CHECK-NONEON-NEXT: strb w8, [sp, #15]
; CHECK-NONEON-NEXT: ldr q0, [sp], #16
; CHECK-NONEON-NEXT: ret
More information about the llvm-commits
mailing list