From: Sanjay Patel Date: Mon, 16 Jan 2017 19:35:45 +0000 (+0000) Subject: [InstCombine] use m_APInt to allow shift-shift folds for vectors with splat constants X-Git-Url: https://granicus.if.org/sourcecode?a=commitdiff_plain;h=2222ec4bc9483199b639f8f7693391d632ac62ed;p=llvm [InstCombine] use m_APInt to allow shift-shift folds for vectors with splat constants Some existing 'FIXME' tests are still not folded because of splat holes in value tracking. git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@292151 91177308-0d34-0410-b5e6-96231b3b80d8 --- diff --git a/lib/Transforms/InstCombine/InstCombineShifts.cpp b/lib/Transforms/InstCombine/InstCombineShifts.cpp index 8ccbd5cf33d..2a42fe7af61 100644 --- a/lib/Transforms/InstCombine/InstCombineShifts.cpp +++ b/lib/Transforms/InstCombine/InstCombineShifts.cpp @@ -72,9 +72,9 @@ static bool canEvaluateShiftedShift(unsigned FirstShiftAmt, Instruction *CxtI) { assert(SecondShift->isLogicalShift() && "Unexpected instruction type"); - // We need constant shifts. - auto *SecondShiftConst = dyn_cast(SecondShift->getOperand(1)); - if (!SecondShiftConst) + // We need constant scalar or constant splat shifts. + const APInt *SecondShiftConst; + if (!match(SecondShift->getOperand(1), m_APInt(SecondShiftConst))) return false; unsigned SecondShiftAmt = SecondShiftConst->getZExtValue(); @@ -200,7 +200,8 @@ static Value *foldShiftedShift(BinaryOperator *InnerShift, unsigned OuterShAmt, unsigned TypeWidth = ShType->getScalarSizeInBits(); // We only accept shifts-by-a-constant in canEvaluateShifted(). - ConstantInt *C1 = cast(InnerShift->getOperand(1)); + const APInt *C1; + match(InnerShift->getOperand(1), m_APInt(C1)); unsigned InnerShAmt = C1->getZExtValue(); // Change the shift amount and clear the appropriate IR flags. diff --git a/test/Transforms/InstCombine/apint-shift.ll b/test/Transforms/InstCombine/apint-shift.ll index a46123529b4..699a543349f 100644 --- a/test/Transforms/InstCombine/apint-shift.ll +++ b/test/Transforms/InstCombine/apint-shift.ll @@ -113,71 +113,66 @@ define i19 @test10(i19 %X) { ret i19 %sh2 } -; FIXME: Two right shifts in the same direction: +; Two right shifts in the same direction: ; lshr (lshr X, C1), C2 --> lshr X, C1 + C2 define <2 x i19> @lshr_lshr_splat_vec(<2 x i19> %X) { ; CHECK-LABEL: @lshr_lshr_splat_vec( -; CHECK-NEXT: [[SH1:%.*]] = lshr <2 x i19> %X, -; CHECK-NEXT: [[SH2:%.*]] = lshr <2 x i19> [[SH1]], -; CHECK-NEXT: ret <2 x i19> [[SH2]] +; CHECK-NEXT: [[SH1:%.*]] = lshr <2 x i19> %X, +; CHECK-NEXT: ret <2 x i19> [[SH1]] ; %sh1 = lshr <2 x i19> %X, %sh2 = lshr <2 x i19> %sh1, ret <2 x i19> %sh2 } -; FIXME: Two left shifts in the same direction: +; Two left shifts in the same direction: ; shl (shl X, C1), C2 --> shl X, C1 + C2 define <2 x i19> @shl_shl_splat_vec(<2 x i19> %X) { ; CHECK-LABEL: @shl_shl_splat_vec( -; CHECK-NEXT: [[SH1:%.*]] = shl <2 x i19> %X, -; CHECK-NEXT: [[SH2:%.*]] = shl <2 x i19> [[SH1]], -; CHECK-NEXT: ret <2 x i19> [[SH2]] +; CHECK-NEXT: [[SH1:%.*]] = shl <2 x i19> %X, +; CHECK-NEXT: ret <2 x i19> [[SH1]] ; %sh1 = shl <2 x i19> %X, %sh2 = shl <2 x i19> %sh1, ret <2 x i19> %sh2 } -; FIXME: Equal shift amounts in opposite directions become bitwise 'and': +; Equal shift amounts in opposite directions become bitwise 'and': ; lshr (shl X, C), C --> and X, C' define <2 x i19> @eq_shl_lshr_splat_vec(<2 x i19> %X) { ; CHECK-LABEL: @eq_shl_lshr_splat_vec( -; CHECK-NEXT: [[SH1:%.*]] = shl <2 x i19> %X, -; CHECK-NEXT: [[SH2:%.*]] = lshr exact <2 x i19> [[SH1]], -; CHECK-NEXT: ret <2 x i19> [[SH2]] +; CHECK-NEXT: [[SH1:%.*]] = and <2 x i19> %X, +; CHECK-NEXT: ret <2 x i19> [[SH1]] ; %sh1 = shl <2 x i19> %X, %sh2 = lshr <2 x i19> %sh1, ret <2 x i19> %sh2 } -; FIXME: Equal shift amounts in opposite directions become bitwise 'and': +; Equal shift amounts in opposite directions become bitwise 'and': ; shl (lshr X, C), C --> and X, C' define <2 x i19> @eq_lshr_shl_splat_vec(<2 x i19> %X) { ; CHECK-LABEL: @eq_lshr_shl_splat_vec( -; CHECK-NEXT: [[SH1:%.*]] = lshr <2 x i19> %X, -; CHECK-NEXT: [[SH2:%.*]] = shl nuw <2 x i19> [[SH1]], -; CHECK-NEXT: ret <2 x i19> [[SH2]] +; CHECK-NEXT: [[SH1:%.*]] = and <2 x i19> %X, +; CHECK-NEXT: ret <2 x i19> [[SH1]] ; %sh1 = lshr <2 x i19> %X, %sh2 = shl <2 x i19> %sh1, ret <2 x i19> %sh2 } -; FIXME: In general, we would need an 'and' for this transform, but the masked-off bits are known zero. +; In general, we would need an 'and' for this transform, but the masked-off bits are known zero. ; shl (lshr X, C1), C2 --> lshr X, C1 - C2 define <2 x i7> @lshr_shl_splat_vec(<2 x i7> %X) { ; CHECK-LABEL: @lshr_shl_splat_vec( ; CHECK-NEXT: [[MUL:%.*]] = mul <2 x i7> %X, -; CHECK-NEXT: [[SH1:%.*]] = lshr exact <2 x i7> [[MUL]], -; CHECK-NEXT: [[SH2:%.*]] = shl nuw nsw <2 x i7> [[SH1]], -; CHECK-NEXT: ret <2 x i7> [[SH2]] +; CHECK-NEXT: [[SH1:%.*]] = lshr exact <2 x i7> [[MUL]], +; CHECK-NEXT: ret <2 x i7> [[SH1]] ; %mul = mul <2 x i7> %X, %sh1 = lshr exact <2 x i7> %mul, @@ -185,15 +180,14 @@ define <2 x i7> @lshr_shl_splat_vec(<2 x i7> %X) { ret <2 x i7> %sh2 } -; FIXME: In general, we would need an 'and' for this transform, but the masked-off bits are known zero. +; In general, we would need an 'and' for this transform, but the masked-off bits are known zero. ; lshr (shl X, C1), C2 --> shl X, C1 - C2 define <2 x i7> @shl_lshr_splat_vec(<2 x i7> %X) { ; CHECK-LABEL: @shl_lshr_splat_vec( ; CHECK-NEXT: [[DIV:%.*]] = udiv <2 x i7> %X, -; CHECK-NEXT: [[SH1:%.*]] = shl nuw <2 x i7> [[DIV]], -; CHECK-NEXT: [[SH2:%.*]] = lshr exact <2 x i7> [[SH1]], -; CHECK-NEXT: ret <2 x i7> [[SH2]] +; CHECK-NEXT: [[SH1:%.*]] = shl nuw nsw <2 x i7> [[DIV]], +; CHECK-NEXT: ret <2 x i7> [[SH1]] ; %div = udiv <2 x i7> %X, %sh1 = shl nuw <2 x i7> %div, diff --git a/test/Transforms/InstCombine/shift.ll b/test/Transforms/InstCombine/shift.ll index 55517e350a1..70f9e74c3bb 100644 --- a/test/Transforms/InstCombine/shift.ll +++ b/test/Transforms/InstCombine/shift.ll @@ -453,9 +453,8 @@ define i32 @test25(i32 %tmp.2, i32 %AA) { define <2 x i32> @test25_vector(<2 x i32> %tmp.2, <2 x i32> %AA) { ; CHECK-LABEL: @test25_vector( -; CHECK-NEXT: [[TMP_3:%.*]] = lshr <2 x i32> %tmp.2, -; CHECK-NEXT: [[TMP_51:%.*]] = shl nuw <2 x i32> [[TMP_3]], -; CHECK-NEXT: [[X2:%.*]] = add <2 x i32> [[TMP_51]], %AA +; CHECK-NEXT: [[TMP_3:%.*]] = and <2 x i32> %tmp.2, +; CHECK-NEXT: [[X2:%.*]] = add <2 x i32> [[TMP_3]], %AA ; CHECK-NEXT: [[TMP_6:%.*]] = and <2 x i32> [[X2]], ; CHECK-NEXT: ret <2 x i32> [[TMP_6]] ;