mirror of
https://github.com/RPCS3/llvm-mirror.git
synced 2024-11-22 02:33:06 +01:00
[RISCV] Optimize bitwise and with constant for the Zbs extension
This patch optimizes (and r i) to (BCLRI (BCLRI r, i0), i1) in which i = ~((1<<i0) | (1<<i1)). or (BCLRI (ANDI r, i0), i1) in which i = i0 & ~(1<<i1). Reviewed By: craig.topper Differential Revision: https://reviews.llvm.org/D103743
This commit is contained in:
parent
4cc1a31398
commit
762e1ae8c2
@ -128,6 +128,49 @@ def BSETINVORIMaskLow : SDNodeXForm<imm, [{
|
||||
SDLoc(N), N->getValueType(0));
|
||||
}]>;
|
||||
|
||||
// Check if (and r, i) can be optimized to (BCLRI (BCLRI r, i0), i1),
|
||||
// in which i = ~((1<<i0) | (1<<i1)).
|
||||
def BCLRITwoBitsMask : PatLeaf<(imm), [{
|
||||
if (!N->hasOneUse())
|
||||
return false;
|
||||
// The immediate should not be a simm12.
|
||||
if (isInt<12>(N->getSExtValue()))
|
||||
return false;
|
||||
// The immediate must have exactly two bits clear.
|
||||
return countPopulation(N->getZExtValue()) == Subtarget->getXLen() - 2;
|
||||
}]>;
|
||||
|
||||
def BCLRITwoBitsMaskLow : SDNodeXForm<imm, [{
|
||||
return CurDAG->getTargetConstant(countTrailingZeros(~N->getZExtValue()),
|
||||
SDLoc(N), N->getValueType(0));
|
||||
}]>;
|
||||
|
||||
def BCLRITwoBitsMaskHigh : SDNodeXForm<imm, [{
|
||||
uint64_t I = N->getSExtValue();
|
||||
if (!Subtarget->is64Bit())
|
||||
I |= 0xffffffffull << 32;
|
||||
return CurDAG->getTargetConstant(63 - countLeadingZeros(~I), SDLoc(N),
|
||||
N->getValueType(0));
|
||||
}]>;
|
||||
|
||||
// Check if (and r, i) can be optimized to (BCLRI (ANDI r, i0), i1),
|
||||
// in which i = i0 & ~(1<<i1).
|
||||
def BCLRIANDIMask : PatLeaf<(imm), [{
|
||||
if (!N->hasOneUse())
|
||||
return false;
|
||||
// The immediate should not be a simm12.
|
||||
if (isInt<12>(N->getSExtValue()))
|
||||
return false;
|
||||
// There should be only one clear bit from bit 11 to the top.
|
||||
uint64_t I = N->getZExtValue() | 0x7ff;
|
||||
return Subtarget->is64Bit() ? isPowerOf2_64(~I) : isPowerOf2_32(~I);
|
||||
}]>;
|
||||
|
||||
def BCLRIANDIMaskLow : SDNodeXForm<imm, [{
|
||||
return CurDAG->getTargetConstant((N->getZExtValue() & 0x7ff) | ~0x7ffull,
|
||||
SDLoc(N), N->getValueType(0));
|
||||
}]>;
|
||||
|
||||
//===----------------------------------------------------------------------===//
|
||||
// Instruction class templates
|
||||
//===----------------------------------------------------------------------===//
|
||||
@ -777,6 +820,12 @@ def : Pat<(or GPR:$r, BSETINVORIMask:$i),
|
||||
def : Pat<(xor GPR:$r, BSETINVORIMask:$i),
|
||||
(BINVI (XORI GPR:$r, (BSETINVORIMaskLow BSETINVORIMask:$i)),
|
||||
(BSETINVTwoBitsMaskHigh BSETINVORIMask:$i))>;
|
||||
def : Pat<(and GPR:$r, BCLRITwoBitsMask:$i),
|
||||
(BCLRI (BCLRI GPR:$r, (BCLRITwoBitsMaskLow BCLRITwoBitsMask:$i)),
|
||||
(BCLRITwoBitsMaskHigh BCLRITwoBitsMask:$i))>;
|
||||
def : Pat<(and GPR:$r, BCLRIANDIMask:$i),
|
||||
(BCLRI (ANDI GPR:$r, (BCLRIANDIMaskLow BCLRIANDIMask:$i)),
|
||||
(BCLRITwoBitsMaskHigh BCLRIANDIMask:$i))>;
|
||||
}
|
||||
|
||||
// There's no encoding for roli in the the 'B' extension as it can be
|
||||
|
@ -560,16 +560,14 @@ define i32 @sbclri_i32_large0(i32 %a) nounwind {
|
||||
;
|
||||
; RV32IB-LABEL: sbclri_i32_large0:
|
||||
; RV32IB: # %bb.0:
|
||||
; RV32IB-NEXT: lui a1, 1044480
|
||||
; RV32IB-NEXT: addi a1, a1, -256
|
||||
; RV32IB-NEXT: and a0, a0, a1
|
||||
; RV32IB-NEXT: andi a0, a0, -256
|
||||
; RV32IB-NEXT: bclri a0, a0, 24
|
||||
; RV32IB-NEXT: ret
|
||||
;
|
||||
; RV32IBS-LABEL: sbclri_i32_large0:
|
||||
; RV32IBS: # %bb.0:
|
||||
; RV32IBS-NEXT: lui a1, 1044480
|
||||
; RV32IBS-NEXT: addi a1, a1, -256
|
||||
; RV32IBS-NEXT: and a0, a0, a1
|
||||
; RV32IBS-NEXT: andi a0, a0, -256
|
||||
; RV32IBS-NEXT: bclri a0, a0, 24
|
||||
; RV32IBS-NEXT: ret
|
||||
%and = and i32 %a, -16777472
|
||||
ret i32 %and
|
||||
@ -585,21 +583,65 @@ define i32 @sbclri_i32_large1(i32 %a) nounwind {
|
||||
;
|
||||
; RV32IB-LABEL: sbclri_i32_large1:
|
||||
; RV32IB: # %bb.0:
|
||||
; RV32IB-NEXT: lui a1, 1044464
|
||||
; RV32IB-NEXT: addi a1, a1, -1
|
||||
; RV32IB-NEXT: and a0, a0, a1
|
||||
; RV32IB-NEXT: bclri a0, a0, 16
|
||||
; RV32IB-NEXT: bclri a0, a0, 24
|
||||
; RV32IB-NEXT: ret
|
||||
;
|
||||
; RV32IBS-LABEL: sbclri_i32_large1:
|
||||
; RV32IBS: # %bb.0:
|
||||
; RV32IBS-NEXT: lui a1, 1044464
|
||||
; RV32IBS-NEXT: addi a1, a1, -1
|
||||
; RV32IBS-NEXT: and a0, a0, a1
|
||||
; RV32IBS-NEXT: bclri a0, a0, 16
|
||||
; RV32IBS-NEXT: bclri a0, a0, 24
|
||||
; RV32IBS-NEXT: ret
|
||||
%and = and i32 %a, -16842753
|
||||
ret i32 %and
|
||||
}
|
||||
|
||||
define i32 @sbclri_i32_large2(i32 %0) {
|
||||
; RV32I-LABEL: sbclri_i32_large2:
|
||||
; RV32I: # %bb.0:
|
||||
; RV32I-NEXT: lui a1, 524288
|
||||
; RV32I-NEXT: addi a1, a1, -5
|
||||
; RV32I-NEXT: and a0, a0, a1
|
||||
; RV32I-NEXT: ret
|
||||
;
|
||||
; RV32IB-LABEL: sbclri_i32_large2:
|
||||
; RV32IB: # %bb.0:
|
||||
; RV32IB-NEXT: bclri a0, a0, 2
|
||||
; RV32IB-NEXT: bclri a0, a0, 31
|
||||
; RV32IB-NEXT: ret
|
||||
;
|
||||
; RV32IBS-LABEL: sbclri_i32_large2:
|
||||
; RV32IBS: # %bb.0:
|
||||
; RV32IBS-NEXT: bclri a0, a0, 2
|
||||
; RV32IBS-NEXT: bclri a0, a0, 31
|
||||
; RV32IBS-NEXT: ret
|
||||
%2 = and i32 %0, 2147483643
|
||||
ret i32 %2
|
||||
}
|
||||
|
||||
define i32 @sbclri_i32_large3(i32 %0) {
|
||||
; RV32I-LABEL: sbclri_i32_large3:
|
||||
; RV32I: # %bb.0:
|
||||
; RV32I-NEXT: lui a1, 524288
|
||||
; RV32I-NEXT: addi a1, a1, -6
|
||||
; RV32I-NEXT: and a0, a0, a1
|
||||
; RV32I-NEXT: ret
|
||||
;
|
||||
; RV32IB-LABEL: sbclri_i32_large3:
|
||||
; RV32IB: # %bb.0:
|
||||
; RV32IB-NEXT: andi a0, a0, -6
|
||||
; RV32IB-NEXT: bclri a0, a0, 31
|
||||
; RV32IB-NEXT: ret
|
||||
;
|
||||
; RV32IBS-LABEL: sbclri_i32_large3:
|
||||
; RV32IBS: # %bb.0:
|
||||
; RV32IBS-NEXT: andi a0, a0, -6
|
||||
; RV32IBS-NEXT: bclri a0, a0, 31
|
||||
; RV32IBS-NEXT: ret
|
||||
%2 = and i32 %0, 2147483642
|
||||
ret i32 %2
|
||||
}
|
||||
|
||||
define i32 @sbseti_i32_10(i32 %a) nounwind {
|
||||
; RV32I-LABEL: sbseti_i32_10:
|
||||
; RV32I: # %bb.0:
|
||||
|
@ -810,16 +810,14 @@ define i64 @sbclri_i64_large0(i64 %a) nounwind {
|
||||
;
|
||||
; RV64IB-LABEL: sbclri_i64_large0:
|
||||
; RV64IB: # %bb.0:
|
||||
; RV64IB-NEXT: lui a1, 1044480
|
||||
; RV64IB-NEXT: addiw a1, a1, -256
|
||||
; RV64IB-NEXT: and a0, a0, a1
|
||||
; RV64IB-NEXT: andi a0, a0, -256
|
||||
; RV64IB-NEXT: bclri a0, a0, 24
|
||||
; RV64IB-NEXT: ret
|
||||
;
|
||||
; RV64IBS-LABEL: sbclri_i64_large0:
|
||||
; RV64IBS: # %bb.0:
|
||||
; RV64IBS-NEXT: lui a1, 1044480
|
||||
; RV64IBS-NEXT: addiw a1, a1, -256
|
||||
; RV64IBS-NEXT: and a0, a0, a1
|
||||
; RV64IBS-NEXT: andi a0, a0, -256
|
||||
; RV64IBS-NEXT: bclri a0, a0, 24
|
||||
; RV64IBS-NEXT: ret
|
||||
%and = and i64 %a, -16777472
|
||||
ret i64 %and
|
||||
@ -835,16 +833,14 @@ define i64 @sbclri_i64_large1(i64 %a) nounwind {
|
||||
;
|
||||
; RV64IB-LABEL: sbclri_i64_large1:
|
||||
; RV64IB: # %bb.0:
|
||||
; RV64IB-NEXT: lui a1, 1044464
|
||||
; RV64IB-NEXT: addiw a1, a1, -1
|
||||
; RV64IB-NEXT: and a0, a0, a1
|
||||
; RV64IB-NEXT: bclri a0, a0, 16
|
||||
; RV64IB-NEXT: bclri a0, a0, 24
|
||||
; RV64IB-NEXT: ret
|
||||
;
|
||||
; RV64IBS-LABEL: sbclri_i64_large1:
|
||||
; RV64IBS: # %bb.0:
|
||||
; RV64IBS-NEXT: lui a1, 1044464
|
||||
; RV64IBS-NEXT: addiw a1, a1, -1
|
||||
; RV64IBS-NEXT: and a0, a0, a1
|
||||
; RV64IBS-NEXT: bclri a0, a0, 16
|
||||
; RV64IBS-NEXT: bclri a0, a0, 24
|
||||
; RV64IBS-NEXT: ret
|
||||
%and = and i64 %a, -16842753
|
||||
ret i64 %and
|
||||
|
Loading…
Reference in New Issue
Block a user