mirror of
https://github.com/RPCS3/llvm-mirror.git
synced 2024-11-23 03:02:36 +01:00
[InstCombine] Add sext(ashr(shl(trunc(x),c),c)) folding support for vectors
Replacing m_ConstantInt with m_Constant permits folding of vectors as well as scalars. Differential Revision: https://reviews.llvm.org/D83058
This commit is contained in:
parent
fdbe62d99b
commit
8257854bda
@ -1460,16 +1460,17 @@ Instruction *InstCombiner::visitSExt(SExtInst &CI) {
|
|||||||
// %d = ashr i32 %a, 30
|
// %d = ashr i32 %a, 30
|
||||||
Value *A = nullptr;
|
Value *A = nullptr;
|
||||||
// TODO: Eventually this could be subsumed by EvaluateInDifferentType.
|
// TODO: Eventually this could be subsumed by EvaluateInDifferentType.
|
||||||
ConstantInt *BA = nullptr, *CA = nullptr;
|
Constant *BA = nullptr, *CA = nullptr;
|
||||||
if (match(Src, m_AShr(m_Shl(m_Trunc(m_Value(A)), m_ConstantInt(BA)),
|
if (match(Src, m_AShr(m_Shl(m_Trunc(m_Value(A)), m_Constant(BA)),
|
||||||
m_ConstantInt(CA))) &&
|
m_Constant(CA))) &&
|
||||||
BA == CA && A->getType() == CI.getType()) {
|
BA == CA && A->getType() == CI.getType()) {
|
||||||
unsigned MidSize = Src->getType()->getScalarSizeInBits();
|
unsigned MidSize = Src->getType()->getScalarSizeInBits();
|
||||||
unsigned SrcDstSize = CI.getType()->getScalarSizeInBits();
|
unsigned SrcDstSize = CI.getType()->getScalarSizeInBits();
|
||||||
unsigned ShAmt = CA->getZExtValue()+SrcDstSize-MidSize;
|
Constant *SizeDiff = ConstantInt::get(CA->getType(), SrcDstSize - MidSize);
|
||||||
Constant *ShAmtV = ConstantInt::get(CI.getType(), ShAmt);
|
Constant *ShAmt = ConstantExpr::getAdd(CA, SizeDiff);
|
||||||
A = Builder.CreateShl(A, ShAmtV, CI.getName());
|
Constant *ShAmtExt = ConstantExpr::getSExt(ShAmt, CI.getType());
|
||||||
return BinaryOperator::CreateAShr(A, ShAmtV);
|
A = Builder.CreateShl(A, ShAmtExt, CI.getName());
|
||||||
|
return BinaryOperator::CreateAShr(A, ShAmtExt);
|
||||||
}
|
}
|
||||||
|
|
||||||
return nullptr;
|
return nullptr;
|
||||||
|
@ -140,10 +140,8 @@ define i32 @test10(i32 %i) {
|
|||||||
|
|
||||||
define <2 x i32> @test10_vec(<2 x i32> %i) {
|
define <2 x i32> @test10_vec(<2 x i32> %i) {
|
||||||
; CHECK-LABEL: @test10_vec(
|
; CHECK-LABEL: @test10_vec(
|
||||||
; CHECK-NEXT: [[A:%.*]] = trunc <2 x i32> [[I:%.*]] to <2 x i8>
|
; CHECK-NEXT: [[D1:%.*]] = shl <2 x i32> [[I:%.*]], <i32 30, i32 30>
|
||||||
; CHECK-NEXT: [[B:%.*]] = shl <2 x i8> [[A]], <i8 6, i8 6>
|
; CHECK-NEXT: [[D:%.*]] = ashr exact <2 x i32> [[D1]], <i32 30, i32 30>
|
||||||
; CHECK-NEXT: [[C:%.*]] = ashr exact <2 x i8> [[B]], <i8 6, i8 6>
|
|
||||||
; CHECK-NEXT: [[D:%.*]] = sext <2 x i8> [[C]] to <2 x i32>
|
|
||||||
; CHECK-NEXT: ret <2 x i32> [[D]]
|
; CHECK-NEXT: ret <2 x i32> [[D]]
|
||||||
;
|
;
|
||||||
%A = trunc <2 x i32> %i to <2 x i8>
|
%A = trunc <2 x i32> %i to <2 x i8>
|
||||||
@ -155,10 +153,8 @@ define <2 x i32> @test10_vec(<2 x i32> %i) {
|
|||||||
|
|
||||||
define <2 x i32> @test10_vec_nonuniform(<2 x i32> %i) {
|
define <2 x i32> @test10_vec_nonuniform(<2 x i32> %i) {
|
||||||
; CHECK-LABEL: @test10_vec_nonuniform(
|
; CHECK-LABEL: @test10_vec_nonuniform(
|
||||||
; CHECK-NEXT: [[A:%.*]] = trunc <2 x i32> [[I:%.*]] to <2 x i8>
|
; CHECK-NEXT: [[D1:%.*]] = shl <2 x i32> [[I:%.*]], <i32 30, i32 27>
|
||||||
; CHECK-NEXT: [[B:%.*]] = shl <2 x i8> [[A]], <i8 6, i8 3>
|
; CHECK-NEXT: [[D:%.*]] = ashr <2 x i32> [[D1]], <i32 30, i32 27>
|
||||||
; CHECK-NEXT: [[C:%.*]] = ashr <2 x i8> [[B]], <i8 6, i8 3>
|
|
||||||
; CHECK-NEXT: [[D:%.*]] = sext <2 x i8> [[C]] to <2 x i32>
|
|
||||||
; CHECK-NEXT: ret <2 x i32> [[D]]
|
; CHECK-NEXT: ret <2 x i32> [[D]]
|
||||||
;
|
;
|
||||||
%A = trunc <2 x i32> %i to <2 x i8>
|
%A = trunc <2 x i32> %i to <2 x i8>
|
||||||
@ -170,10 +166,8 @@ define <2 x i32> @test10_vec_nonuniform(<2 x i32> %i) {
|
|||||||
|
|
||||||
define <2 x i32> @test10_vec_undef(<2 x i32> %i) {
|
define <2 x i32> @test10_vec_undef(<2 x i32> %i) {
|
||||||
; CHECK-LABEL: @test10_vec_undef(
|
; CHECK-LABEL: @test10_vec_undef(
|
||||||
; CHECK-NEXT: [[A:%.*]] = trunc <2 x i32> [[I:%.*]] to <2 x i8>
|
; CHECK-NEXT: [[D1:%.*]] = shl <2 x i32> [[I:%.*]], <i32 30, i32 0>
|
||||||
; CHECK-NEXT: [[B:%.*]] = shl <2 x i8> [[A]], <i8 6, i8 undef>
|
; CHECK-NEXT: [[D:%.*]] = ashr <2 x i32> [[D1]], <i32 30, i32 0>
|
||||||
; CHECK-NEXT: [[C:%.*]] = ashr <2 x i8> [[B]], <i8 6, i8 undef>
|
|
||||||
; CHECK-NEXT: [[D:%.*]] = sext <2 x i8> [[C]] to <2 x i32>
|
|
||||||
; CHECK-NEXT: ret <2 x i32> [[D]]
|
; CHECK-NEXT: ret <2 x i32> [[D]]
|
||||||
;
|
;
|
||||||
%A = trunc <2 x i32> %i to <2 x i8>
|
%A = trunc <2 x i32> %i to <2 x i8>
|
||||||
|
@ -82,9 +82,8 @@ define i64 @test2(i64 %a) {
|
|||||||
define <2 x i64> @test2_vec(<2 x i64> %a) {
|
define <2 x i64> @test2_vec(<2 x i64> %a) {
|
||||||
; CHECK-LABEL: @test2_vec(
|
; CHECK-LABEL: @test2_vec(
|
||||||
; CHECK-NEXT: [[B:%.*]] = trunc <2 x i64> [[A:%.*]] to <2 x i32>
|
; CHECK-NEXT: [[B:%.*]] = trunc <2 x i64> [[A:%.*]] to <2 x i32>
|
||||||
; CHECK-NEXT: [[C:%.*]] = shl <2 x i32> [[B]], <i32 4, i32 4>
|
; CHECK-NEXT: [[D1:%.*]] = shl <2 x i64> [[A]], <i64 36, i64 36>
|
||||||
; CHECK-NEXT: [[Q:%.*]] = ashr exact <2 x i32> [[C]], <i32 4, i32 4>
|
; CHECK-NEXT: [[D:%.*]] = ashr exact <2 x i64> [[D1]], <i64 36, i64 36>
|
||||||
; CHECK-NEXT: [[D:%.*]] = sext <2 x i32> [[Q]] to <2 x i64>
|
|
||||||
; CHECK-NEXT: call void @use_vec(<2 x i32> [[B]])
|
; CHECK-NEXT: call void @use_vec(<2 x i32> [[B]])
|
||||||
; CHECK-NEXT: ret <2 x i64> [[D]]
|
; CHECK-NEXT: ret <2 x i64> [[D]]
|
||||||
;
|
;
|
||||||
@ -99,9 +98,8 @@ define <2 x i64> @test2_vec(<2 x i64> %a) {
|
|||||||
define <2 x i64> @test2_vec_nonuniform(<2 x i64> %a) {
|
define <2 x i64> @test2_vec_nonuniform(<2 x i64> %a) {
|
||||||
; CHECK-LABEL: @test2_vec_nonuniform(
|
; CHECK-LABEL: @test2_vec_nonuniform(
|
||||||
; CHECK-NEXT: [[B:%.*]] = trunc <2 x i64> [[A:%.*]] to <2 x i32>
|
; CHECK-NEXT: [[B:%.*]] = trunc <2 x i64> [[A:%.*]] to <2 x i32>
|
||||||
; CHECK-NEXT: [[C:%.*]] = shl <2 x i32> [[B]], <i32 4, i32 5>
|
; CHECK-NEXT: [[D1:%.*]] = shl <2 x i64> [[A]], <i64 36, i64 37>
|
||||||
; CHECK-NEXT: [[Q:%.*]] = ashr <2 x i32> [[C]], <i32 4, i32 5>
|
; CHECK-NEXT: [[D:%.*]] = ashr <2 x i64> [[D1]], <i64 36, i64 37>
|
||||||
; CHECK-NEXT: [[D:%.*]] = sext <2 x i32> [[Q]] to <2 x i64>
|
|
||||||
; CHECK-NEXT: call void @use_vec(<2 x i32> [[B]])
|
; CHECK-NEXT: call void @use_vec(<2 x i32> [[B]])
|
||||||
; CHECK-NEXT: ret <2 x i64> [[D]]
|
; CHECK-NEXT: ret <2 x i64> [[D]]
|
||||||
;
|
;
|
||||||
@ -116,9 +114,8 @@ define <2 x i64> @test2_vec_nonuniform(<2 x i64> %a) {
|
|||||||
define <2 x i64> @test2_vec_undef(<2 x i64> %a) {
|
define <2 x i64> @test2_vec_undef(<2 x i64> %a) {
|
||||||
; CHECK-LABEL: @test2_vec_undef(
|
; CHECK-LABEL: @test2_vec_undef(
|
||||||
; CHECK-NEXT: [[B:%.*]] = trunc <2 x i64> [[A:%.*]] to <2 x i32>
|
; CHECK-NEXT: [[B:%.*]] = trunc <2 x i64> [[A:%.*]] to <2 x i32>
|
||||||
; CHECK-NEXT: [[C:%.*]] = shl <2 x i32> [[B]], <i32 4, i32 undef>
|
; CHECK-NEXT: [[D1:%.*]] = shl <2 x i64> [[A]], <i64 36, i64 0>
|
||||||
; CHECK-NEXT: [[Q:%.*]] = ashr <2 x i32> [[C]], <i32 4, i32 undef>
|
; CHECK-NEXT: [[D:%.*]] = ashr <2 x i64> [[D1]], <i64 36, i64 0>
|
||||||
; CHECK-NEXT: [[D:%.*]] = sext <2 x i32> [[Q]] to <2 x i64>
|
|
||||||
; CHECK-NEXT: call void @use_vec(<2 x i32> [[B]])
|
; CHECK-NEXT: call void @use_vec(<2 x i32> [[B]])
|
||||||
; CHECK-NEXT: ret <2 x i64> [[D]]
|
; CHECK-NEXT: ret <2 x i64> [[D]]
|
||||||
;
|
;
|
||||||
|
Loading…
Reference in New Issue
Block a user