From: Craig Topper Date: Wed, 2 Aug 2017 20:25:56 +0000 (+0000) Subject: [InstCombine] Support sext in foldLogicCastConstant X-Git-Tag: llvmorg-6.0.0-rc1~11069 X-Git-Url: http://review.tizen.org/git/?a=commitdiff_plain;h=ae9b87d10cb501231a79ba972dd4654b38dc9f93;p=platform%2Fupstream%2Fllvm.git [InstCombine] Support sext in foldLogicCastConstant This adds support for sext in foldLogicCastConstant. This is a prerequisite for D36214. Differential Revision: https://reviews.llvm.org/D36234 llvm-svn: 309880 --- diff --git a/llvm/lib/Transforms/InstCombine/InstCombineAndOrXor.cpp b/llvm/lib/Transforms/InstCombine/InstCombineAndOrXor.cpp index 9d68201..87678f3 100644 --- a/llvm/lib/Transforms/InstCombine/InstCombineAndOrXor.cpp +++ b/llvm/lib/Transforms/InstCombine/InstCombineAndOrXor.cpp @@ -1089,10 +1089,10 @@ static Instruction *foldLogicCastConstant(BinaryOperator &Logic, CastInst *Cast, Type *DestTy = Logic.getType(); Type *SrcTy = Cast->getSrcTy(); - // Move the logic operation ahead of a zext if the constant is unchanged in - // the smaller source type. Performing the logic in a smaller type may provide - // more information to later folds, and the smaller logic instruction may be - // cheaper (particularly in the case of vectors). + // Move the logic operation ahead of a zext or sext if the constant is + // unchanged in the smaller source type. Performing the logic in a smaller + // type may provide more information to later folds, and the smaller logic + // instruction may be cheaper (particularly in the case of vectors). Value *X; if (match(Cast, m_OneUse(m_ZExt(m_Value(X))))) { Constant *TruncC = ConstantExpr::getTrunc(C, SrcTy); @@ -1104,6 +1104,16 @@ static Instruction *foldLogicCastConstant(BinaryOperator &Logic, CastInst *Cast, } } + if (match(Cast, m_OneUse(m_SExt(m_Value(X))))) { + Constant *TruncC = ConstantExpr::getTrunc(C, SrcTy); + Constant *SextTruncC = ConstantExpr::getSExt(TruncC, DestTy); + if (SextTruncC == C) { + // LogicOpc (sext X), C --> sext (LogicOpc X, C) + Value *NewOp = Builder.CreateBinOp(LogicOpc, X, TruncC); + return new SExtInst(NewOp, DestTy); + } + } + return nullptr; } diff --git a/llvm/test/Transforms/InstCombine/cast.ll b/llvm/test/Transforms/InstCombine/cast.ll index 700bf48..dedbd78 100644 --- a/llvm/test/Transforms/InstCombine/cast.ll +++ b/llvm/test/Transforms/InstCombine/cast.ll @@ -587,9 +587,9 @@ define i64 @test46(i64 %A) { define i64 @test47(i8 %A) { ; CHECK-LABEL: @test47( -; CHECK-NEXT: [[B:%.*]] = sext i8 %A to i64 -; CHECK-NEXT: [[C:%.*]] = and i64 [[B]], 4294967253 -; CHECK-NEXT: [[E:%.*]] = or i64 [[C]], 42 +; CHECK-NEXT: [[TMP1:%.*]] = or i8 [[A:%.*]], 42 +; CHECK-NEXT: [[C:%.*]] = sext i8 [[TMP1]] to i64 +; CHECK-NEXT: [[E:%.*]] = and i64 [[C]], 4294967295 ; CHECK-NEXT: ret i64 [[E]] ; %B = sext i8 %A to i32 diff --git a/llvm/test/Transforms/InstCombine/logical-select.ll b/llvm/test/Transforms/InstCombine/logical-select.ll index 4c0223a..44f23ed 100644 --- a/llvm/test/Transforms/InstCombine/logical-select.ll +++ b/llvm/test/Transforms/InstCombine/logical-select.ll @@ -504,11 +504,11 @@ define <4 x i32> @vec_sel_xor(<4 x i32> %a, <4 x i32> %b, <4 x i1> %c) { define <4 x i32> @vec_sel_xor_multi_use(<4 x i32> %a, <4 x i32> %b, <4 x i1> %c) { ; CHECK-LABEL: @vec_sel_xor_multi_use( -; CHECK-NEXT: [[MASK:%.*]] = sext <4 x i1> %c to <4 x i32> -; CHECK-NEXT: [[MASK_FLIP1:%.*]] = xor <4 x i32> [[MASK]], -; CHECK-NEXT: [[TMP1:%.*]] = xor <4 x i1> %c, -; CHECK-NEXT: [[TMP2:%.*]] = select <4 x i1> [[TMP1]], <4 x i32> %a, <4 x i32> %b -; CHECK-NEXT: [[ADD:%.*]] = add <4 x i32> [[TMP2]], [[MASK_FLIP1]] +; CHECK-NEXT: [[TMP1:%.*]] = xor <4 x i1> [[C:%.*]], +; CHECK-NEXT: [[MASK_FLIP1:%.*]] = sext <4 x i1> [[TMP1]] to <4 x i32> +; CHECK-NEXT: [[TMP2:%.*]] = xor <4 x i1> [[C]], +; CHECK-NEXT: [[TMP3:%.*]] = select <4 x i1> [[TMP2]], <4 x i32> [[A:%.*]], <4 x i32> [[B:%.*]] +; CHECK-NEXT: [[ADD:%.*]] = add <4 x i32> [[TMP3]], [[MASK_FLIP1]] ; CHECK-NEXT: ret <4 x i32> [[ADD]] ; %mask = sext <4 x i1> %c to <4 x i32> diff --git a/llvm/test/Transforms/SLPVectorizer/X86/minimum-sizes.ll b/llvm/test/Transforms/SLPVectorizer/X86/minimum-sizes.ll index 00af8ff..723108f 100644 --- a/llvm/test/Transforms/SLPVectorizer/X86/minimum-sizes.ll +++ b/llvm/test/Transforms/SLPVectorizer/X86/minimum-sizes.ll @@ -48,12 +48,12 @@ entry: ; optimization, we make the proposed smaller type (i8) larger (i16) to ; ensure correctness. ; -; CHECK: %[[S0:.+]] = sext <2 x i8> {{.*}} to <2 x i16> -; CHECK: %[[OR:.+]] = or <2 x i16> %[[S0]], -; CHECK: %[[E0:.+]] = extractelement <2 x i16> %[[OR]], i32 0 +; CHECK: %[[OR:.+]] = or <2 x i8> {{.*}}, +; CHECK: %[[S0:.+]] = sext <2 x i8> %[[OR]] to <2 x i16> +; CHECK: %[[E0:.+]] = extractelement <2 x i16> %[[S0]], i32 0 ; CHECK: %[[S1:.+]] = sext i16 %[[E0]] to i64 ; CHECK: getelementptr inbounds i8, i8* %ptr, i64 %[[S1]] -; CHECK: %[[E1:.+]] = extractelement <2 x i16> %[[OR]], i32 1 +; CHECK: %[[E1:.+]] = extractelement <2 x i16> %[[S0]], i32 1 ; CHECK: %[[S2:.+]] = sext i16 %[[E1]] to i64 ; CHECK: getelementptr inbounds i8, i8* %ptr, i64 %[[S2]] ;