diff options
author | Sanjay Patel <spatel@rotateright.com> | 2016-05-22 15:41:53 +0000 |
---|---|---|
committer | Sanjay Patel <spatel@rotateright.com> | 2016-05-22 15:41:53 +0000 |
commit | e2e89ef93604fefb1a145d26e12f43da7a5f24d2 (patch) | |
tree | 6a066966e9d915b590c26985b6c8c689851d175c | |
parent | 4f3fe5b1a6c0bc555d39d4847a9573c1060e045a (diff) | |
download | bcm5719-llvm-e2e89ef93604fefb1a145d26e12f43da7a5f24d2.tar.gz bcm5719-llvm-e2e89ef93604fefb1a145d26e12f43da7a5f24d2.zip |
[ValueTracking, InstCombine] extend isKnownToBeAPowerOfTwo() to handle vector splat constants
We could try harder to handle non-splat vector constants too,
but that seems much rarer to me.
Note that the div test isn't resolved because there's a check
for isIntegerTy() guarding that transform.
Differential Revision: http://reviews.llvm.org/D20497
llvm-svn: 270369
-rw-r--r-- | llvm/lib/Analysis/ValueTracking.cpp | 7 | ||||
-rw-r--r-- | llvm/test/Transforms/InstCombine/div.ll | 2 | ||||
-rw-r--r-- | llvm/test/Transforms/InstCombine/rem.ll | 8 | ||||
-rw-r--r-- | llvm/test/Transforms/InstCombine/shift.ll | 4 |
4 files changed, 8 insertions, 13 deletions
diff --git a/llvm/lib/Analysis/ValueTracking.cpp b/llvm/lib/Analysis/ValueTracking.cpp index 19fef59e1f3..38853478c06 100644 --- a/llvm/lib/Analysis/ValueTracking.cpp +++ b/llvm/lib/Analysis/ValueTracking.cpp @@ -1500,9 +1500,10 @@ bool isKnownToBeAPowerOfTwo(Value *V, bool OrZero, unsigned Depth, if (Constant *C = dyn_cast<Constant>(V)) { if (C->isNullValue()) return OrZero; - if (ConstantInt *CI = dyn_cast<ConstantInt>(C)) - return CI->getValue().isPowerOf2(); - // TODO: Handle vector constants. + + const APInt *ConstIntOrConstSplatInt; + if (match(C, m_APInt(ConstIntOrConstSplatInt))) + return ConstIntOrConstSplatInt->isPowerOf2(); } // 1 << X is clearly a power of two if the one is not shifted off the end. If diff --git a/llvm/test/Transforms/InstCombine/div.ll b/llvm/test/Transforms/InstCombine/div.ll index e4fd3324777..2b7c907f177 100644 --- a/llvm/test/Transforms/InstCombine/div.ll +++ b/llvm/test/Transforms/InstCombine/div.ll @@ -374,7 +374,7 @@ define i32 @test36(i32 %A) { define <2 x i32> @test36vec(<2 x i32> %A) { ; CHECK-LABEL: @test36vec( ; CHECK-NEXT: [[AND:%.*]] = and <2 x i32> %A, <i32 2147483647, i32 2147483647> -; CHECK-NEXT: [[SHL:%.*]] = shl nsw <2 x i32> <i32 1, i32 1>, %A +; CHECK-NEXT: [[SHL:%.*]] = shl nuw nsw <2 x i32> <i32 1, i32 1>, %A ; CHECK-NEXT: [[MUL:%.*]] = sdiv exact <2 x i32> [[AND]], [[SHL]] ; CHECK-NEXT: ret <2 x i32> [[MUL]] ; diff --git a/llvm/test/Transforms/InstCombine/rem.ll b/llvm/test/Transforms/InstCombine/rem.ll index 9f65228dee1..227344f16f2 100644 --- a/llvm/test/Transforms/InstCombine/rem.ll +++ b/llvm/test/Transforms/InstCombine/rem.ll @@ -25,22 +25,18 @@ define i32 @test3(i32 %A) { ret i32 %B } -; FIXME: This could be an 'and' just like above. - define <2 x i32> @vec_power_of_2_constant_splat_divisor(<2 x i32> %A) { ; CHECK-LABEL: @vec_power_of_2_constant_splat_divisor( -; CHECK-NEXT: [[B:%.*]] = urem <2 x i32> %A, <i32 8, i32 8> +; CHECK-NEXT: [[B:%.*]] = and <2 x i32> %A, <i32 7, i32 7> ; CHECK-NEXT: ret <2 x i32> [[B]] ; %B = urem <2 x i32> %A, <i32 8, i32 8> ret <2 x i32> %B } -; FIXME: And it shouldn't matter whether we have ConstantVector or ConstantDataVector. - define <2 x i19> @weird_vec_power_of_2_constant_splat_divisor(<2 x i19> %A) { ; CHECK-LABEL: @weird_vec_power_of_2_constant_splat_divisor( -; CHECK-NEXT: [[B:%.*]] = urem <2 x i19> %A, <i19 8, i19 8> +; CHECK-NEXT: [[B:%.*]] = and <2 x i19> %A, <i19 7, i19 7> ; CHECK-NEXT: ret <2 x i19> [[B]] ; %B = urem <2 x i19> %A, <i19 8, i19 8> diff --git a/llvm/test/Transforms/InstCombine/shift.ll b/llvm/test/Transforms/InstCombine/shift.ll index e4dd377952a..755c4a7f9f1 100644 --- a/llvm/test/Transforms/InstCombine/shift.ll +++ b/llvm/test/Transforms/InstCombine/shift.ll @@ -700,11 +700,9 @@ define i32 @test42(i32 %a, i32 %b) nounwind { ret i32 %div2 } -; FIXME: Vector lshr should be treated the same as scalar. - define <2 x i32> @test42vec(<2 x i32> %a, <2 x i32> %b) { ; CHECK-LABEL: @test42vec( -; CHECK-NEXT: [[DIV:%.*]] = lshr <2 x i32> <i32 4096, i32 4096>, %b +; CHECK-NEXT: [[DIV:%.*]] = lshr exact <2 x i32> <i32 4096, i32 4096>, %b ; CHECK-NEXT: [[DIV2:%.*]] = udiv <2 x i32> %a, [[DIV]] ; CHECK-NEXT: ret <2 x i32> [[DIV2]] ; |