mirror of
https://github.com/RPCS3/llvm-mirror.git
synced 2024-10-19 11:02:59 +02:00
[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
This commit is contained in:
parent
7450d33b3c
commit
be15a9a346
@ -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
|
||||
|
@ -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]]
|
||||
;
|
||||
|
@ -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>
|
||||
|
@ -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]]
|
||||
;
|
||||
|
Loading…
Reference in New Issue
Block a user