[llvm] [InstCombine] Swap out range metadata to range attribute for arm_mve_pred_v2i (PR #94847)
Andreas Jonson via llvm-commits
llvm-commits at lists.llvm.org
Wed Jun 12 15:00:35 PDT 2024
https://github.com/andjo403 updated https://github.com/llvm/llvm-project/pull/94847
>From 18248f7ce2cc5b2fe7fed0570fa045d6ab4a261c Mon Sep 17 00:00:00 2001
From: Andreas Jonson <andjo403 at hotmail.com>
Date: Thu, 13 Jun 2024 00:00:10 +0200
Subject: [PATCH] [InstCombine] Swap out range and noundef metadata to
attribute for arm_mve_pred_v2i.
---
.../SelectionDAG/SelectionDAGBuilder.cpp | 23 ++++++---
.../lib/Target/ARM/ARMTargetTransformInfo.cpp | 24 +++++----
.../Transforms/InstCombine/ARM/mve-v2i2v.ll | 51 +++++++++++++++----
3 files changed, 72 insertions(+), 26 deletions(-)
diff --git a/llvm/lib/CodeGen/SelectionDAG/SelectionDAGBuilder.cpp b/llvm/lib/CodeGen/SelectionDAG/SelectionDAGBuilder.cpp
index be5e0f6ef058b..5d21a905c316c 100644
--- a/llvm/lib/CodeGen/SelectionDAG/SelectionDAGBuilder.cpp
+++ b/llvm/lib/CodeGen/SelectionDAG/SelectionDAGBuilder.cpp
@@ -4487,6 +4487,18 @@ static const MDNode *getRangeMetadata(const Instruction &I) {
return I.getMetadata(LLVMContext::MD_range);
}
+static std::optional<ConstantRange> getRange(const Instruction &I) {
+ if (const auto *CB = dyn_cast<CallBase>(&I)) {
+ // see comment in getRangeMetadata about this check
+ if (CB->hasRetAttr(Attribute::NoUndef))
+ return CB->getRange();
+ }
+ if (const MDNode *Range = getRangeMetadata(I)) {
+ return getConstantRangeFromMetadata(*Range);
+ }
+ return std::nullopt;
+}
+
void SelectionDAGBuilder::visitLoad(const LoadInst &I) {
if (I.isAtomic())
return visitAtomicLoad(I);
@@ -10229,19 +10241,16 @@ void SelectionDAGBuilder::visitVACopy(const CallInst &I) {
SDValue SelectionDAGBuilder::lowerRangeToAssertZExt(SelectionDAG &DAG,
const Instruction &I,
SDValue Op) {
- const MDNode *Range = getRangeMetadata(I);
- if (!Range)
- return Op;
+ std::optional<ConstantRange> CR = getRange(I);
- ConstantRange CR = getConstantRangeFromMetadata(*Range);
- if (CR.isFullSet() || CR.isEmptySet() || CR.isUpperWrapped())
+ if (!CR || CR->isFullSet() || CR->isEmptySet() || CR->isUpperWrapped())
return Op;
- APInt Lo = CR.getUnsignedMin();
+ APInt Lo = CR->getUnsignedMin();
if (!Lo.isMinValue())
return Op;
- APInt Hi = CR.getUnsignedMax();
+ APInt Hi = CR->getUnsignedMax();
unsigned Bits = std::max(Hi.getActiveBits(),
static_cast<unsigned>(IntegerType::MIN_INT_BITS));
diff --git a/llvm/lib/Target/ARM/ARMTargetTransformInfo.cpp b/llvm/lib/Target/ARM/ARMTargetTransformInfo.cpp
index 7db2e8ee7e6f9..4dc4d28724ef9 100644
--- a/llvm/lib/Target/ARM/ARMTargetTransformInfo.cpp
+++ b/llvm/lib/Target/ARM/ARMTargetTransformInfo.cpp
@@ -199,17 +199,21 @@ ARMTTIImpl::instCombineIntrinsic(InstCombiner &IC, IntrinsicInst &II) const {
PatternMatch::m_Value(ArgArg)))) {
return IC.replaceInstUsesWith(II, ArgArg);
}
- if (!II.getMetadata(LLVMContext::MD_range)) {
- Type *IntTy32 = Type::getInt32Ty(II.getContext());
- Metadata *M[] = {
- ConstantAsMetadata::get(ConstantInt::get(IntTy32, 0)),
- ConstantAsMetadata::get(ConstantInt::get(IntTy32, 0x10000))};
- II.setMetadata(LLVMContext::MD_range, MDNode::get(II.getContext(), M));
- II.setMetadata(LLVMContext::MD_noundef,
- MDNode::get(II.getContext(), std::nullopt));
- return &II;
+
+ if (II.getMetadata(LLVMContext::MD_range))
+ break;
+
+ ConstantRange Range(APInt(32, 0), APInt(32, 0x10000));
+
+ if (auto CurrentRange = II.getRange()) {
+ Range = Range.intersectWith(*CurrentRange);
+ if (Range == CurrentRange)
+ break;
}
- break;
+
+ II.addRangeRetAttr(Range);
+ II.addRetAttr(Attribute::NoUndef);
+ return &II;
}
case Intrinsic::arm_mve_vadc:
case Intrinsic::arm_mve_vadc_predicated: {
diff --git a/llvm/test/Transforms/InstCombine/ARM/mve-v2i2v.ll b/llvm/test/Transforms/InstCombine/ARM/mve-v2i2v.ll
index d0d17efd23050..d5fc6d34abca9 100644
--- a/llvm/test/Transforms/InstCombine/ARM/mve-v2i2v.ll
+++ b/llvm/test/Transforms/InstCombine/ARM/mve-v2i2v.ll
@@ -66,7 +66,7 @@ entry:
define <16 x i1> @v2i2v_2_16(<2 x i1> %vin) {
; CHECK-LABEL: @v2i2v_2_16(
; CHECK-NEXT: entry:
-; CHECK-NEXT: [[INT:%.*]] = call i32 @llvm.arm.mve.pred.v2i.v2i1(<2 x i1> [[VIN:%.*]]), !range [[RNG0:![0-9]+]]
+; CHECK-NEXT: [[INT:%.*]] = call noundef range(i32 0, 65536) i32 @llvm.arm.mve.pred.v2i.v2i1(<2 x i1> [[VIN:%.*]])
; CHECK-NEXT: [[VOUT:%.*]] = call <16 x i1> @llvm.arm.mve.pred.i2v.v16i1(i32 [[INT]])
; CHECK-NEXT: ret <16 x i1> [[VOUT]]
;
@@ -79,7 +79,7 @@ entry:
define <16 x i1> @v2i2v_4_16(<4 x i1> %vin) {
; CHECK-LABEL: @v2i2v_4_16(
; CHECK-NEXT: entry:
-; CHECK-NEXT: [[INT:%.*]] = call i32 @llvm.arm.mve.pred.v2i.v4i1(<4 x i1> [[VIN:%.*]]), !range [[RNG0]]
+; CHECK-NEXT: [[INT:%.*]] = call noundef range(i32 0, 65536) i32 @llvm.arm.mve.pred.v2i.v4i1(<4 x i1> [[VIN:%.*]])
; CHECK-NEXT: [[VOUT:%.*]] = call <16 x i1> @llvm.arm.mve.pred.i2v.v16i1(i32 [[INT]])
; CHECK-NEXT: ret <16 x i1> [[VOUT]]
;
@@ -92,7 +92,7 @@ entry:
define <4 x i1> @v2i2v_8_4(<8 x i1> %vin) {
; CHECK-LABEL: @v2i2v_8_4(
; CHECK-NEXT: entry:
-; CHECK-NEXT: [[INT:%.*]] = call i32 @llvm.arm.mve.pred.v2i.v8i1(<8 x i1> [[VIN:%.*]]), !range [[RNG0]]
+; CHECK-NEXT: [[INT:%.*]] = call noundef range(i32 0, 65536) i32 @llvm.arm.mve.pred.v2i.v8i1(<8 x i1> [[VIN:%.*]])
; CHECK-NEXT: [[VOUT:%.*]] = call <4 x i1> @llvm.arm.mve.pred.i2v.v4i1(i32 [[INT]])
; CHECK-NEXT: ret <4 x i1> [[VOUT]]
;
@@ -105,7 +105,7 @@ entry:
define <8 x i1> @v2i2v_16_8(<16 x i1> %vin) {
; CHECK-LABEL: @v2i2v_16_8(
; CHECK-NEXT: entry:
-; CHECK-NEXT: [[INT:%.*]] = call i32 @llvm.arm.mve.pred.v2i.v16i1(<16 x i1> [[VIN:%.*]]), !range [[RNG0]]
+; CHECK-NEXT: [[INT:%.*]] = call noundef range(i32 0, 65536) i32 @llvm.arm.mve.pred.v2i.v16i1(<16 x i1> [[VIN:%.*]])
; CHECK-NEXT: [[VOUT:%.*]] = call <8 x i1> @llvm.arm.mve.pred.i2v.v8i1(i32 [[INT]])
; CHECK-NEXT: ret <8 x i1> [[VOUT]]
;
@@ -170,7 +170,7 @@ entry:
define i32 @v2i_truncext_i16(<4 x i1> %vin) {
; CHECK-LABEL: @v2i_truncext_i16(
; CHECK-NEXT: entry:
-; CHECK-NEXT: [[WIDE1:%.*]] = call i32 @llvm.arm.mve.pred.v2i.v4i1(<4 x i1> [[VIN:%.*]]), !range [[RNG0]]
+; CHECK-NEXT: [[WIDE1:%.*]] = call noundef range(i32 0, 65536) i32 @llvm.arm.mve.pred.v2i.v4i1(<4 x i1> [[VIN:%.*]])
; CHECK-NEXT: ret i32 [[WIDE1]]
;
entry:
@@ -183,7 +183,7 @@ entry:
define i32 @v2i_truncext_i8(<4 x i1> %vin) {
; CHECK-LABEL: @v2i_truncext_i8(
; CHECK-NEXT: entry:
-; CHECK-NEXT: [[WIDE1:%.*]] = call i32 @llvm.arm.mve.pred.v2i.v4i1(<4 x i1> [[VIN:%.*]]), !range [[RNG0]]
+; CHECK-NEXT: [[WIDE1:%.*]] = call noundef range(i32 0, 65536) i32 @llvm.arm.mve.pred.v2i.v4i1(<4 x i1> [[VIN:%.*]])
; CHECK-NEXT: [[WIDE2:%.*]] = and i32 [[WIDE1]], 255
; CHECK-NEXT: ret i32 [[WIDE2]]
;
@@ -197,7 +197,7 @@ entry:
define i32 @v2i_and_16(<4 x i1> %vin) {
; CHECK-LABEL: @v2i_and_16(
; CHECK-NEXT: entry:
-; CHECK-NEXT: [[WIDE1:%.*]] = call i32 @llvm.arm.mve.pred.v2i.v4i1(<4 x i1> [[VIN:%.*]]), !range [[RNG0]]
+; CHECK-NEXT: [[WIDE1:%.*]] = call noundef range(i32 0, 65536) i32 @llvm.arm.mve.pred.v2i.v4i1(<4 x i1> [[VIN:%.*]])
; CHECK-NEXT: ret i32 [[WIDE1]]
;
entry:
@@ -209,7 +209,7 @@ entry:
define i32 @v2i_and_15(<4 x i1> %vin) {
; CHECK-LABEL: @v2i_and_15(
; CHECK-NEXT: entry:
-; CHECK-NEXT: [[WIDE1:%.*]] = call i32 @llvm.arm.mve.pred.v2i.v4i1(<4 x i1> [[VIN:%.*]]), !range [[RNG0]]
+; CHECK-NEXT: [[WIDE1:%.*]] = call noundef range(i32 0, 65536) i32 @llvm.arm.mve.pred.v2i.v4i1(<4 x i1> [[VIN:%.*]])
; CHECK-NEXT: [[WIDE2:%.*]] = and i32 [[WIDE1]], 32767
; CHECK-NEXT: ret i32 [[WIDE2]]
;
@@ -397,7 +397,7 @@ entry:
define i32 @range_upper_limit(<16 x i1> %vin) {
; CHECK-LABEL: @range_upper_limit(
; CHECK-NEXT: entry:
-; CHECK-NEXT: [[INT:%.*]] = call i32 @llvm.arm.mve.pred.v2i.v16i1(<16 x i1> [[VIN:%.*]]), !range [[RNG0]]
+; CHECK-NEXT: [[INT:%.*]] = call noundef range(i32 0, 65536) i32 @llvm.arm.mve.pred.v2i.v16i1(<16 x i1> [[VIN:%.*]])
; CHECK-NEXT: [[C:%.*]] = icmp eq i32 [[INT]], 65535
; CHECK-NEXT: [[S:%.*]] = zext i1 [[C]] to i32
; CHECK-NEXT: ret i32 [[S]]
@@ -408,3 +408,36 @@ entry:
%s = select i1 %c, i32 1, i32 0
ret i32 %s
}
+
+define i32 @range_already_added_larger_range(<16 x i1> %vin) {
+; CHECK-LABEL: @range_already_added_larger_range(
+; CHECK-NEXT: entry:
+; CHECK-NEXT: [[INT:%.*]] = call noundef range(i32 0, 65536) i32 @llvm.arm.mve.pred.v2i.v16i1(<16 x i1> [[VIN:%.*]])
+; CHECK-NEXT: ret i32 [[INT]]
+;
+entry:
+ %int = call noundef range(i32 0, 65540) i32 @llvm.arm.mve.pred.v2i.v16i1(<16 x i1> %vin)
+ ret i32 %int
+}
+
+define i32 @range_already_added_smaller_range(<16 x i1> %vin) {
+; CHECK-LABEL: @range_already_added_smaller_range(
+; CHECK-NEXT: entry:
+; CHECK-NEXT: [[INT:%.*]] = call noundef range(i32 0, 655) i32 @llvm.arm.mve.pred.v2i.v16i1(<16 x i1> [[VIN:%.*]])
+; CHECK-NEXT: ret i32 [[INT]]
+;
+entry:
+ %int = call noundef range(i32 0, 655) i32 @llvm.arm.mve.pred.v2i.v16i1(<16 x i1> %vin)
+ ret i32 %int
+}
+
+define i32 @range_already_added_same_range(<16 x i1> %vin) {
+; CHECK-LABEL: @range_already_added_same_range(
+; CHECK-NEXT: entry:
+; CHECK-NEXT: [[INT:%.*]] = call noundef range(i32 0, 65536) i32 @llvm.arm.mve.pred.v2i.v16i1(<16 x i1> [[VIN:%.*]])
+; CHECK-NEXT: ret i32 [[INT]]
+;
+entry:
+ %int = call noundef range(i32 0, 65536) i32 @llvm.arm.mve.pred.v2i.v16i1(<16 x i1> %vin)
+ ret i32 %int
+}
More information about the llvm-commits
mailing list