[llvm] becaa68 - [ARM] Constant fold VCTP intrinsics
David Green via llvm-commits
llvm-commits at lists.llvm.org
Tue Jul 21 04:03:55 PDT 2020
Author: David Green
Date: 2020-07-21T11:39:31+01:00
New Revision: becaa6803ab532d15506829f0551a5fa49c39d7e
URL: https://github.com/llvm/llvm-project/commit/becaa6803ab532d15506829f0551a5fa49c39d7e
DIFF: https://github.com/llvm/llvm-project/commit/becaa6803ab532d15506829f0551a5fa49c39d7e.diff
LOG: [ARM] Constant fold VCTP intrinsics
We can sometimes get into the situation where the operand to a vctp
intrinsic becomes constant, such as after a loop is fully unrolled. This
adds the constant folding needed for them, allowing them to simplify
away and hopefully simplifying remaining instructions.
Differential Revision: https://reviews.llvm.org/D84110
Added:
llvm/test/Analysis/ConstantFolding/ARM/lit.local.cfg
llvm/test/Analysis/ConstantFolding/ARM/mve-vctp.ll
Modified:
llvm/lib/Analysis/ConstantFolding.cpp
Removed:
################################################################################
diff --git a/llvm/lib/Analysis/ConstantFolding.cpp b/llvm/lib/Analysis/ConstantFolding.cpp
index 6feffcbb98e1..7c3e35be5074 100644
--- a/llvm/lib/Analysis/ConstantFolding.cpp
+++ b/llvm/lib/Analysis/ConstantFolding.cpp
@@ -41,6 +41,7 @@
#include "llvm/IR/IntrinsicInst.h"
#include "llvm/IR/Intrinsics.h"
#include "llvm/IR/IntrinsicsAMDGPU.h"
+#include "llvm/IR/IntrinsicsARM.h"
#include "llvm/IR/IntrinsicsX86.h"
#include "llvm/IR/Operator.h"
#include "llvm/IR/Type.h"
@@ -1456,6 +1457,11 @@ bool llvm::canConstantFoldCallTo(const CallBase *Call, const Function *F) {
case Intrinsic::experimental_vector_reduce_smax:
case Intrinsic::experimental_vector_reduce_umin:
case Intrinsic::experimental_vector_reduce_umax:
+ // Target intrinsics
+ case Intrinsic::arm_mve_vctp8:
+ case Intrinsic::arm_mve_vctp16:
+ case Intrinsic::arm_mve_vctp32:
+ case Intrinsic::arm_mve_vctp64:
return true;
// Floating point operations cannot be folded in strictfp functions in
@@ -2719,7 +2725,8 @@ static Constant *ConstantFoldVectorCall(StringRef Name,
SmallVector<Constant *, 4> Lane(Operands.size());
Type *Ty = FVTy->getElementType();
- if (IntrinsicID == Intrinsic::masked_load) {
+ switch (IntrinsicID) {
+ case Intrinsic::masked_load: {
auto *SrcPtr = Operands[0];
auto *Mask = Operands[2];
auto *Passthru = Operands[3];
@@ -2757,6 +2764,32 @@ static Constant *ConstantFoldVectorCall(StringRef Name,
return nullptr;
return ConstantVector::get(NewElements);
}
+ case Intrinsic::arm_mve_vctp8:
+ case Intrinsic::arm_mve_vctp16:
+ case Intrinsic::arm_mve_vctp32:
+ case Intrinsic::arm_mve_vctp64: {
+ if (auto *Op = dyn_cast<ConstantInt>(Operands[0])) {
+ unsigned Lanes = FVTy->getNumElements();
+ uint64_t Limit = Op->getZExtValue();
+ // vctp64 are currently modelled as returning a v4i1, not a v2i1. Make
+ // sure we get the limit right in that case and set all relevant lanes.
+ if (IntrinsicID == Intrinsic::arm_mve_vctp64)
+ Limit *= 2;
+
+ SmallVector<Constant *, 16> NCs;
+ for (unsigned i = 0; i < Lanes; i++) {
+ if (i < Limit)
+ NCs.push_back(ConstantInt::getTrue(Ty));
+ else
+ NCs.push_back(ConstantInt::getFalse(Ty));
+ }
+ return ConstantVector::get(NCs);
+ }
+ break;
+ }
+ default:
+ break;
+ }
for (unsigned I = 0, E = FVTy->getNumElements(); I != E; ++I) {
// Gather a column of constants.
diff --git a/llvm/test/Analysis/ConstantFolding/ARM/lit.local.cfg b/llvm/test/Analysis/ConstantFolding/ARM/lit.local.cfg
new file mode 100644
index 000000000000..236e1d344166
--- /dev/null
+++ b/llvm/test/Analysis/ConstantFolding/ARM/lit.local.cfg
@@ -0,0 +1,2 @@
+if not 'ARM' in config.root.targets:
+ config.unsupported = True
diff --git a/llvm/test/Analysis/ConstantFolding/ARM/mve-vctp.ll b/llvm/test/Analysis/ConstantFolding/ARM/mve-vctp.ll
new file mode 100644
index 000000000000..0651a489e35a
--- /dev/null
+++ b/llvm/test/Analysis/ConstantFolding/ARM/mve-vctp.ll
@@ -0,0 +1,267 @@
+; NOTE: Assertions have been autogenerated by utils/update_test_checks.py
+; RUN: opt -instsimplify -S -o - %s | FileCheck %s
+
+target datalayout = "e-m:e-p:32:32-Fi8-i64:64-v128:64:128-a:0:32-n32-S64"
+
+define <16 x i1> @vctp8_0() {
+; CHECK-LABEL: @vctp8_0(
+; CHECK-NEXT: entry:
+; CHECK-NEXT: ret <16 x i1> zeroinitializer
+;
+entry:
+ %int = call <16 x i1> @llvm.arm.mve.vctp8(i32 0)
+ ret <16 x i1> %int
+}
+
+define <16 x i1> @vctp8_1() {
+; CHECK-LABEL: @vctp8_1(
+; CHECK-NEXT: entry:
+; CHECK-NEXT: ret <16 x i1> <i1 true, i1 false, i1 false, i1 false, i1 false, i1 false, i1 false, i1 false, i1 false, i1 false, i1 false, i1 false, i1 false, i1 false, i1 false, i1 false>
+;
+entry:
+ %int = call <16 x i1> @llvm.arm.mve.vctp8(i32 1)
+ ret <16 x i1> %int
+}
+
+define <16 x i1> @vctp8_8() {
+; CHECK-LABEL: @vctp8_8(
+; CHECK-NEXT: entry:
+; CHECK-NEXT: ret <16 x i1> <i1 true, i1 true, i1 true, i1 true, i1 true, i1 true, i1 true, i1 true, i1 false, i1 false, i1 false, i1 false, i1 false, i1 false, i1 false, i1 false>
+;
+entry:
+ %int = call <16 x i1> @llvm.arm.mve.vctp8(i32 8)
+ ret <16 x i1> %int
+}
+
+define <16 x i1> @vctp8_15() {
+; CHECK-LABEL: @vctp8_15(
+; CHECK-NEXT: entry:
+; CHECK-NEXT: ret <16 x i1> <i1 true, i1 true, i1 true, i1 true, i1 true, i1 true, i1 true, i1 true, i1 true, i1 true, i1 true, i1 true, i1 true, i1 true, i1 true, i1 false>
+;
+entry:
+ %int = call <16 x i1> @llvm.arm.mve.vctp8(i32 15)
+ ret <16 x i1> %int
+}
+
+define <16 x i1> @vctp8_16() {
+; CHECK-LABEL: @vctp8_16(
+; CHECK-NEXT: entry:
+; CHECK-NEXT: ret <16 x i1> <i1 true, i1 true, i1 true, i1 true, i1 true, i1 true, i1 true, i1 true, i1 true, i1 true, i1 true, i1 true, i1 true, i1 true, i1 true, i1 true>
+;
+entry:
+ %int = call <16 x i1> @llvm.arm.mve.vctp8(i32 16)
+ ret <16 x i1> %int
+}
+
+define <16 x i1> @vctp8_100() {
+; CHECK-LABEL: @vctp8_100(
+; CHECK-NEXT: entry:
+; CHECK-NEXT: ret <16 x i1> <i1 true, i1 true, i1 true, i1 true, i1 true, i1 true, i1 true, i1 true, i1 true, i1 true, i1 true, i1 true, i1 true, i1 true, i1 true, i1 true>
+;
+entry:
+ %int = call <16 x i1> @llvm.arm.mve.vctp8(i32 100)
+ ret <16 x i1> %int
+}
+
+define <16 x i1> @vctp8_m1() {
+; CHECK-LABEL: @vctp8_m1(
+; CHECK-NEXT: entry:
+; CHECK-NEXT: ret <16 x i1> <i1 true, i1 true, i1 true, i1 true, i1 true, i1 true, i1 true, i1 true, i1 true, i1 true, i1 true, i1 true, i1 true, i1 true, i1 true, i1 true>
+;
+entry:
+ %int = call <16 x i1> @llvm.arm.mve.vctp8(i32 -1)
+ ret <16 x i1> %int
+}
+
+
+
+define <8 x i1> @vctp16_0() {
+; CHECK-LABEL: @vctp16_0(
+; CHECK-NEXT: entry:
+; CHECK-NEXT: ret <8 x i1> zeroinitializer
+;
+entry:
+ %int = call <8 x i1> @llvm.arm.mve.vctp16(i32 0)
+ ret <8 x i1> %int
+}
+
+define <8 x i1> @vctp16_1() {
+; CHECK-LABEL: @vctp16_1(
+; CHECK-NEXT: entry:
+; CHECK-NEXT: ret <8 x i1> <i1 true, i1 false, i1 false, i1 false, i1 false, i1 false, i1 false, i1 false>
+;
+entry:
+ %int = call <8 x i1> @llvm.arm.mve.vctp16(i32 1)
+ ret <8 x i1> %int
+}
+
+define <8 x i1> @vctp16_4() {
+; CHECK-LABEL: @vctp16_4(
+; CHECK-NEXT: entry:
+; CHECK-NEXT: ret <8 x i1> <i1 true, i1 true, i1 true, i1 true, i1 false, i1 false, i1 false, i1 false>
+;
+entry:
+ %int = call <8 x i1> @llvm.arm.mve.vctp16(i32 4)
+ ret <8 x i1> %int
+}
+
+define <8 x i1> @vctp16_7() {
+; CHECK-LABEL: @vctp16_7(
+; CHECK-NEXT: entry:
+; CHECK-NEXT: ret <8 x i1> <i1 true, i1 true, i1 true, i1 true, i1 true, i1 true, i1 true, i1 false>
+;
+entry:
+ %int = call <8 x i1> @llvm.arm.mve.vctp16(i32 7)
+ ret <8 x i1> %int
+}
+
+define <8 x i1> @vctp16_8() {
+; CHECK-LABEL: @vctp16_8(
+; CHECK-NEXT: entry:
+; CHECK-NEXT: ret <8 x i1> <i1 true, i1 true, i1 true, i1 true, i1 true, i1 true, i1 true, i1 true>
+;
+entry:
+ %int = call <8 x i1> @llvm.arm.mve.vctp16(i32 8)
+ ret <8 x i1> %int
+}
+
+define <8 x i1> @vctp16_100() {
+; CHECK-LABEL: @vctp16_100(
+; CHECK-NEXT: entry:
+; CHECK-NEXT: ret <8 x i1> <i1 true, i1 true, i1 true, i1 true, i1 true, i1 true, i1 true, i1 true>
+;
+entry:
+ %int = call <8 x i1> @llvm.arm.mve.vctp16(i32 100)
+ ret <8 x i1> %int
+}
+
+define <8 x i1> @vctp16_m1() {
+; CHECK-LABEL: @vctp16_m1(
+; CHECK-NEXT: entry:
+; CHECK-NEXT: ret <8 x i1> <i1 true, i1 true, i1 true, i1 true, i1 true, i1 true, i1 true, i1 true>
+;
+entry:
+ %int = call <8 x i1> @llvm.arm.mve.vctp16(i32 -1)
+ ret <8 x i1> %int
+}
+
+
+
+define <4 x i1> @vctp32_0() {
+; CHECK-LABEL: @vctp32_0(
+; CHECK-NEXT: entry:
+; CHECK-NEXT: ret <4 x i1> zeroinitializer
+;
+entry:
+ %int = call <4 x i1> @llvm.arm.mve.vctp32(i32 0)
+ ret <4 x i1> %int
+}
+
+define <4 x i1> @vctp32_1() {
+; CHECK-LABEL: @vctp32_1(
+; CHECK-NEXT: entry:
+; CHECK-NEXT: ret <4 x i1> <i1 true, i1 false, i1 false, i1 false>
+;
+entry:
+ %int = call <4 x i1> @llvm.arm.mve.vctp32(i32 1)
+ ret <4 x i1> %int
+}
+
+define <4 x i1> @vctp32_3() {
+; CHECK-LABEL: @vctp32_3(
+; CHECK-NEXT: entry:
+; CHECK-NEXT: ret <4 x i1> <i1 true, i1 true, i1 true, i1 false>
+;
+entry:
+ %int = call <4 x i1> @llvm.arm.mve.vctp32(i32 3)
+ ret <4 x i1> %int
+}
+
+define <4 x i1> @vctp32_4() {
+; CHECK-LABEL: @vctp32_4(
+; CHECK-NEXT: entry:
+; CHECK-NEXT: ret <4 x i1> <i1 true, i1 true, i1 true, i1 true>
+;
+entry:
+ %int = call <4 x i1> @llvm.arm.mve.vctp32(i32 4)
+ ret <4 x i1> %int
+}
+
+define <4 x i1> @vctp32_100() {
+; CHECK-LABEL: @vctp32_100(
+; CHECK-NEXT: entry:
+; CHECK-NEXT: ret <4 x i1> <i1 true, i1 true, i1 true, i1 true>
+;
+entry:
+ %int = call <4 x i1> @llvm.arm.mve.vctp32(i32 100)
+ ret <4 x i1> %int
+}
+
+define <4 x i1> @vctp32_m1() {
+; CHECK-LABEL: @vctp32_m1(
+; CHECK-NEXT: entry:
+; CHECK-NEXT: ret <4 x i1> <i1 true, i1 true, i1 true, i1 true>
+;
+entry:
+ %int = call <4 x i1> @llvm.arm.mve.vctp32(i32 -1)
+ ret <4 x i1> %int
+}
+
+
+
+define <4 x i1> @vctp64_0() {
+; CHECK-LABEL: @vctp64_0(
+; CHECK-NEXT: entry:
+; CHECK-NEXT: ret <4 x i1> zeroinitializer
+;
+entry:
+ %int = call <4 x i1> @llvm.arm.mve.vctp64(i32 0)
+ ret <4 x i1> %int
+}
+
+define <4 x i1> @vctp64_1() {
+; CHECK-LABEL: @vctp64_1(
+; CHECK-NEXT: entry:
+; CHECK-NEXT: ret <4 x i1> <i1 true, i1 true, i1 false, i1 false>
+;
+entry:
+ %int = call <4 x i1> @llvm.arm.mve.vctp64(i32 1)
+ ret <4 x i1> %int
+}
+
+define <4 x i1> @vctp64_2() {
+; CHECK-LABEL: @vctp64_2(
+; CHECK-NEXT: entry:
+; CHECK-NEXT: ret <4 x i1> <i1 true, i1 true, i1 true, i1 true>
+;
+entry:
+ %int = call <4 x i1> @llvm.arm.mve.vctp64(i32 2)
+ ret <4 x i1> %int
+}
+
+define <4 x i1> @vctp64_100() {
+; CHECK-LABEL: @vctp64_100(
+; CHECK-NEXT: entry:
+; CHECK-NEXT: ret <4 x i1> <i1 true, i1 true, i1 true, i1 true>
+;
+entry:
+ %int = call <4 x i1> @llvm.arm.mve.vctp64(i32 100)
+ ret <4 x i1> %int
+}
+
+define <4 x i1> @vctp64_m1() {
+; CHECK-LABEL: @vctp64_m1(
+; CHECK-NEXT: entry:
+; CHECK-NEXT: ret <4 x i1> <i1 true, i1 true, i1 true, i1 true>
+;
+entry:
+ %int = call <4 x i1> @llvm.arm.mve.vctp64(i32 -1)
+ ret <4 x i1> %int
+}
+
+
+
+declare <4 x i1> @llvm.arm.mve.vctp64(i32)
+declare <4 x i1> @llvm.arm.mve.vctp32(i32)
+declare <8 x i1> @llvm.arm.mve.vctp16(i32)
+declare <16 x i1> @llvm.arm.mve.vctp8(i32)
More information about the llvm-commits
mailing list