From 65dd32afbc2aba6975a44fab7c8a4f4f05e104d7 Mon Sep 17 00:00:00 2001 From: Craig Topper Date: Sat, 5 Aug 2017 20:00:42 +0000 Subject: [PATCH] [InstCombine] Teach the code that pulls logical operators through constant shifts to handle vector splats too. llvm-svn: 310185 --- llvm/lib/Transforms/InstCombine/InstCombineShifts.cpp | 8 +++++--- llvm/test/Transforms/InstCombine/pr17827.ll | 6 ++---- .../Transforms/InstCombine/select-with-bitwise-ops.ll | 16 ++++++++-------- llvm/test/Transforms/InstCombine/vector-casts.ll | 4 ++-- 4 files changed, 17 insertions(+), 17 deletions(-) diff --git a/llvm/lib/Transforms/InstCombine/InstCombineShifts.cpp b/llvm/lib/Transforms/InstCombine/InstCombineShifts.cpp index 2b20d8e..5f21666 100644 --- a/llvm/lib/Transforms/InstCombine/InstCombineShifts.cpp +++ b/llvm/lib/Transforms/InstCombine/InstCombineShifts.cpp @@ -470,7 +470,8 @@ Instruction *InstCombiner::FoldShiftByConstant(Value *Op0, Constant *Op1, // If the operand is a bitwise operator with a constant RHS, and the // shift is the only use, we can pull it out of the shift. - if (ConstantInt *Op0C = dyn_cast(Op0BO->getOperand(1))) { + const APInt *Op0C; + if (match(Op0BO->getOperand(1), m_APInt(Op0C))) { bool isValid = true; // Valid only for And, Or, Xor bool highBitSet = false; // Transform if high bit of constant set? @@ -495,10 +496,11 @@ Instruction *InstCombiner::FoldShiftByConstant(Value *Op0, Constant *Op1, // operation. // if (isValid && I.getOpcode() == Instruction::AShr) - isValid = Op0C->getValue()[TypeBits-1] == highBitSet; + isValid = Op0C->isNegative() == highBitSet; if (isValid) { - Constant *NewRHS = ConstantExpr::get(I.getOpcode(), Op0C, Op1); + Constant *NewRHS = ConstantExpr::get(I.getOpcode(), + cast(Op0BO->getOperand(1)), Op1); Value *NewShift = Builder.CreateBinOp(I.getOpcode(), Op0BO->getOperand(0), Op1); diff --git a/llvm/test/Transforms/InstCombine/pr17827.ll b/llvm/test/Transforms/InstCombine/pr17827.ll index c9cbf76..e9312fc 100644 --- a/llvm/test/Transforms/InstCombine/pr17827.ll +++ b/llvm/test/Transforms/InstCombine/pr17827.ll @@ -47,12 +47,10 @@ define i1 @test_shift_and_cmp_changed1(i8 %p, i8 %q) { ret i1 %cmp } -; FIXME: Vectors should fold the same way. - define <2 x i1> @test_shift_and_cmp_changed1_vec(<2 x i8> %p, <2 x i8> %q) { ; CHECK-LABEL: @test_shift_and_cmp_changed1_vec( -; CHECK-NEXT: [[ANDP:%.*]] = and <2 x i8> %p, -; CHECK-NEXT: [[SHL:%.*]] = shl nuw <2 x i8> [[ANDP]], +; CHECK-NEXT: [[ANDP:%.*]] = shl <2 x i8> [[P:%.*]], +; CHECK-NEXT: [[SHL:%.*]] = and <2 x i8> [[ANDP]], ; CHECK-NEXT: [[CMP:%.*]] = icmp slt <2 x i8> [[SHL]], ; CHECK-NEXT: ret <2 x i1> [[CMP]] ; diff --git a/llvm/test/Transforms/InstCombine/select-with-bitwise-ops.ll b/llvm/test/Transforms/InstCombine/select-with-bitwise-ops.ll index 7580fad..24e5f257 100644 --- a/llvm/test/Transforms/InstCombine/select-with-bitwise-ops.ll +++ b/llvm/test/Transforms/InstCombine/select-with-bitwise-ops.ll @@ -270,9 +270,9 @@ define i32 @test65(i64 %x) { define <2 x i32> @test65vec(<2 x i64> %x) { ; CHECK-LABEL: @test65vec( -; CHECK-NEXT: [[TMP1:%.*]] = and <2 x i64> [[X:%.*]], -; CHECK-NEXT: [[TMP2:%.*]] = lshr exact <2 x i64> [[TMP1]], -; CHECK-NEXT: [[TMP3:%.*]] = trunc <2 x i64> [[TMP2]] to <2 x i32> +; CHECK-NEXT: [[TMP1:%.*]] = lshr <2 x i64> [[X:%.*]], +; CHECK-NEXT: [[TMP2:%.*]] = trunc <2 x i64> [[TMP1]] to <2 x i32> +; CHECK-NEXT: [[TMP3:%.*]] = and <2 x i32> [[TMP2]], ; CHECK-NEXT: [[TMP4:%.*]] = or <2 x i32> [[TMP3]], ; CHECK-NEXT: [[TMP5:%.*]] = xor <2 x i32> [[TMP4]], ; CHECK-NEXT: ret <2 x i32> [[TMP5]] @@ -299,9 +299,9 @@ define i32 @test66(i64 %x) { define <2 x i32> @test66vec(<2 x i64> %x) { ; CHECK-LABEL: @test66vec( -; CHECK-NEXT: [[TMP1:%.*]] = and <2 x i64> [[X:%.*]], -; CHECK-NEXT: [[TMP2:%.*]] = lshr exact <2 x i64> [[TMP1]], -; CHECK-NEXT: [[TMP3:%.*]] = trunc <2 x i64> [[TMP2]] to <2 x i32> +; CHECK-NEXT: [[TMP1:%.*]] = lshr <2 x i64> [[X:%.*]], +; CHECK-NEXT: [[TMP2:%.*]] = trunc <2 x i64> [[TMP1]] to <2 x i32> +; CHECK-NEXT: [[TMP3:%.*]] = and <2 x i32> [[TMP2]], ; CHECK-NEXT: [[TMP4:%.*]] = or <2 x i32> [[TMP3]], ; CHECK-NEXT: [[TMP5:%.*]] = xor <2 x i32> [[TMP4]], ; CHECK-NEXT: ret <2 x i32> [[TMP5]] @@ -342,8 +342,8 @@ define i32 @test67(i16 %x) { define <2 x i32> @test67vec(<2 x i16> %x) { ; CHECK-LABEL: @test67vec( -; CHECK-NEXT: [[TMP1:%.*]] = and <2 x i16> [[X:%.*]], -; CHECK-NEXT: [[TMP2:%.*]] = lshr exact <2 x i16> [[TMP1]], +; CHECK-NEXT: [[TMP1:%.*]] = lshr <2 x i16> [[X:%.*]], +; CHECK-NEXT: [[TMP2:%.*]] = and <2 x i16> [[TMP1]], ; CHECK-NEXT: [[TMP3:%.*]] = or <2 x i16> [[TMP2]], ; CHECK-NEXT: [[TMP4:%.*]] = xor <2 x i16> [[TMP3]], ; CHECK-NEXT: [[TMP5:%.*]] = zext <2 x i16> [[TMP4]] to <2 x i32> diff --git a/llvm/test/Transforms/InstCombine/vector-casts.ll b/llvm/test/Transforms/InstCombine/vector-casts.ll index 447f86f..4541b30 100644 --- a/llvm/test/Transforms/InstCombine/vector-casts.ll +++ b/llvm/test/Transforms/InstCombine/vector-casts.ll @@ -15,8 +15,8 @@ define <2 x i1> @test1(<2 x i64> %a) { ; The ashr turns into an lshr. define <2 x i64> @test2(<2 x i64> %a) { ; CHECK-LABEL: @test2( -; CHECK-NEXT: [[B:%.*]] = and <2 x i64> %a, -; CHECK-NEXT: [[TMP1:%.*]] = lshr exact <2 x i64> [[B]], +; CHECK-NEXT: [[B:%.*]] = lshr <2 x i64> [[A:%.*]], +; CHECK-NEXT: [[TMP1:%.*]] = and <2 x i64> [[B]], ; CHECK-NEXT: ret <2 x i64> [[TMP1]] ; %b = and <2 x i64> %a, -- 2.7.4