[llvm] 7203286 - [LangRef] vscale_range implies the vscale is power-of-two
via llvm-commits
llvm-commits at lists.llvm.org
Fri Jul 14 18:18:05 PDT 2023
Author: Zhongyunde
Date: 2023-07-15T09:13:48+08:00
New Revision: 7203286329defc7976c719d8750712c0d5de9c31
URL: https://github.com/llvm/llvm-project/commit/7203286329defc7976c719d8750712c0d5de9c31
DIFF: https://github.com/llvm/llvm-project/commit/7203286329defc7976c719d8750712c0d5de9c31.diff
LOG: [LangRef] vscale_range implies the vscale is power-of-two
According the discuss on D154953, we need to make the LangRef change
before the optimization relied on the new behaviour:
vscale_range implies vscale is a power-of-two value, parse of the
attribute to reject values that are not a power-of-two.
Thanks nikic for the wonderful summary of discussing on D154953:
To provide a bit more context here. We would like to have power of two vscale exposed in a target-independent way, so we can make use of this in places like ValueTracking, just like we currently do the vscale range. Some options that have been discussed are:
- Remove support for non-power-of-two vscales entirely. (This is my personal preference, but this is hard to undo if it turns out someone does need them.)
- Add an extra attribute vscale_pow2, or a data layout property.
- Make vscale_range imply power-of-two vscale, as a compromise solution (what this patch does). This would be relatively easy to turn into one of the two above at a later point.
Reviewed By: paulwalker-arm, nikic, efriedma
Differential Revision: https://reviews.llvm.org/D155193
Added:
Modified:
llvm/docs/LangRef.rst
llvm/lib/IR/Verifier.cpp
llvm/test/Transforms/InstCombine/icmp-vscale.ll
llvm/test/Transforms/InstCombine/vscale_sext_and_zext.ll
llvm/test/Transforms/InstCombine/vscale_trunc.ll
llvm/test/Verifier/vscale_range.ll
Removed:
################################################################################
diff --git a/llvm/docs/LangRef.rst b/llvm/docs/LangRef.rst
index 1aae6852a3e16d..eeba36e4167323 100644
--- a/llvm/docs/LangRef.rst
+++ b/llvm/docs/LangRef.rst
@@ -2331,11 +2331,12 @@ example:
than `UINT_MAX`. It's unspecified which threshold will be used when
duplicate definitions are linked together with
diff ering values.
``vscale_range(<min>[, <max>])``
- This attribute indicates the minimum and maximum vscale value for the given
- function. The min must be greater than 0. A maximum value of 0 means
- unbounded. If the optional max value is omitted then max is set to the
- value of min. If the attribute is not present, no assumptions are made
- about the range of vscale.
+ This function attribute indicates `vscale` is a power-of-two within a
+ specified range. `min` must be a power-of-two that is greater than 0. When
+ specified, `max` must be a power-of-two greater-than-or-equal to `min` or 0
+ to signify an unbounded maximum. The syntax `vscale_range(<val>)` can be
+ used to set both `min` and `max` to the same value. Functions that don't
+ include this attribute make no assumptions about the value of `vscale`.
``"nooutline"``
This attribute indicates that outlining passes should not modify the
function.
diff --git a/llvm/lib/IR/Verifier.cpp b/llvm/lib/IR/Verifier.cpp
index d10eb5f4f03ee6..1408ce293ca654 100644
--- a/llvm/lib/IR/Verifier.cpp
+++ b/llvm/lib/IR/Verifier.cpp
@@ -2181,10 +2181,13 @@ void Verifier::verifyFunctionAttrs(FunctionType *FT, AttributeList Attrs,
unsigned VScaleMin = Attrs.getFnAttrs().getVScaleRangeMin();
if (VScaleMin == 0)
CheckFailed("'vscale_range' minimum must be greater than 0", V);
-
+ else if (!isPowerOf2_32(VScaleMin))
+ CheckFailed("'vscale_range' minimum must be power-of-two value", V);
std::optional<unsigned> VScaleMax = Attrs.getFnAttrs().getVScaleRangeMax();
if (VScaleMax && VScaleMin > VScaleMax)
CheckFailed("'vscale_range' minimum cannot be greater than maximum", V);
+ else if (VScaleMax && !isPowerOf2_32(*VScaleMax))
+ CheckFailed("'vscale_range' maximum must be power-of-two value", V);
}
if (Attrs.hasFnAttr("frame-pointer")) {
diff --git a/llvm/test/Transforms/InstCombine/icmp-vscale.ll b/llvm/test/Transforms/InstCombine/icmp-vscale.ll
index baac5ce4959859..ae1be58938aa33 100644
--- a/llvm/test/Transforms/InstCombine/icmp-vscale.ll
+++ b/llvm/test/Transforms/InstCombine/icmp-vscale.ll
@@ -82,85 +82,85 @@ entry:
ret i1 %res
}
-define i1 @vscale_ule_max() vscale_range(5,10) {
+define i1 @vscale_ule_max() vscale_range(4,8) {
; CHECK-LABEL: @vscale_ule_max(
; CHECK-NEXT: ret i1 true
;
%vscale = call i16 @llvm.vscale.i16()
- %res = icmp ule i16 %vscale, 10
+ %res = icmp ule i16 %vscale, 8
ret i1 %res
}
-define i1 @vscale_ult_max() vscale_range(5,10) {
+define i1 @vscale_ult_max() vscale_range(4,8) {
; CHECK-LABEL: @vscale_ult_max(
; CHECK-NEXT: [[VSCALE:%.*]] = call i16 @llvm.vscale.i16()
-; CHECK-NEXT: [[RES:%.*]] = icmp ult i16 [[VSCALE]], 10
+; CHECK-NEXT: [[RES:%.*]] = icmp ult i16 [[VSCALE]], 8
; CHECK-NEXT: ret i1 [[RES]]
;
%vscale = call i16 @llvm.vscale.i16()
- %res = icmp ult i16 %vscale, 10
+ %res = icmp ult i16 %vscale, 8
ret i1 %res
}
-define i1 @vscale_uge_min() vscale_range(5,10) {
+define i1 @vscale_uge_min() vscale_range(4,8) {
; CHECK-LABEL: @vscale_uge_min(
; CHECK-NEXT: ret i1 true
;
%vscale = call i16 @llvm.vscale.i16()
- %res = icmp uge i16 %vscale, 5
+ %res = icmp uge i16 %vscale, 4
ret i1 %res
}
-define i1 @vscale_ugt_min() vscale_range(5,10) {
+define i1 @vscale_ugt_min() vscale_range(4,8) {
; CHECK-LABEL: @vscale_ugt_min(
; CHECK-NEXT: [[VSCALE:%.*]] = call i16 @llvm.vscale.i16()
-; CHECK-NEXT: [[RES:%.*]] = icmp ugt i16 [[VSCALE]], 5
+; CHECK-NEXT: [[RES:%.*]] = icmp ugt i16 [[VSCALE]], 4
; CHECK-NEXT: ret i1 [[RES]]
;
%vscale = call i16 @llvm.vscale.i16()
- %res = icmp ugt i16 %vscale, 5
+ %res = icmp ugt i16 %vscale, 4
ret i1 %res
}
-define i1 @vscale_uge_no_max() vscale_range(5) {
+define i1 @vscale_uge_no_max() vscale_range(4) {
; CHECK-LABEL: @vscale_uge_no_max(
; CHECK-NEXT: ret i1 true
;
%vscale = call i8 @llvm.vscale.i8()
- %res = icmp uge i8 %vscale, 5
+ %res = icmp uge i8 %vscale, 4
ret i1 %res
}
-define i1 @vscale_ugt_no_max() vscale_range(5) {
+define i1 @vscale_ugt_no_max() vscale_range(4) {
; CHECK-LABEL: @vscale_ugt_no_max(
; CHECK-NEXT: ret i1 false
;
%vscale = call i8 @llvm.vscale.i8()
- %res = icmp ugt i8 %vscale, 5
+ %res = icmp ugt i8 %vscale, 4
ret i1 %res
}
-define i1 @vscale_uge_max_overflow() vscale_range(5,256) {
+define i1 @vscale_uge_max_overflow() vscale_range(4,256) {
; CHECK-LABEL: @vscale_uge_max_overflow(
; CHECK-NEXT: ret i1 true
;
%vscale = call i8 @llvm.vscale.i8()
- %res = icmp uge i8 %vscale, 5
+ %res = icmp uge i8 %vscale, 4
ret i1 %res
}
-define i1 @vscale_ugt_max_overflow() vscale_range(5,256) {
+define i1 @vscale_ugt_max_overflow() vscale_range(4,256) {
; CHECK-LABEL: @vscale_ugt_max_overflow(
; CHECK-NEXT: [[VSCALE:%.*]] = call i8 @llvm.vscale.i8()
-; CHECK-NEXT: [[RES:%.*]] = icmp ugt i8 [[VSCALE]], 5
+; CHECK-NEXT: [[RES:%.*]] = icmp ugt i8 [[VSCALE]], 4
; CHECK-NEXT: ret i1 [[RES]]
;
%vscale = call i8 @llvm.vscale.i8()
- %res = icmp ugt i8 %vscale, 5
+ %res = icmp ugt i8 %vscale, 4
ret i1 %res
}
-define i1 @vscale_eq_min_overflow() vscale_range(256,300) {
+define i1 @vscale_eq_min_overflow() vscale_range(256,512) {
; CHECK-LABEL: @vscale_eq_min_overflow(
; CHECK-NEXT: ret i1 true
;
@@ -169,7 +169,7 @@ define i1 @vscale_eq_min_overflow() vscale_range(256,300) {
ret i1 %res
}
-define i1 @vscale_ult_min_overflow() vscale_range(256,300) {
+define i1 @vscale_ult_min_overflow() vscale_range(256,512) {
; CHECK-LABEL: @vscale_ult_min_overflow(
; CHECK-NEXT: ret i1 true
;
@@ -178,7 +178,7 @@ define i1 @vscale_ult_min_overflow() vscale_range(256,300) {
ret i1 %res
}
-define i1 @vscale_ugt_min_overflow() vscale_range(256,300) {
+define i1 @vscale_ugt_min_overflow() vscale_range(256,512) {
; CHECK-LABEL: @vscale_ugt_min_overflow(
; CHECK-NEXT: ret i1 true
;
diff --git a/llvm/test/Transforms/InstCombine/vscale_sext_and_zext.ll b/llvm/test/Transforms/InstCombine/vscale_sext_and_zext.ll
index aa224c11ae2f34..80d196d05735d2 100644
--- a/llvm/test/Transforms/InstCombine/vscale_sext_and_zext.ll
+++ b/llvm/test/Transforms/InstCombine/vscale_sext_and_zext.ll
@@ -5,7 +5,7 @@
; Sign-extend
;
-define i32 @vscale_SExt_i8toi32() vscale_range(1, 127) {
+define i32 @vscale_SExt_i8toi32() vscale_range(1, 64) {
; CHECK-LABEL: @vscale_SExt_i8toi32(
; CHECK-NEXT: entry:
; CHECK-NEXT: [[TMP0:%.*]] = call i32 @llvm.vscale.i32()
diff --git a/llvm/test/Transforms/InstCombine/vscale_trunc.ll b/llvm/test/Transforms/InstCombine/vscale_trunc.ll
index e7e416eaf78187..e5211ba6228cd4 100644
--- a/llvm/test/Transforms/InstCombine/vscale_trunc.ll
+++ b/llvm/test/Transforms/InstCombine/vscale_trunc.ll
@@ -1,7 +1,7 @@
; NOTE: Assertions have been autogenerated by utils/update_test_checks.py
; RUN: opt < %s -passes=instcombine -S | FileCheck %s
-define i8 @vscale_trunc_i32toi8() vscale_range(1, 255) {
+define i8 @vscale_trunc_i32toi8() vscale_range(1, 128) {
; CHECK-LABEL: @vscale_trunc_i32toi8(
; CHECK-NEXT: entry:
; CHECK-NEXT: [[TMP0:%.*]] = call i8 @llvm.vscale.i8()
diff --git a/llvm/test/Verifier/vscale_range.ll b/llvm/test/Verifier/vscale_range.ll
index 37e761e7464d4c..fc7abd7af1d82a 100644
--- a/llvm/test/Verifier/vscale_range.ll
+++ b/llvm/test/Verifier/vscale_range.ll
@@ -5,3 +5,9 @@ declare ptr @a(ptr) vscale_range(0, 1)
; CHECK: 'vscale_range' minimum cannot be greater than maximum
declare ptr @b(ptr) vscale_range(8, 1)
+
+; CHECK: 'vscale_range' minimum must be power-of-two value
+declare ptr @c(ptr) vscale_range(3, 16)
+
+; CHECK: 'vscale_range' maximum must be power-of-two value
+declare ptr @d(ptr) vscale_range(2, 5)
More information about the llvm-commits
mailing list