Skip to content

Commit 18248f7

Browse files
committed
[InstCombine] Swap out range and noundef metadata to attribute for arm_mve_pred_v2i.
1 parent 6b3e000 commit 18248f7

File tree

3 files changed

+72
-26
lines changed

3 files changed

+72
-26
lines changed

llvm/lib/CodeGen/SelectionDAG/SelectionDAGBuilder.cpp

Lines changed: 16 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -4487,6 +4487,18 @@ static const MDNode *getRangeMetadata(const Instruction &I) {
44874487
return I.getMetadata(LLVMContext::MD_range);
44884488
}
44894489

4490+
static std::optional<ConstantRange> getRange(const Instruction &I) {
4491+
if (const auto *CB = dyn_cast<CallBase>(&I)) {
4492+
// see comment in getRangeMetadata about this check
4493+
if (CB->hasRetAttr(Attribute::NoUndef))
4494+
return CB->getRange();
4495+
}
4496+
if (const MDNode *Range = getRangeMetadata(I)) {
4497+
return getConstantRangeFromMetadata(*Range);
4498+
}
4499+
return std::nullopt;
4500+
}
4501+
44904502
void SelectionDAGBuilder::visitLoad(const LoadInst &I) {
44914503
if (I.isAtomic())
44924504
return visitAtomicLoad(I);
@@ -10229,19 +10241,16 @@ void SelectionDAGBuilder::visitVACopy(const CallInst &I) {
1022910241
SDValue SelectionDAGBuilder::lowerRangeToAssertZExt(SelectionDAG &DAG,
1023010242
const Instruction &I,
1023110243
SDValue Op) {
10232-
const MDNode *Range = getRangeMetadata(I);
10233-
if (!Range)
10234-
return Op;
10244+
std::optional<ConstantRange> CR = getRange(I);
1023510245

10236-
ConstantRange CR = getConstantRangeFromMetadata(*Range);
10237-
if (CR.isFullSet() || CR.isEmptySet() || CR.isUpperWrapped())
10246+
if (!CR || CR->isFullSet() || CR->isEmptySet() || CR->isUpperWrapped())
1023810247
return Op;
1023910248

10240-
APInt Lo = CR.getUnsignedMin();
10249+
APInt Lo = CR->getUnsignedMin();
1024110250
if (!Lo.isMinValue())
1024210251
return Op;
1024310252

10244-
APInt Hi = CR.getUnsignedMax();
10253+
APInt Hi = CR->getUnsignedMax();
1024510254
unsigned Bits = std::max(Hi.getActiveBits(),
1024610255
static_cast<unsigned>(IntegerType::MIN_INT_BITS));
1024710256

llvm/lib/Target/ARM/ARMTargetTransformInfo.cpp

Lines changed: 14 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -199,17 +199,21 @@ ARMTTIImpl::instCombineIntrinsic(InstCombiner &IC, IntrinsicInst &II) const {
199199
PatternMatch::m_Value(ArgArg)))) {
200200
return IC.replaceInstUsesWith(II, ArgArg);
201201
}
202-
if (!II.getMetadata(LLVMContext::MD_range)) {
203-
Type *IntTy32 = Type::getInt32Ty(II.getContext());
204-
Metadata *M[] = {
205-
ConstantAsMetadata::get(ConstantInt::get(IntTy32, 0)),
206-
ConstantAsMetadata::get(ConstantInt::get(IntTy32, 0x10000))};
207-
II.setMetadata(LLVMContext::MD_range, MDNode::get(II.getContext(), M));
208-
II.setMetadata(LLVMContext::MD_noundef,
209-
MDNode::get(II.getContext(), std::nullopt));
210-
return &II;
202+
203+
if (II.getMetadata(LLVMContext::MD_range))
204+
break;
205+
206+
ConstantRange Range(APInt(32, 0), APInt(32, 0x10000));
207+
208+
if (auto CurrentRange = II.getRange()) {
209+
Range = Range.intersectWith(*CurrentRange);
210+
if (Range == CurrentRange)
211+
break;
211212
}
212-
break;
213+
214+
II.addRangeRetAttr(Range);
215+
II.addRetAttr(Attribute::NoUndef);
216+
return &II;
213217
}
214218
case Intrinsic::arm_mve_vadc:
215219
case Intrinsic::arm_mve_vadc_predicated: {

llvm/test/Transforms/InstCombine/ARM/mve-v2i2v.ll

Lines changed: 42 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -66,7 +66,7 @@ entry:
6666
define <16 x i1> @v2i2v_2_16(<2 x i1> %vin) {
6767
; CHECK-LABEL: @v2i2v_2_16(
6868
; CHECK-NEXT: entry:
69-
; CHECK-NEXT: [[INT:%.*]] = call i32 @llvm.arm.mve.pred.v2i.v2i1(<2 x i1> [[VIN:%.*]]), !range [[RNG0:![0-9]+]]
69+
; CHECK-NEXT: [[INT:%.*]] = call noundef range(i32 0, 65536) i32 @llvm.arm.mve.pred.v2i.v2i1(<2 x i1> [[VIN:%.*]])
7070
; CHECK-NEXT: [[VOUT:%.*]] = call <16 x i1> @llvm.arm.mve.pred.i2v.v16i1(i32 [[INT]])
7171
; CHECK-NEXT: ret <16 x i1> [[VOUT]]
7272
;
@@ -79,7 +79,7 @@ entry:
7979
define <16 x i1> @v2i2v_4_16(<4 x i1> %vin) {
8080
; CHECK-LABEL: @v2i2v_4_16(
8181
; CHECK-NEXT: entry:
82-
; CHECK-NEXT: [[INT:%.*]] = call i32 @llvm.arm.mve.pred.v2i.v4i1(<4 x i1> [[VIN:%.*]]), !range [[RNG0]]
82+
; CHECK-NEXT: [[INT:%.*]] = call noundef range(i32 0, 65536) i32 @llvm.arm.mve.pred.v2i.v4i1(<4 x i1> [[VIN:%.*]])
8383
; CHECK-NEXT: [[VOUT:%.*]] = call <16 x i1> @llvm.arm.mve.pred.i2v.v16i1(i32 [[INT]])
8484
; CHECK-NEXT: ret <16 x i1> [[VOUT]]
8585
;
@@ -92,7 +92,7 @@ entry:
9292
define <4 x i1> @v2i2v_8_4(<8 x i1> %vin) {
9393
; CHECK-LABEL: @v2i2v_8_4(
9494
; CHECK-NEXT: entry:
95-
; CHECK-NEXT: [[INT:%.*]] = call i32 @llvm.arm.mve.pred.v2i.v8i1(<8 x i1> [[VIN:%.*]]), !range [[RNG0]]
95+
; CHECK-NEXT: [[INT:%.*]] = call noundef range(i32 0, 65536) i32 @llvm.arm.mve.pred.v2i.v8i1(<8 x i1> [[VIN:%.*]])
9696
; CHECK-NEXT: [[VOUT:%.*]] = call <4 x i1> @llvm.arm.mve.pred.i2v.v4i1(i32 [[INT]])
9797
; CHECK-NEXT: ret <4 x i1> [[VOUT]]
9898
;
@@ -105,7 +105,7 @@ entry:
105105
define <8 x i1> @v2i2v_16_8(<16 x i1> %vin) {
106106
; CHECK-LABEL: @v2i2v_16_8(
107107
; CHECK-NEXT: entry:
108-
; CHECK-NEXT: [[INT:%.*]] = call i32 @llvm.arm.mve.pred.v2i.v16i1(<16 x i1> [[VIN:%.*]]), !range [[RNG0]]
108+
; CHECK-NEXT: [[INT:%.*]] = call noundef range(i32 0, 65536) i32 @llvm.arm.mve.pred.v2i.v16i1(<16 x i1> [[VIN:%.*]])
109109
; CHECK-NEXT: [[VOUT:%.*]] = call <8 x i1> @llvm.arm.mve.pred.i2v.v8i1(i32 [[INT]])
110110
; CHECK-NEXT: ret <8 x i1> [[VOUT]]
111111
;
@@ -170,7 +170,7 @@ entry:
170170
define i32 @v2i_truncext_i16(<4 x i1> %vin) {
171171
; CHECK-LABEL: @v2i_truncext_i16(
172172
; CHECK-NEXT: entry:
173-
; CHECK-NEXT: [[WIDE1:%.*]] = call i32 @llvm.arm.mve.pred.v2i.v4i1(<4 x i1> [[VIN:%.*]]), !range [[RNG0]]
173+
; CHECK-NEXT: [[WIDE1:%.*]] = call noundef range(i32 0, 65536) i32 @llvm.arm.mve.pred.v2i.v4i1(<4 x i1> [[VIN:%.*]])
174174
; CHECK-NEXT: ret i32 [[WIDE1]]
175175
;
176176
entry:
@@ -183,7 +183,7 @@ entry:
183183
define i32 @v2i_truncext_i8(<4 x i1> %vin) {
184184
; CHECK-LABEL: @v2i_truncext_i8(
185185
; CHECK-NEXT: entry:
186-
; CHECK-NEXT: [[WIDE1:%.*]] = call i32 @llvm.arm.mve.pred.v2i.v4i1(<4 x i1> [[VIN:%.*]]), !range [[RNG0]]
186+
; CHECK-NEXT: [[WIDE1:%.*]] = call noundef range(i32 0, 65536) i32 @llvm.arm.mve.pred.v2i.v4i1(<4 x i1> [[VIN:%.*]])
187187
; CHECK-NEXT: [[WIDE2:%.*]] = and i32 [[WIDE1]], 255
188188
; CHECK-NEXT: ret i32 [[WIDE2]]
189189
;
@@ -197,7 +197,7 @@ entry:
197197
define i32 @v2i_and_16(<4 x i1> %vin) {
198198
; CHECK-LABEL: @v2i_and_16(
199199
; CHECK-NEXT: entry:
200-
; CHECK-NEXT: [[WIDE1:%.*]] = call i32 @llvm.arm.mve.pred.v2i.v4i1(<4 x i1> [[VIN:%.*]]), !range [[RNG0]]
200+
; CHECK-NEXT: [[WIDE1:%.*]] = call noundef range(i32 0, 65536) i32 @llvm.arm.mve.pred.v2i.v4i1(<4 x i1> [[VIN:%.*]])
201201
; CHECK-NEXT: ret i32 [[WIDE1]]
202202
;
203203
entry:
@@ -209,7 +209,7 @@ entry:
209209
define i32 @v2i_and_15(<4 x i1> %vin) {
210210
; CHECK-LABEL: @v2i_and_15(
211211
; CHECK-NEXT: entry:
212-
; CHECK-NEXT: [[WIDE1:%.*]] = call i32 @llvm.arm.mve.pred.v2i.v4i1(<4 x i1> [[VIN:%.*]]), !range [[RNG0]]
212+
; CHECK-NEXT: [[WIDE1:%.*]] = call noundef range(i32 0, 65536) i32 @llvm.arm.mve.pred.v2i.v4i1(<4 x i1> [[VIN:%.*]])
213213
; CHECK-NEXT: [[WIDE2:%.*]] = and i32 [[WIDE1]], 32767
214214
; CHECK-NEXT: ret i32 [[WIDE2]]
215215
;
@@ -397,7 +397,7 @@ entry:
397397
define i32 @range_upper_limit(<16 x i1> %vin) {
398398
; CHECK-LABEL: @range_upper_limit(
399399
; CHECK-NEXT: entry:
400-
; CHECK-NEXT: [[INT:%.*]] = call i32 @llvm.arm.mve.pred.v2i.v16i1(<16 x i1> [[VIN:%.*]]), !range [[RNG0]]
400+
; CHECK-NEXT: [[INT:%.*]] = call noundef range(i32 0, 65536) i32 @llvm.arm.mve.pred.v2i.v16i1(<16 x i1> [[VIN:%.*]])
401401
; CHECK-NEXT: [[C:%.*]] = icmp eq i32 [[INT]], 65535
402402
; CHECK-NEXT: [[S:%.*]] = zext i1 [[C]] to i32
403403
; CHECK-NEXT: ret i32 [[S]]
@@ -408,3 +408,36 @@ entry:
408408
%s = select i1 %c, i32 1, i32 0
409409
ret i32 %s
410410
}
411+
412+
define i32 @range_already_added_larger_range(<16 x i1> %vin) {
413+
; CHECK-LABEL: @range_already_added_larger_range(
414+
; CHECK-NEXT: entry:
415+
; CHECK-NEXT: [[INT:%.*]] = call noundef range(i32 0, 65536) i32 @llvm.arm.mve.pred.v2i.v16i1(<16 x i1> [[VIN:%.*]])
416+
; CHECK-NEXT: ret i32 [[INT]]
417+
;
418+
entry:
419+
%int = call noundef range(i32 0, 65540) i32 @llvm.arm.mve.pred.v2i.v16i1(<16 x i1> %vin)
420+
ret i32 %int
421+
}
422+
423+
define i32 @range_already_added_smaller_range(<16 x i1> %vin) {
424+
; CHECK-LABEL: @range_already_added_smaller_range(
425+
; CHECK-NEXT: entry:
426+
; CHECK-NEXT: [[INT:%.*]] = call noundef range(i32 0, 655) i32 @llvm.arm.mve.pred.v2i.v16i1(<16 x i1> [[VIN:%.*]])
427+
; CHECK-NEXT: ret i32 [[INT]]
428+
;
429+
entry:
430+
%int = call noundef range(i32 0, 655) i32 @llvm.arm.mve.pred.v2i.v16i1(<16 x i1> %vin)
431+
ret i32 %int
432+
}
433+
434+
define i32 @range_already_added_same_range(<16 x i1> %vin) {
435+
; CHECK-LABEL: @range_already_added_same_range(
436+
; CHECK-NEXT: entry:
437+
; CHECK-NEXT: [[INT:%.*]] = call noundef range(i32 0, 65536) i32 @llvm.arm.mve.pred.v2i.v16i1(<16 x i1> [[VIN:%.*]])
438+
; CHECK-NEXT: ret i32 [[INT]]
439+
;
440+
entry:
441+
%int = call noundef range(i32 0, 65536) i32 @llvm.arm.mve.pred.v2i.v16i1(<16 x i1> %vin)
442+
ret i32 %int
443+
}

0 commit comments

Comments
 (0)