diff options
| author | Sanjay Patel <spatel@rotateright.com> | 2017-01-16 19:35:45 +0000 |
|---|---|---|
| committer | Sanjay Patel <spatel@rotateright.com> | 2017-01-16 19:35:45 +0000 |
| commit | ab8b32de7199703905f2d3a5f891bfa163bba2d0 (patch) | |
| tree | 72076d7752d17bf51a97b7b5580dac7fa2e2e05a /llvm | |
| parent | cd06f6fe10640ced55acecb128a5b8bff1830106 (diff) | |
| download | bcm5719-llvm-ab8b32de7199703905f2d3a5f891bfa163bba2d0.tar.gz bcm5719-llvm-ab8b32de7199703905f2d3a5f891bfa163bba2d0.zip | |
[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.
llvm-svn: 292151
Diffstat (limited to 'llvm')
| -rw-r--r-- | llvm/lib/Transforms/InstCombine/InstCombineShifts.cpp | 9 | ||||
| -rw-r--r-- | llvm/test/Transforms/InstCombine/apint-shift.ll | 42 | ||||
| -rw-r--r-- | llvm/test/Transforms/InstCombine/shift.ll | 5 |
3 files changed, 25 insertions, 31 deletions
diff --git a/llvm/lib/Transforms/InstCombine/InstCombineShifts.cpp b/llvm/lib/Transforms/InstCombine/InstCombineShifts.cpp index 8ccbd5cf33d..2a42fe7af61 100644 --- a/llvm/lib/Transforms/InstCombine/InstCombineShifts.cpp +++ b/llvm/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<ConstantInt>(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<ConstantInt>(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/llvm/test/Transforms/InstCombine/apint-shift.ll b/llvm/test/Transforms/InstCombine/apint-shift.ll index a46123529b4..699a543349f 100644 --- a/llvm/test/Transforms/InstCombine/apint-shift.ll +++ b/llvm/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, <i19 3, i19 3> -; CHECK-NEXT: [[SH2:%.*]] = lshr <2 x i19> [[SH1]], <i19 2, i19 2> -; CHECK-NEXT: ret <2 x i19> [[SH2]] +; CHECK-NEXT: [[SH1:%.*]] = lshr <2 x i19> %X, <i19 5, i19 5> +; CHECK-NEXT: ret <2 x i19> [[SH1]] ; %sh1 = lshr <2 x i19> %X, <i19 3, i19 3> %sh2 = lshr <2 x i19> %sh1, <i19 2, i19 2> 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, <i19 3, i19 3> -; CHECK-NEXT: [[SH2:%.*]] = shl <2 x i19> [[SH1]], <i19 2, i19 2> -; CHECK-NEXT: ret <2 x i19> [[SH2]] +; CHECK-NEXT: [[SH1:%.*]] = shl <2 x i19> %X, <i19 5, i19 5> +; CHECK-NEXT: ret <2 x i19> [[SH1]] ; %sh1 = shl <2 x i19> %X, <i19 3, i19 3> %sh2 = shl <2 x i19> %sh1, <i19 2, i19 2> 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, <i19 3, i19 3> -; CHECK-NEXT: [[SH2:%.*]] = lshr exact <2 x i19> [[SH1]], <i19 3, i19 3> -; CHECK-NEXT: ret <2 x i19> [[SH2]] +; CHECK-NEXT: [[SH1:%.*]] = and <2 x i19> %X, <i19 65535, i19 65535> +; CHECK-NEXT: ret <2 x i19> [[SH1]] ; %sh1 = shl <2 x i19> %X, <i19 3, i19 3> %sh2 = lshr <2 x i19> %sh1, <i19 3, i19 3> 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, <i19 3, i19 3> -; CHECK-NEXT: [[SH2:%.*]] = shl nuw <2 x i19> [[SH1]], <i19 3, i19 3> -; CHECK-NEXT: ret <2 x i19> [[SH2]] +; CHECK-NEXT: [[SH1:%.*]] = and <2 x i19> %X, <i19 -8, i19 -8> +; CHECK-NEXT: ret <2 x i19> [[SH1]] ; %sh1 = lshr <2 x i19> %X, <i19 3, i19 3> %sh2 = shl <2 x i19> %sh1, <i19 3, i19 3> 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, <i7 -8, i7 -8> -; CHECK-NEXT: [[SH1:%.*]] = lshr exact <2 x i7> [[MUL]], <i7 3, i7 3> -; CHECK-NEXT: [[SH2:%.*]] = shl nuw nsw <2 x i7> [[SH1]], <i7 2, i7 2> -; CHECK-NEXT: ret <2 x i7> [[SH2]] +; CHECK-NEXT: [[SH1:%.*]] = lshr exact <2 x i7> [[MUL]], <i7 1, i7 1> +; CHECK-NEXT: ret <2 x i7> [[SH1]] ; %mul = mul <2 x i7> %X, <i7 -8, i7 -8> %sh1 = lshr exact <2 x i7> %mul, <i7 3, i7 3> @@ -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, <i7 9, i7 9> -; CHECK-NEXT: [[SH1:%.*]] = shl nuw <2 x i7> [[DIV]], <i7 3, i7 3> -; CHECK-NEXT: [[SH2:%.*]] = lshr exact <2 x i7> [[SH1]], <i7 2, i7 2> -; CHECK-NEXT: ret <2 x i7> [[SH2]] +; CHECK-NEXT: [[SH1:%.*]] = shl nuw nsw <2 x i7> [[DIV]], <i7 1, i7 1> +; CHECK-NEXT: ret <2 x i7> [[SH1]] ; %div = udiv <2 x i7> %X, <i7 9, i7 9> %sh1 = shl nuw <2 x i7> %div, <i7 3, i7 3> diff --git a/llvm/test/Transforms/InstCombine/shift.ll b/llvm/test/Transforms/InstCombine/shift.ll index 55517e350a1..70f9e74c3bb 100644 --- a/llvm/test/Transforms/InstCombine/shift.ll +++ b/llvm/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, <i32 17, i32 17> -; CHECK-NEXT: [[TMP_51:%.*]] = shl nuw <2 x i32> [[TMP_3]], <i32 17, i32 17> -; CHECK-NEXT: [[X2:%.*]] = add <2 x i32> [[TMP_51]], %AA +; CHECK-NEXT: [[TMP_3:%.*]] = and <2 x i32> %tmp.2, <i32 -131072, i32 -131072> +; CHECK-NEXT: [[X2:%.*]] = add <2 x i32> [[TMP_3]], %AA ; CHECK-NEXT: [[TMP_6:%.*]] = and <2 x i32> [[X2]], <i32 -131072, i32 -131072> ; CHECK-NEXT: ret <2 x i32> [[TMP_6]] ; |

