Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
56 changes: 24 additions & 32 deletions llvm/lib/Analysis/ConstantFolding.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -2177,16 +2177,13 @@ Constant *constantFoldVectorReduce(Intrinsic::ID IID, Constant *Op) {
return PoisonValue::get(VT->getElementType());

// TODO: Handle undef.
if (!isa<ConstantVector>(Op) && !isa<ConstantDataVector>(Op))
return nullptr;

auto *EltC = dyn_cast<ConstantInt>(Op->getAggregateElement(0U));
auto *EltC = dyn_cast_or_null<ConstantInt>(Op->getAggregateElement(0U));
if (!EltC)
return nullptr;

APInt Acc = EltC->getValue();
for (unsigned I = 1, E = VT->getNumElements(); I != E; I++) {
if (!(EltC = dyn_cast<ConstantInt>(Op->getAggregateElement(I))))
if (!(EltC = dyn_cast_or_null<ConstantInt>(Op->getAggregateElement(I))))
return nullptr;
const APInt &X = EltC->getValue();
switch (IID) {
Expand Down Expand Up @@ -3059,35 +3056,25 @@ static Constant *ConstantFoldScalarCall1(StringRef Name,
Val = Val | Val << 1;
return ConstantInt::get(Ty, Val);
}

default:
return nullptr;
}
}

switch (IntrinsicID) {
default: break;
case Intrinsic::vector_reduce_add:
case Intrinsic::vector_reduce_mul:
case Intrinsic::vector_reduce_and:
case Intrinsic::vector_reduce_or:
case Intrinsic::vector_reduce_xor:
case Intrinsic::vector_reduce_smin:
case Intrinsic::vector_reduce_smax:
case Intrinsic::vector_reduce_umin:
case Intrinsic::vector_reduce_umax:
if (Constant *C = constantFoldVectorReduce(IntrinsicID, Operands[0]))
return C;
break;
}

// Support ConstantVector in case we have an Undef in the top.
if (isa<ConstantVector>(Operands[0]) ||
isa<ConstantDataVector>(Operands[0]) ||
isa<ConstantAggregateZero>(Operands[0])) {
if (Operands[0]->getType()->isVectorTy()) {
auto *Op = cast<Constant>(Operands[0]);
switch (IntrinsicID) {
default: break;
case Intrinsic::vector_reduce_add:
case Intrinsic::vector_reduce_mul:
case Intrinsic::vector_reduce_and:
case Intrinsic::vector_reduce_or:
case Intrinsic::vector_reduce_xor:
case Intrinsic::vector_reduce_smin:
case Intrinsic::vector_reduce_smax:
case Intrinsic::vector_reduce_umin:
case Intrinsic::vector_reduce_umax:
if (Constant *C = constantFoldVectorReduce(IntrinsicID, Operands[0]))
return C;
break;
case Intrinsic::x86_sse_cvtss2si:
case Intrinsic::x86_sse_cvtss2si64:
case Intrinsic::x86_sse2_cvtsd2si:
Expand Down Expand Up @@ -3116,10 +3103,15 @@ static Constant *ConstantFoldScalarCall1(StringRef Name,
case Intrinsic::wasm_alltrue:
// Check each element individually
unsigned E = cast<FixedVectorType>(Op->getType())->getNumElements();
for (unsigned I = 0; I != E; ++I)
if (Constant *Elt = Op->getAggregateElement(I))
if (Elt->isZeroValue())
return ConstantInt::get(Ty, 0);
for (unsigned I = 0; I != E; ++I) {
Constant *Elt = Op->getAggregateElement(I);
// Return false as soon as we find a non-true element.
if (Elt && Elt->isZeroValue())
return ConstantInt::get(Ty, 0);
// Bail as soon as we find an element we cannot prove to be true.
if (!Elt || !isa<ConstantInt>(Elt))
return nullptr;
}

return ConstantInt::get(Ty, 1);
}
Expand Down
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
; NOTE: Assertions have been autogenerated by utils/update_test_checks.py UTC_ARGS: --version 5

; RUN: opt -passes=instsimplify -S < %s | FileCheck %s
; RUN: opt -passes=instsimplify -use-constant-int-for-fixed-length-splat -S < %s | FileCheck %s

; Test that intrinsics wasm call are constant folded

Expand Down
17 changes: 17 additions & 0 deletions llvm/test/Transforms/InstSimplify/ConstProp/bitcount.ll
Original file line number Diff line number Diff line change
@@ -1,5 +1,6 @@
; NOTE: Assertions have been autogenerated by utils/update_test_checks.py
; RUN: opt < %s -passes=instsimplify -S | FileCheck %s
; RUN: opt < %s -passes=instsimplify -use-constant-int-for-fixed-length-splat -use-constant-int-for-scalable-splat -S | FileCheck %s

declare i31 @llvm.ctpop.i31(i31 %val)
declare i32 @llvm.cttz.i32(i32 %val, i1)
Expand Down Expand Up @@ -120,6 +121,22 @@ define <2 x i31> @ctpop_vector() {
ret <2 x i31> %x
}

define <2 x i31> @ctpop_vector_splat_v2i31() {
; CHECK-LABEL: @ctpop_vector_splat_v2i31(
; CHECK-NEXT: ret <2 x i31> splat (i31 1)
;
%x = call <2 x i31> @llvm.ctpop.v2i31(<2 x i31> splat(i31 16))
ret <2 x i31> %x
}

define <vscale x 2 x i31> @ctpop_vector_splat_nxv2i31() {
; CHECK-LABEL: @ctpop_vector_splat_nxv2i31(
; CHECK-NEXT: ret <vscale x 2 x i31> splat (i31 1)
;
%x = call <vscale x 2 x i31> @llvm.ctpop.nxv2i31(<vscale x 2 x i31> splat(i31 16))
ret <vscale x 2 x i31> %x
}

define <2 x i31> @ctpop_vector_undef() {
; CHECK-LABEL: @ctpop_vector_undef(
; CHECK-NEXT: ret <2 x i31> zeroinitializer
Expand Down
51 changes: 51 additions & 0 deletions llvm/test/Transforms/InstSimplify/ConstProp/bitreverse.ll
Original file line number Diff line number Diff line change
@@ -0,0 +1,51 @@
; NOTE: Assertions have been autogenerated by utils/update_test_checks.py UTC_ARGS: --version 6
; RUN: opt < %s -passes=instsimplify -S | FileCheck %s
; RUN: opt < %s -passes=instsimplify -use-constant-int-for-fixed-length-splat -use-constant-int-for-scalable-splat -S | FileCheck %s

define i16 @W() {
; CHECK-LABEL: define i16 @W() {
; CHECK-NEXT: ret i16 -32768
;
%Z = call i16 @llvm.bitreverse.i16(i16 1)
ret i16 %Z
}

define i32 @X() {
; CHECK-LABEL: define i32 @X() {
; CHECK-NEXT: ret i32 -2147483648
;
%Z = call i32 @llvm.bitreverse.i32(i32 1)
ret i32 %Z
}

define i64 @Y() {
; CHECK-LABEL: define i64 @Y() {
; CHECK-NEXT: ret i64 -9223372036854775808
;
%Z = call i64 @llvm.bitreverse.i64(i64 1)
ret i64 %Z
}

define i80 @Z() {
; CHECK-LABEL: define i80 @Z() {
; CHECK-NEXT: ret i80 23777929115895377691656
;
%Z = call i80 @llvm.bitreverse.i80(i80 76151636403560493650080)
ret i80 %Z
}

define <4 x i32> @bitreverse_splat_v4i32() {
; CHECK-LABEL: define <4 x i32> @bitreverse_splat_v4i32() {
; CHECK-NEXT: ret <4 x i32> splat (i32 -2147483648)
;
%Z = call <4 x i32> @llvm.bitreverse.v4i32(<4 x i32> splat(i32 1))
ret <4 x i32> %Z
}

define <vscale x 4 x i32> @bitreverse_splat_nxv4i32() {
; CHECK-LABEL: define <vscale x 4 x i32> @bitreverse_splat_nxv4i32() {
; CHECK-NEXT: ret <vscale x 4 x i32> splat (i32 -2147483648)
;
%Z = call <vscale x 4 x i32> @llvm.bitreverse.v4i32(<vscale x 4 x i32> splat(i32 1))
ret <vscale x 4 x i32> %Z
}
17 changes: 17 additions & 0 deletions llvm/test/Transforms/InstSimplify/ConstProp/bswap.ll
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,7 @@
; bswap should be constant folded when it is passed a constant argument

; RUN: opt < %s -passes=instsimplify -S | FileCheck %s
; RUN: opt < %s -passes=instsimplify -use-constant-int-for-fixed-length-splat -use-constant-int-for-scalable-splat -S | FileCheck %s

declare i16 @llvm.bswap.i16(i16)

Expand Down Expand Up @@ -42,3 +43,19 @@ define i80 @Z() {
%Z = call i80 @llvm.bswap.i80( i80 76151636403560493650080 )
ret i80 %Z
}

define <4 x i32> @bswap_splat_v4i32() {
; CHECK-LABEL: define <4 x i32> @bswap_splat_v4i32() {
; CHECK-NEXT: ret <4 x i32> splat (i32 16777216)
;
%Z = call <4 x i32> @llvm.bswap.v4i32(<4 x i32> splat(i32 1))
ret <4 x i32> %Z
}

define <vscale x 4 x i32> @bswap_splat_nxv4i32() {
; CHECK-LABEL: define <vscale x 4 x i32> @bswap_splat_nxv4i32() {
; CHECK-NEXT: ret <vscale x 4 x i32> splat (i32 16777216)
;
%Z = call <vscale x 4 x i32> @llvm.bswap.v4i32(<vscale x 4 x i32> splat(i32 1))
ret <vscale x 4 x i32> %Z
}
1 change: 1 addition & 0 deletions llvm/test/Transforms/InstSimplify/ConstProp/vecreduce.ll
Original file line number Diff line number Diff line change
@@ -1,5 +1,6 @@
; NOTE: Assertions have been autogenerated by utils/update_test_checks.py
; RUN: opt < %s -passes=instsimplify -S | FileCheck %s
; RUN: opt < %s -passes=instsimplify -use-constant-int-for-fixed-length-splat -S | FileCheck %s

declare i32 @llvm.vector.reduce.add.v1i32(<1 x i32> %a)
declare i32 @llvm.vector.reduce.add.v8i32(<8 x i32> %a)
Expand Down