mirror of
https://github.com/RPCS3/llvm-mirror.git
synced 2024-11-25 20:23:11 +01:00
[AArch64][SVEIntrinsicOpts] Convect cntb/h/w/d to vscale intrinsic or constant.
As is mentioned above Differential Revision: https://reviews.llvm.org/D104852
This commit is contained in:
parent
ecb5bd2ec9
commit
e735ac1e0d
@ -642,6 +642,46 @@ static Optional<Instruction *> instCombineRDFFR(InstCombiner &IC,
|
||||
return IC.replaceInstUsesWith(II, RDFFR);
|
||||
}
|
||||
|
||||
static Optional<Instruction *>
|
||||
instCombineSVECntElts(InstCombiner &IC, IntrinsicInst &II, unsigned NumElts) {
|
||||
const auto Pattern = cast<ConstantInt>(II.getArgOperand(0))->getZExtValue();
|
||||
|
||||
if (Pattern == AArch64SVEPredPattern::all) {
|
||||
LLVMContext &Ctx = II.getContext();
|
||||
IRBuilder<> Builder(Ctx);
|
||||
Builder.SetInsertPoint(&II);
|
||||
|
||||
Constant *StepVal = ConstantInt::get(II.getType(), NumElts);
|
||||
auto *VScale = Builder.CreateVScale(StepVal);
|
||||
VScale->takeName(&II);
|
||||
return IC.replaceInstUsesWith(II, VScale);
|
||||
}
|
||||
|
||||
unsigned MinNumElts = 0;
|
||||
switch (Pattern) {
|
||||
default:
|
||||
return None;
|
||||
case AArch64SVEPredPattern::vl1:
|
||||
case AArch64SVEPredPattern::vl2:
|
||||
case AArch64SVEPredPattern::vl3:
|
||||
case AArch64SVEPredPattern::vl4:
|
||||
case AArch64SVEPredPattern::vl5:
|
||||
case AArch64SVEPredPattern::vl6:
|
||||
case AArch64SVEPredPattern::vl7:
|
||||
case AArch64SVEPredPattern::vl8:
|
||||
MinNumElts = Pattern;
|
||||
break;
|
||||
case AArch64SVEPredPattern::vl16:
|
||||
MinNumElts = 16;
|
||||
break;
|
||||
}
|
||||
|
||||
return NumElts >= MinNumElts
|
||||
? Optional<Instruction *>(IC.replaceInstUsesWith(
|
||||
II, ConstantInt::get(II.getType(), MinNumElts)))
|
||||
: None;
|
||||
}
|
||||
|
||||
Optional<Instruction *>
|
||||
AArch64TTIImpl::instCombineIntrinsic(InstCombiner &IC,
|
||||
IntrinsicInst &II) const {
|
||||
@ -661,6 +701,14 @@ AArch64TTIImpl::instCombineIntrinsic(InstCombiner &IC,
|
||||
case Intrinsic::aarch64_sve_lasta:
|
||||
case Intrinsic::aarch64_sve_lastb:
|
||||
return instCombineSVELast(IC, II);
|
||||
case Intrinsic::aarch64_sve_cntd:
|
||||
return instCombineSVECntElts(IC, II, 2);
|
||||
case Intrinsic::aarch64_sve_cntw:
|
||||
return instCombineSVECntElts(IC, II, 4);
|
||||
case Intrinsic::aarch64_sve_cnth:
|
||||
return instCombineSVECntElts(IC, II, 8);
|
||||
case Intrinsic::aarch64_sve_cntb:
|
||||
return instCombineSVECntElts(IC, II, 16);
|
||||
}
|
||||
|
||||
return None;
|
||||
|
@ -0,0 +1,247 @@
|
||||
; NOTE: Assertions have been autogenerated by utils/update_test_checks.py
|
||||
; RUN: opt -S -instcombine < %s | FileCheck %s
|
||||
|
||||
target triple = "aarch64-unknown-linux-gnu"
|
||||
|
||||
;
|
||||
; CNTB
|
||||
;
|
||||
|
||||
define i64 @cntb_vl1() {
|
||||
; CHECK-LABEL: @cntb_vl1(
|
||||
; CHECK-NEXT: ret i64 1
|
||||
;
|
||||
%out = call i64 @llvm.aarch64.sve.cntb(i32 1)
|
||||
ret i64 %out
|
||||
}
|
||||
|
||||
define i64 @cntb_vl2() {
|
||||
; CHECK-LABEL: @cntb_vl2(
|
||||
; CHECK-NEXT: ret i64 2
|
||||
;
|
||||
%out = call i64 @llvm.aarch64.sve.cntb(i32 2)
|
||||
ret i64 %out
|
||||
}
|
||||
|
||||
define i64 @cntb_vl4() {
|
||||
; CHECK-LABEL: @cntb_vl4(
|
||||
; CHECK-NEXT: ret i64 4
|
||||
;
|
||||
%out = call i64 @llvm.aarch64.sve.cntb(i32 4)
|
||||
ret i64 %out
|
||||
}
|
||||
|
||||
define i64 @cntb_mul3() {
|
||||
; CHECK-LABEL: @cntb_mul3(
|
||||
; CHECK-NEXT: ret i64 24
|
||||
;
|
||||
%cnt = call i64 @llvm.aarch64.sve.cntb(i32 8)
|
||||
%out = mul i64 %cnt, 3
|
||||
ret i64 %out
|
||||
}
|
||||
|
||||
define i64 @cntb_mul4() {
|
||||
; CHECK-LABEL: @cntb_mul4(
|
||||
; CHECK-NEXT: ret i64 64
|
||||
;
|
||||
%cnt = call i64 @llvm.aarch64.sve.cntb(i32 9)
|
||||
%out = mul i64 %cnt, 4
|
||||
ret i64 %out
|
||||
}
|
||||
|
||||
define i64 @cntb_all() {
|
||||
; CHECK-LABEL: @cntb_all(
|
||||
; CHECK-NEXT: [[TMP1:%.*]] = call i64 @llvm.vscale.i64()
|
||||
; CHECK-NEXT: [[OUT:%.*]] = shl i64 [[TMP1]], 4
|
||||
; CHECK-NEXT: ret i64 [[OUT]]
|
||||
;
|
||||
%out = call i64 @llvm.aarch64.sve.cntb(i32 31)
|
||||
ret i64 %out
|
||||
}
|
||||
|
||||
;
|
||||
; CNTH
|
||||
;
|
||||
|
||||
define i64 @cnth_vl1() {
|
||||
; CHECK-LABEL: @cnth_vl1(
|
||||
; CHECK-NEXT: ret i64 1
|
||||
;
|
||||
%out = call i64 @llvm.aarch64.sve.cnth(i32 1)
|
||||
ret i64 %out
|
||||
}
|
||||
|
||||
define i64 @cnth_vl2() {
|
||||
; CHECK-LABEL: @cnth_vl2(
|
||||
; CHECK-NEXT: ret i64 2
|
||||
;
|
||||
%out = call i64 @llvm.aarch64.sve.cnth(i32 2)
|
||||
ret i64 %out
|
||||
}
|
||||
|
||||
define i64 @cnth_vl4() {
|
||||
; CHECK-LABEL: @cnth_vl4(
|
||||
; CHECK-NEXT: ret i64 4
|
||||
;
|
||||
%out = call i64 @llvm.aarch64.sve.cnth(i32 4)
|
||||
ret i64 %out
|
||||
}
|
||||
|
||||
define i64 @cnth_mul3() {
|
||||
; CHECK-LABEL: @cnth_mul3(
|
||||
; CHECK-NEXT: ret i64 24
|
||||
;
|
||||
%cnt = call i64 @llvm.aarch64.sve.cnth(i32 8)
|
||||
%out = mul i64 %cnt, 3
|
||||
ret i64 %out
|
||||
}
|
||||
|
||||
define i64 @cnth_mul4() {
|
||||
; CHECK-LABEL: @cnth_mul4(
|
||||
; CHECK-NEXT: [[CNT:%.*]] = call i64 @llvm.aarch64.sve.cnth(i32 9)
|
||||
; CHECK-NEXT: [[OUT:%.*]] = shl i64 [[CNT]], 2
|
||||
; CHECK-NEXT: ret i64 [[OUT]]
|
||||
;
|
||||
%cnt = call i64 @llvm.aarch64.sve.cnth(i32 9)
|
||||
%out = mul i64 %cnt, 4
|
||||
ret i64 %out
|
||||
}
|
||||
|
||||
define i64 @cnth_all() {
|
||||
; CHECK-LABEL: @cnth_all(
|
||||
; CHECK-NEXT: [[TMP1:%.*]] = call i64 @llvm.vscale.i64()
|
||||
; CHECK-NEXT: [[OUT:%.*]] = shl i64 [[TMP1]], 3
|
||||
; CHECK-NEXT: ret i64 [[OUT]]
|
||||
;
|
||||
%out = call i64 @llvm.aarch64.sve.cnth(i32 31)
|
||||
ret i64 %out
|
||||
}
|
||||
|
||||
;
|
||||
; CNTW
|
||||
;
|
||||
|
||||
define i64 @cntw_vl1() {
|
||||
; CHECK-LABEL: @cntw_vl1(
|
||||
; CHECK-NEXT: ret i64 1
|
||||
;
|
||||
%out = call i64 @llvm.aarch64.sve.cntw(i32 1)
|
||||
ret i64 %out
|
||||
}
|
||||
|
||||
define i64 @cntw_vl2() {
|
||||
; CHECK-LABEL: @cntw_vl2(
|
||||
; CHECK-NEXT: ret i64 2
|
||||
;
|
||||
%out = call i64 @llvm.aarch64.sve.cntw(i32 2)
|
||||
ret i64 %out
|
||||
}
|
||||
|
||||
define i64 @cntw_vl4() {
|
||||
; CHECK-LABEL: @cntw_vl4(
|
||||
; CHECK-NEXT: ret i64 4
|
||||
;
|
||||
%out = call i64 @llvm.aarch64.sve.cntw(i32 4)
|
||||
ret i64 %out
|
||||
}
|
||||
|
||||
define i64 @cntw_mul3() {
|
||||
; CHECK-LABEL: @cntw_mul3(
|
||||
; CHECK-NEXT: [[CNT:%.*]] = call i64 @llvm.aarch64.sve.cntw(i32 8)
|
||||
; CHECK-NEXT: [[OUT:%.*]] = mul i64 [[CNT]], 3
|
||||
; CHECK-NEXT: ret i64 [[OUT]]
|
||||
;
|
||||
%cnt = call i64 @llvm.aarch64.sve.cntw(i32 8)
|
||||
%out = mul i64 %cnt, 3
|
||||
ret i64 %out
|
||||
}
|
||||
|
||||
define i64 @cntw_mul4() {
|
||||
; CHECK-LABEL: @cntw_mul4(
|
||||
; CHECK-NEXT: [[CNT:%.*]] = call i64 @llvm.aarch64.sve.cntw(i32 9)
|
||||
; CHECK-NEXT: [[OUT:%.*]] = shl i64 [[CNT]], 2
|
||||
; CHECK-NEXT: ret i64 [[OUT]]
|
||||
;
|
||||
%cnt = call i64 @llvm.aarch64.sve.cntw(i32 9)
|
||||
%out = mul i64 %cnt, 4
|
||||
ret i64 %out
|
||||
}
|
||||
|
||||
define i64 @cntw_all() {
|
||||
; CHECK-LABEL: @cntw_all(
|
||||
; CHECK-NEXT: [[TMP1:%.*]] = call i64 @llvm.vscale.i64()
|
||||
; CHECK-NEXT: [[OUT:%.*]] = shl i64 [[TMP1]], 2
|
||||
; CHECK-NEXT: ret i64 [[OUT]]
|
||||
;
|
||||
%out = call i64 @llvm.aarch64.sve.cntw(i32 31)
|
||||
ret i64 %out
|
||||
}
|
||||
|
||||
|
||||
;
|
||||
; CNTD
|
||||
;
|
||||
|
||||
define i64 @cntd_vl1() {
|
||||
; CHECK-LABEL: @cntd_vl1(
|
||||
; CHECK-NEXT: ret i64 1
|
||||
;
|
||||
%out = call i64 @llvm.aarch64.sve.cntd(i32 1)
|
||||
ret i64 %out
|
||||
}
|
||||
|
||||
define i64 @cntd_vl2() {
|
||||
; CHECK-LABEL: @cntd_vl2(
|
||||
; CHECK-NEXT: ret i64 2
|
||||
;
|
||||
%out = call i64 @llvm.aarch64.sve.cntd(i32 2)
|
||||
ret i64 %out
|
||||
}
|
||||
|
||||
define i64 @cntd_vl4() {
|
||||
; CHECK-LABEL: @cntd_vl4(
|
||||
; CHECK-NEXT: [[OUT:%.*]] = call i64 @llvm.aarch64.sve.cntd(i32 4)
|
||||
; CHECK-NEXT: ret i64 [[OUT]]
|
||||
;
|
||||
%out = call i64 @llvm.aarch64.sve.cntd(i32 4)
|
||||
ret i64 %out
|
||||
}
|
||||
|
||||
define i64 @cntd_mul3() {
|
||||
; CHECK-LABEL: @cntd_mul3(
|
||||
; CHECK-NEXT: [[CNT:%.*]] = call i64 @llvm.aarch64.sve.cntd(i32 8)
|
||||
; CHECK-NEXT: [[OUT:%.*]] = mul i64 [[CNT]], 3
|
||||
; CHECK-NEXT: ret i64 [[OUT]]
|
||||
;
|
||||
%cnt = call i64 @llvm.aarch64.sve.cntd(i32 8)
|
||||
%out = mul i64 %cnt, 3
|
||||
ret i64 %out
|
||||
}
|
||||
|
||||
define i64 @cntd_mul4() {
|
||||
; CHECK-LABEL: @cntd_mul4(
|
||||
; CHECK-NEXT: [[CNT:%.*]] = call i64 @llvm.aarch64.sve.cntd(i32 9)
|
||||
; CHECK-NEXT: [[OUT:%.*]] = shl i64 [[CNT]], 2
|
||||
; CHECK-NEXT: ret i64 [[OUT]]
|
||||
;
|
||||
%cnt = call i64 @llvm.aarch64.sve.cntd(i32 9)
|
||||
%out = mul i64 %cnt, 4
|
||||
ret i64 %out
|
||||
}
|
||||
|
||||
define i64 @cntd_all() {
|
||||
; CHECK-LABEL: @cntd_all(
|
||||
; CHECK-NEXT: [[TMP1:%.*]] = call i64 @llvm.vscale.i64()
|
||||
; CHECK-NEXT: [[OUT:%.*]] = shl i64 [[TMP1]], 1
|
||||
; CHECK-NEXT: ret i64 [[OUT]]
|
||||
;
|
||||
%out = call i64 @llvm.aarch64.sve.cntd(i32 31)
|
||||
ret i64 %out
|
||||
}
|
||||
|
||||
|
||||
declare i64 @llvm.aarch64.sve.cntb(i32 %pattern)
|
||||
declare i64 @llvm.aarch64.sve.cnth(i32 %pattern)
|
||||
declare i64 @llvm.aarch64.sve.cntw(i32 %pattern)
|
||||
declare i64 @llvm.aarch64.sve.cntd(i32 %pattern)
|
||||
|
Loading…
Reference in New Issue
Block a user