[llvm-branch-commits] [llvm] [SelectionDAG] Emit `AssertZext` for function argument range attributes (PR #196786)
https://github.com/el-ev updated https://github.com/llvm/llvm-project/pull/196786 >From e07ed31ce772d4f648b0894546f5bd801e4611b4 Mon Sep 17 00:00:00 2001 From: Iris Shi <[email protected]> Date: Sun, 10 May 2026 15:30:20 +0800 Subject: [PATCH 1/4] [SelectionDAG] Emit `AssertZext` for function argument range attributes --- llvm/lib/CodeGen/SelectionDAG/SelectionDAGBuilder.cpp | 7 ++- llvm/lib/CodeGen/SelectionDAG/SelectionDAGBuilder.h | 2 ++ 2 files changed, 8 insertions(+), 1 deletion(-) diff --git a/llvm/lib/CodeGen/SelectionDAG/SelectionDAGBuilder.cpp b/llvm/lib/CodeGen/SelectionDAG/SelectionDAGBuilder.cpp index 5753d74168e59..1139ba64fa01c 100644 --- a/llvm/lib/CodeGen/SelectionDAG/SelectionDAGBuilder.cpp +++ b/llvm/lib/CodeGen/SelectionDAG/SelectionDAGBuilder.cpp @@ -10847,8 +10847,11 @@ void SelectionDAGBuilder::visitVACopy(const CallInst &I) { SDValue SelectionDAGBuilder::lowerRangeToAssertZExt(SelectionDAG &DAG, const Instruction &I, SDValue Op) { - std::optional CR = getRange(I); + return lowerRangeToAssertZExt(DAG, getRange(I), Op); +} +SDValue SelectionDAGBuilder::lowerRangeToAssertZExt( +SelectionDAG &DAG, std::optional CR, SDValue Op) { if (!CR || CR->isFullSet() || CR->isEmptySet() || CR->isUpperWrapped()) return Op; @@ -12198,6 +12201,8 @@ void SelectionDAGISel::LowerArguments(const Function &F) { OutVal = DAG.getNode(ISD::AssertNoFPClass, dl, OutVal.getValueType(), OutVal, SDNoFPClass); } +if (NumValues == 1 && VT.isInteger()) + OutVal = SDB->lowerRangeToAssertZExt(DAG, Arg.getRange(), OutVal); ArgValues.push_back(OutVal); } diff --git a/llvm/lib/CodeGen/SelectionDAG/SelectionDAGBuilder.h b/llvm/lib/CodeGen/SelectionDAG/SelectionDAGBuilder.h index 21aac333a73cd..7edf005586989 100644 --- a/llvm/lib/CodeGen/SelectionDAG/SelectionDAGBuilder.h +++ b/llvm/lib/CodeGen/SelectionDAG/SelectionDAGBuilder.h @@ -429,6 +429,8 @@ class SelectionDAGBuilder { // floor power of two. SDValue lowerRangeToAssertZExt(SelectionDAG &DAG, const Instruction &I, SDValue Op); + SDValue lowerRangeToAssertZExt(SelectionDAG &DAG, + std::optional CR, SDValue Op); // Lower nofpclass attributes to AssertNoFPClass SDValue lowerNoFPClassToAssertNoFPClass(SelectionDAG &DAG, >From c00d6b6378e73232b9c8a2d57db3c1aa5c71ab29 Mon Sep 17 00:00:00 2001 From: Iris Shi <[email protected]> Date: Sun, 10 May 2026 15:30:45 +0800 Subject: [PATCH 2/4] add test --- llvm/test/CodeGen/X86/argument-range-attr.ll | 123 +++ 1 file changed, 123 insertions(+) create mode 100644 llvm/test/CodeGen/X86/argument-range-attr.ll diff --git a/llvm/test/CodeGen/X86/argument-range-attr.ll b/llvm/test/CodeGen/X86/argument-range-attr.ll new file mode 100644 index 0..376213bf6bd7c --- /dev/null +++ b/llvm/test/CodeGen/X86/argument-range-attr.ll @@ -0,0 +1,123 @@ +; NOTE: Assertions have been autogenerated by utils/update_llc_test_checks.py UTC_ARGS: --version 4 +; RUN: llc -mtriple=x86_64-unknown-linux-gnu < %s | FileCheck %s + +; range: 0..2^61 +; mask: 2^61 - 8 +define i64 @arg_range_top3(i64 range(i64 0, 2305843009213693952) %n) { +; CHECK-LABEL: arg_range_top3: +; CHECK: # %bb.0: +; CHECK-NEXT:movabsq $2305843009213693944, %rax # imm = 0x1FF8 +; CHECK-NEXT:andq %rdi, %rax +; CHECK-NEXT:retq + %r = and i64 %n, 2305843009213693944 + ret i64 %r +} + +; range: 0..256 +; mask: 0xF8 = 248 +define i64 @arg_range_byte(i64 range(i64 0, 256) %n) { +; CHECK-LABEL: arg_range_byte: +; CHECK: # %bb.0: +; CHECK-NEXT:movq %rdi, %rax +; CHECK-NEXT:andl $248, %eax +; CHECK-NEXT:retq + %r = and i64 %n, 248 + ret i64 %r +} + +define i64 @arg_range_nonzero_lo(i64 range(i64 1, 2305843009213693952) %n) { +; CHECK-LABEL: arg_range_nonzero_lo: +; CHECK: # %bb.0: +; CHECK-NEXT:movabsq $2305843009213693944, %rax # imm = 0x1FF8 +; CHECK-NEXT:andq %rdi, %rax +; CHECK-NEXT:retq + %r = and i64 %n, 2305843009213693944 + ret i64 %r +} + +define i64 @arg_range_byte_nonzero_lo(i64 range(i64 1, 256) %n) { +; CHECK-LABEL: arg_range_byte_nonzero_lo: +; CHECK: # %bb.0: +; CHECK-NEXT:movq %rdi, %rax +; CHECK-NEXT:andl $248, %eax +; CHECK-NEXT:retq + %r = and i64 %n, 248 + ret i64 %r +} + +define i32 @arg_range_i32_byte(i32 range(i32 0, 256) %n) { +; CHECK-LABEL: arg_range_i32_byte: +; CHECK: # %bb.0: +; CHECK-NEXT:movl %edi, %eax +; CHECK-NEXT:andl $248, %eax +; CHECK-NEXT:retq + %r = and i32 %n, 248 + ret i32 %r +} + +define i64 @arg_range_top1(i64 range(i64 0, 9223372036854775808) %n) { +; CHECK-LABEL: arg_range_top1: +; CHECK: # %bb.0: +; CHECK-NEXT:movq %rdi, %rax +; CHECK-NEXT:shrq $63, %rax +; CHECK-NEXT:retq + %r = lshr
[llvm-branch-commits] [llvm] [SelectionDAG] Emit `AssertZext` for function argument range attributes (PR #196786)
https://github.com/el-ev updated https://github.com/llvm/llvm-project/pull/196786 >From 02177f39214de7c77a10563d6e847bd90fd896d4 Mon Sep 17 00:00:00 2001 From: Iris Shi <[email protected]> Date: Sun, 10 May 2026 15:30:20 +0800 Subject: [PATCH 1/4] [SelectionDAG] Emit `AssertZext` for function argument range attributes --- llvm/lib/CodeGen/SelectionDAG/SelectionDAGBuilder.cpp | 7 ++- llvm/lib/CodeGen/SelectionDAG/SelectionDAGBuilder.h | 2 ++ 2 files changed, 8 insertions(+), 1 deletion(-) diff --git a/llvm/lib/CodeGen/SelectionDAG/SelectionDAGBuilder.cpp b/llvm/lib/CodeGen/SelectionDAG/SelectionDAGBuilder.cpp index 5753d74168e59..1139ba64fa01c 100644 --- a/llvm/lib/CodeGen/SelectionDAG/SelectionDAGBuilder.cpp +++ b/llvm/lib/CodeGen/SelectionDAG/SelectionDAGBuilder.cpp @@ -10847,8 +10847,11 @@ void SelectionDAGBuilder::visitVACopy(const CallInst &I) { SDValue SelectionDAGBuilder::lowerRangeToAssertZExt(SelectionDAG &DAG, const Instruction &I, SDValue Op) { - std::optional CR = getRange(I); + return lowerRangeToAssertZExt(DAG, getRange(I), Op); +} +SDValue SelectionDAGBuilder::lowerRangeToAssertZExt( +SelectionDAG &DAG, std::optional CR, SDValue Op) { if (!CR || CR->isFullSet() || CR->isEmptySet() || CR->isUpperWrapped()) return Op; @@ -12198,6 +12201,8 @@ void SelectionDAGISel::LowerArguments(const Function &F) { OutVal = DAG.getNode(ISD::AssertNoFPClass, dl, OutVal.getValueType(), OutVal, SDNoFPClass); } +if (NumValues == 1 && VT.isInteger()) + OutVal = SDB->lowerRangeToAssertZExt(DAG, Arg.getRange(), OutVal); ArgValues.push_back(OutVal); } diff --git a/llvm/lib/CodeGen/SelectionDAG/SelectionDAGBuilder.h b/llvm/lib/CodeGen/SelectionDAG/SelectionDAGBuilder.h index 21aac333a73cd..7edf005586989 100644 --- a/llvm/lib/CodeGen/SelectionDAG/SelectionDAGBuilder.h +++ b/llvm/lib/CodeGen/SelectionDAG/SelectionDAGBuilder.h @@ -429,6 +429,8 @@ class SelectionDAGBuilder { // floor power of two. SDValue lowerRangeToAssertZExt(SelectionDAG &DAG, const Instruction &I, SDValue Op); + SDValue lowerRangeToAssertZExt(SelectionDAG &DAG, + std::optional CR, SDValue Op); // Lower nofpclass attributes to AssertNoFPClass SDValue lowerNoFPClassToAssertNoFPClass(SelectionDAG &DAG, >From 3855bbafd2b2011a2509d4ac346644a71bd22c8c Mon Sep 17 00:00:00 2001 From: Iris Shi <[email protected]> Date: Sun, 10 May 2026 15:30:45 +0800 Subject: [PATCH 2/4] add test --- llvm/test/CodeGen/X86/argument-range-attr.ll | 123 +++ 1 file changed, 123 insertions(+) create mode 100644 llvm/test/CodeGen/X86/argument-range-attr.ll diff --git a/llvm/test/CodeGen/X86/argument-range-attr.ll b/llvm/test/CodeGen/X86/argument-range-attr.ll new file mode 100644 index 0..376213bf6bd7c --- /dev/null +++ b/llvm/test/CodeGen/X86/argument-range-attr.ll @@ -0,0 +1,123 @@ +; NOTE: Assertions have been autogenerated by utils/update_llc_test_checks.py UTC_ARGS: --version 4 +; RUN: llc -mtriple=x86_64-unknown-linux-gnu < %s | FileCheck %s + +; range: 0..2^61 +; mask: 2^61 - 8 +define i64 @arg_range_top3(i64 range(i64 0, 2305843009213693952) %n) { +; CHECK-LABEL: arg_range_top3: +; CHECK: # %bb.0: +; CHECK-NEXT:movabsq $2305843009213693944, %rax # imm = 0x1FF8 +; CHECK-NEXT:andq %rdi, %rax +; CHECK-NEXT:retq + %r = and i64 %n, 2305843009213693944 + ret i64 %r +} + +; range: 0..256 +; mask: 0xF8 = 248 +define i64 @arg_range_byte(i64 range(i64 0, 256) %n) { +; CHECK-LABEL: arg_range_byte: +; CHECK: # %bb.0: +; CHECK-NEXT:movq %rdi, %rax +; CHECK-NEXT:andl $248, %eax +; CHECK-NEXT:retq + %r = and i64 %n, 248 + ret i64 %r +} + +define i64 @arg_range_nonzero_lo(i64 range(i64 1, 2305843009213693952) %n) { +; CHECK-LABEL: arg_range_nonzero_lo: +; CHECK: # %bb.0: +; CHECK-NEXT:movabsq $2305843009213693944, %rax # imm = 0x1FF8 +; CHECK-NEXT:andq %rdi, %rax +; CHECK-NEXT:retq + %r = and i64 %n, 2305843009213693944 + ret i64 %r +} + +define i64 @arg_range_byte_nonzero_lo(i64 range(i64 1, 256) %n) { +; CHECK-LABEL: arg_range_byte_nonzero_lo: +; CHECK: # %bb.0: +; CHECK-NEXT:movq %rdi, %rax +; CHECK-NEXT:andl $248, %eax +; CHECK-NEXT:retq + %r = and i64 %n, 248 + ret i64 %r +} + +define i32 @arg_range_i32_byte(i32 range(i32 0, 256) %n) { +; CHECK-LABEL: arg_range_i32_byte: +; CHECK: # %bb.0: +; CHECK-NEXT:movl %edi, %eax +; CHECK-NEXT:andl $248, %eax +; CHECK-NEXT:retq + %r = and i32 %n, 248 + ret i32 %r +} + +define i64 @arg_range_top1(i64 range(i64 0, 9223372036854775808) %n) { +; CHECK-LABEL: arg_range_top1: +; CHECK: # %bb.0: +; CHECK-NEXT:movq %rdi, %rax +; CHECK-NEXT:shrq $63, %rax +; CHECK-NEXT:retq + %r = lshr
[llvm-branch-commits] [llvm] [SelectionDAG] Emit `AssertZext` for function argument range attributes (PR #196786)
@@ -0,0 +1,121 @@
+; NOTE: Assertions have been autogenerated by utils/update_llc_test_checks.py
UTC_ARGS: --version 4
+; RUN: llc -mtriple=x86_64-unknown-linux-gnu < %s | FileCheck %s
+
+; range: 0..2^61
+; mask: 2^61 - 8
+define i64 @arg_range_top3(i64 range(i64 0, 2305843009213693952) %n) {
+; CHECK-LABEL: arg_range_top3:
+; CHECK: # %bb.0:
+; CHECK-NEXT:movq %rdi, %rax
+; CHECK-NEXT:andq $-8, %rax
+; CHECK-NEXT:retq
+ %r = and i64 %n, 2305843009213693944
+ ret i64 %r
+}
+
+; range: 0..256
+; mask: 0xF8 = 248
+define i64 @arg_range_byte(i64 range(i64 0, 256) %n) {
+; CHECK-LABEL: arg_range_byte:
+; CHECK: # %bb.0:
+; CHECK-NEXT:movq %rdi, %rax
+; CHECK-NEXT:andl $-8, %eax
+; CHECK-NEXT:retq
+ %r = and i64 %n, 248
+ ret i64 %r
+}
+
+define i64 @arg_range_nonzero_lo(i64 range(i64 1, 2305843009213693952) %n) {
+; CHECK-LABEL: arg_range_nonzero_lo:
+; CHECK: # %bb.0:
+; CHECK-NEXT:movq %rdi, %rax
+; CHECK-NEXT:andq $-8, %rax
+; CHECK-NEXT:retq
+ %r = and i64 %n, 2305843009213693944
+ ret i64 %r
+}
+
+define i64 @arg_range_byte_nonzero_lo(i64 range(i64 1, 256) %n) {
+; CHECK-LABEL: arg_range_byte_nonzero_lo:
+; CHECK: # %bb.0:
+; CHECK-NEXT:movq %rdi, %rax
+; CHECK-NEXT:andl $-8, %eax
+; CHECK-NEXT:retq
+ %r = and i64 %n, 248
+ ret i64 %r
+}
+
+define i32 @arg_range_i32_byte(i32 range(i32 0, 256) %n) {
+; CHECK-LABEL: arg_range_i32_byte:
+; CHECK: # %bb.0:
+; CHECK-NEXT:movl %edi, %eax
+; CHECK-NEXT:andl $-8, %eax
+; CHECK-NEXT:retq
+ %r = and i32 %n, 248
+ ret i32 %r
+}
+
+define i64 @arg_range_top1(i64 range(i64 0, 9223372036854775808) %n) {
+; CHECK-LABEL: arg_range_top1:
+; CHECK: # %bb.0:
+; CHECK-NEXT:xorl %eax, %eax
+; CHECK-NEXT:retq
+ %r = lshr i64 %n, 63
+ ret i64 %r
+}
+
+define i64 @arg_range_two_args(i64 range(i64 0, 256) %a, i64 range(i64 0,
65536) %b) {
+; CHECK-LABEL: arg_range_two_args:
+; CHECK: # %bb.0:
+; CHECK-NEXT:movq %rdi, %rax
+; CHECK-NEXT:orl %esi, %eax
+; CHECK-NEXT:andl $-8, %eax
+; CHECK-NEXT:retq
+ %ra = and i64 %a, 248
+ %rb = and i64 %b, 65528
+ %r = or i64 %ra, %rb
+ ret i64 %r
+}
+
+define i32 @arg_range_zeroext(i8 zeroext range(i8 0, 16) %n) {
+; CHECK-LABEL: arg_range_zeroext:
+; CHECK: # %bb.0:
+; CHECK-NEXT:movl %edi, %eax
+; CHECK-NEXT:andl $-2, %eax
+; CHECK-NEXT:retq
+ %z = zext i8 %n to i32
+ %r = and i32 %z, 14
+ ret i32 %r
+}
+
+; Negative tests
+
+define i64 @neg_no_range(i64 %n) {
+; CHECK-LABEL: neg_no_range:
+; CHECK: # %bb.0:
+; CHECK-NEXT:movabsq $2305843009213693944, %rax # imm = 0x1FF8
+; CHECK-NEXT:andq %rdi, %rax
+; CHECK-NEXT:retq
+ %r = and i64 %n, 2305843009213693944
+ ret i64 %r
+}
+
+define i64 @neg_wrapped_range(i64 range(i64 -100, 100) %n) {
+; CHECK-LABEL: neg_wrapped_range:
+; CHECK: # %bb.0:
+; CHECK-NEXT:movabsq $2305843009213693944, %rax # imm = 0x1FF8
+; CHECK-NEXT:andq %rdi, %rax
+; CHECK-NEXT:retq
+ %r = and i64 %n, 2305843009213693944
+ ret i64 %r
+}
+
+define i32 @neg_near_full_range(i32 range(i32 0, -1) %n) {
+; CHECK-LABEL: neg_near_full_range:
+; CHECK: # %bb.0:
+; CHECK-NEXT:movl %edi, %eax
+; CHECK-NEXT:andl $248, %eax
+; CHECK-NEXT:retq
+ %r = and i32 %n, 248
+ ret i32 %r
+}
arsenm wrote:
Can you test a case where the argument list is long enough such that the
argument becomes a load from the stack? It should not be emitted in that case
since load nodes can directly encode the range
https://github.com/llvm/llvm-project/pull/196786
___
llvm-branch-commits mailing list
[email protected]
https://lists.llvm.org/cgi-bin/mailman/listinfo/llvm-branch-commits
[llvm-branch-commits] [llvm] [SelectionDAG] Emit `AssertZext` for function argument range attributes (PR #196786)
github-actions[bot] wrote:
# :window: Windows x64 Test Results
* 134510 tests passed
* 3259 tests skipped
* 3 tests failed
## Failed Tests
(click on a test name to see its output)
### LLVM
LLVM.Transforms/LoopVectorize/AArch64/partial-reduce-fsub-chained.ll
```
Exit Code: 1
Command Output (stdout):
--
# RUN: at line 2
not --crash c:\_work\llvm-project\llvm-project\build\bin\opt.exe
-passes=loop-vectorize -S
C:\_work\llvm-project\llvm-project\llvm\test\Transforms\LoopVectorize\AArch64\partial-reduce-fsub-chained.ll
2>&1 | c:\_work\llvm-project\llvm-project\build\bin\filecheck.exe
C:\_work\llvm-project\llvm-project\llvm\test\Transforms\LoopVectorize\AArch64\partial-reduce-fsub-chained.ll
--check-prefix=ASSERTION
# executed command: not --crash
'c:\_work\llvm-project\llvm-project\build\bin\opt.exe' -passes=loop-vectorize
-S
'C:\_work\llvm-project\llvm-project\llvm\test\Transforms\LoopVectorize\AArch64\partial-reduce-fsub-chained.ll'
# note: command had no output on stdout or stderr
# error: command failed with exit status: 1
# executed command:
'c:\_work\llvm-project\llvm-project\build\bin\filecheck.exe'
'C:\_work\llvm-project\llvm-project\llvm\test\Transforms\LoopVectorize\AArch64\partial-reduce-fsub-chained.ll'
--check-prefix=ASSERTION
# .---command stderr
# |
C:\_work\llvm-project\llvm-project\llvm\test\Transforms\LoopVectorize\AArch64\partial-reduce-fsub-chained.ll:11:14:
error: ASSERTION: expected string not found in input
# | ; ASSERTION: (Chain.RK != RecurKind::FAddChainWithSubs)
# | ^
# | :1:1: note: scanning from here
# | ; ModuleID =
'C:\_work\llvm-project\llvm-project\llvm\test\Transforms\LoopVectorize\AArch64\partial-reduce-fsub-chained.ll'
# | ^
# | :45:4: note: possible intended match here
# | %21 = icmp eq i32 %index.next, 1024
# |^
# |
# | Input file:
# | Check file:
C:\_work\llvm-project\llvm-project\llvm\test\Transforms\LoopVectorize\AArch64\partial-reduce-fsub-chained.ll
# |
# | -dump-input=help explains the following input dump.
# |
# | Input was:
# | <<
# | 1: ; ModuleID =
'C:\_work\llvm-project\llvm-project\llvm\test\Transforms\LoopVectorize\AArch64\partial-reduce-fsub-chained.ll'
# | check:11'0
X~~~
error: no match found
# | 2: source_filename =
"C:\\_work\\llvm-project\\llvm-project\\llvm\\test\\Transforms\\LoopVectorize\\AArch64\\partial-reduce-fsub-chained.ll"
# | check:11'0
~~
# | 3: target datalayout =
"e-m:e-i8:8:32-i16:16:32-i64:64-i128:128-n32:64-S128"
# | check:11'0
~~
# | 4: target triple = "aarch64-none-unknown-elf"
# | check:11'0 ~~~
# | 5:
# | check:11'0 ~
# | 6: define float @fadd_fsub_reduction(float %startval, ptr
%src1, ptr %src2, ptr %src3) {
# | check:11'0
~~
# | .
# | .
# | .
# |40: %17 = fmul reassoc contract <8 x float> %11, %3
# | check:11'0 ~
# |41: %18 = fmul reassoc contract <8 x float> %12, %4
# | check:11'0 ~
# |42: %19 = fsub reassoc contract <8 x float> %15, %17
# | check:11'0 ~~
# |43: %20 = fsub reassoc contract <8 x float> %16, %18
# | check:11'0 ~~
# |44: %index.next = add nuw i32 %index, 16
# | check:11'0 ~~
# |45: %21 = icmp eq i32 %index.next, 1024
# | check:11'0 ~
# | check:11'1? possible intended match
# |46: br i1 %21, label %middle.block, label %vector.body,
!llvm.loop !0
# | check:11'0
~~~
# |47:
# | check:11'0 ~
# |48: middle.block: ; preds = %vector.body
# | check:11'0 ~
# |49: %bin.rdx = fadd reassoc contract <8 x float> %20, %19
# | check:11'0 ~~~
# |50: %22 = call reassoc contract float
@llvm.vector.reduce.fadd.v8f32(float -0.00e+00, <8 x float> %bin.rdx)
# | check:11'0
~
# | .
# | .
# | .
# | >
[llvm-branch-commits] [llvm] [SelectionDAG] Emit `AssertZext` for function argument range attributes (PR #196786)
github-actions[bot] wrote:
# :penguin: Linux x64 Test Results
* 174046 tests passed
* 3323 tests skipped
* 3 tests failed
## Failed Tests
(click on a test name to see its output)
### LLVM
LLVM.Transforms/LoopVectorize/AArch64/partial-reduce-fsub-chained.ll
```
Exit Code: 1
Command Output (stdout):
--
# RUN: at line 2
not --crash
/home/gha/actions-runner/_work/llvm-project/llvm-project/build/bin/opt
-passes=loop-vectorize -S
/home/gha/actions-runner/_work/llvm-project/llvm-project/llvm/test/Transforms/LoopVectorize/AArch64/partial-reduce-fsub-chained.ll
2>&1 |
/home/gha/actions-runner/_work/llvm-project/llvm-project/build/bin/FileCheck
/home/gha/actions-runner/_work/llvm-project/llvm-project/llvm/test/Transforms/LoopVectorize/AArch64/partial-reduce-fsub-chained.ll
--check-prefix=ASSERTION
# executed command: not --crash
/home/gha/actions-runner/_work/llvm-project/llvm-project/build/bin/opt
-passes=loop-vectorize -S
/home/gha/actions-runner/_work/llvm-project/llvm-project/llvm/test/Transforms/LoopVectorize/AArch64/partial-reduce-fsub-chained.ll
# note: command had no output on stdout or stderr
# error: command failed with exit status: 1
# executed command:
/home/gha/actions-runner/_work/llvm-project/llvm-project/build/bin/FileCheck
/home/gha/actions-runner/_work/llvm-project/llvm-project/llvm/test/Transforms/LoopVectorize/AArch64/partial-reduce-fsub-chained.ll
--check-prefix=ASSERTION
# .---command stderr
# |
/home/gha/actions-runner/_work/llvm-project/llvm-project/llvm/test/Transforms/LoopVectorize/AArch64/partial-reduce-fsub-chained.ll:11:14:
error: ASSERTION: expected string not found in input
# | ; ASSERTION: (Chain.RK != RecurKind::FAddChainWithSubs)
# | ^
# | :1:1: note: scanning from here
# | ; ModuleID =
'/home/gha/actions-runner/_work/llvm-project/llvm-project/llvm/test/Transforms/LoopVectorize/AArch64/partial-reduce-fsub-chained.ll'
# | ^
# | :45:4: note: possible intended match here
# | %21 = icmp eq i32 %index.next, 1024
# |^
# |
# | Input file:
# | Check file:
/home/gha/actions-runner/_work/llvm-project/llvm-project/llvm/test/Transforms/LoopVectorize/AArch64/partial-reduce-fsub-chained.ll
# |
# | -dump-input=help explains the following input dump.
# |
# | Input was:
# | <<
# | 1: ; ModuleID =
'/home/gha/actions-runner/_work/llvm-project/llvm-project/llvm/test/Transforms/LoopVectorize/AArch64/partial-reduce-fsub-chained.ll'
# | check:11'0
X~
error: no match found
# | 2: source_filename =
"/home/gha/actions-runner/_work/llvm-project/llvm-project/llvm/test/Transforms/LoopVectorize/AArch64/partial-reduce-fsub-chained.ll"
# | check:11'0
~~~
# | 3: target datalayout =
"e-m:e-i8:8:32-i16:16:32-i64:64-i128:128-n32:64-S128"
# | check:11'0
~~
# | 4: target triple = "aarch64-none-unknown-elf"
# | check:11'0 ~~~
# | 5:
# | check:11'0 ~
# | 6: define float @fadd_fsub_reduction(float %startval, ptr
%src1, ptr %src2, ptr %src3) {
# | check:11'0
~~
# | .
# | .
# | .
# |40: %17 = fmul reassoc contract <8 x float> %11, %3
# | check:11'0 ~
# |41: %18 = fmul reassoc contract <8 x float> %12, %4
# | check:11'0 ~
# |42: %19 = fsub reassoc contract <8 x float> %15, %17
# | check:11'0 ~~
# |43: %20 = fsub reassoc contract <8 x float> %16, %18
# | check:11'0 ~~
# |44: %index.next = add nuw i32 %index, 16
# | check:11'0 ~~
# |45: %21 = icmp eq i32 %index.next, 1024
# | check:11'0 ~
# | check:11'1? possible intended match
# |46: br i1 %21, label %middle.block, label %vector.body,
!llvm.loop !0
# | check:11'0
~~~
# |47:
# | check:11'0 ~
# |48: middle.block: ; preds = %vector.body
# | check:11'0 ~
# |49: %bin.rdx = fadd reassoc contract <8 x float> %20, %19
# | check:11'0 ~~~
# |50: %22 = call rea
[llvm-branch-commits] [llvm] [SelectionDAG] Emit `AssertZext` for function argument range attributes (PR #196786)
https://github.com/el-ev updated https://github.com/llvm/llvm-project/pull/196786 >From ccb3861e2d938c5d1c4002b18c7462320bad32b1 Mon Sep 17 00:00:00 2001 From: Iris Shi <[email protected]> Date: Sun, 10 May 2026 15:30:20 +0800 Subject: [PATCH 1/3] [SelectionDAG] Emit `AssertZext` for function argument range attributes --- llvm/lib/CodeGen/SelectionDAG/SelectionDAGBuilder.cpp | 7 ++- llvm/lib/CodeGen/SelectionDAG/SelectionDAGBuilder.h | 2 ++ 2 files changed, 8 insertions(+), 1 deletion(-) diff --git a/llvm/lib/CodeGen/SelectionDAG/SelectionDAGBuilder.cpp b/llvm/lib/CodeGen/SelectionDAG/SelectionDAGBuilder.cpp index c001f0e0bd450..08fc33644e5b7 100644 --- a/llvm/lib/CodeGen/SelectionDAG/SelectionDAGBuilder.cpp +++ b/llvm/lib/CodeGen/SelectionDAG/SelectionDAGBuilder.cpp @@ -10848,8 +10848,11 @@ void SelectionDAGBuilder::visitVACopy(const CallInst &I) { SDValue SelectionDAGBuilder::lowerRangeToAssertZExt(SelectionDAG &DAG, const Instruction &I, SDValue Op) { - std::optional CR = getRange(I); + return lowerRangeToAssertZExt(DAG, getRange(I), Op); +} +SDValue SelectionDAGBuilder::lowerRangeToAssertZExt( +SelectionDAG &DAG, std::optional CR, SDValue Op) { if (!CR || CR->isFullSet() || CR->isEmptySet() || CR->isUpperWrapped()) return Op; @@ -12199,6 +12202,8 @@ void SelectionDAGISel::LowerArguments(const Function &F) { OutVal = DAG.getNode(ISD::AssertNoFPClass, dl, OutVal.getValueType(), OutVal, SDNoFPClass); } +if (NumValues == 1 && VT.isInteger()) + OutVal = SDB->lowerRangeToAssertZExt(DAG, Arg.getRange(), OutVal); ArgValues.push_back(OutVal); } diff --git a/llvm/lib/CodeGen/SelectionDAG/SelectionDAGBuilder.h b/llvm/lib/CodeGen/SelectionDAG/SelectionDAGBuilder.h index 21aac333a73cd..7edf005586989 100644 --- a/llvm/lib/CodeGen/SelectionDAG/SelectionDAGBuilder.h +++ b/llvm/lib/CodeGen/SelectionDAG/SelectionDAGBuilder.h @@ -429,6 +429,8 @@ class SelectionDAGBuilder { // floor power of two. SDValue lowerRangeToAssertZExt(SelectionDAG &DAG, const Instruction &I, SDValue Op); + SDValue lowerRangeToAssertZExt(SelectionDAG &DAG, + std::optional CR, SDValue Op); // Lower nofpclass attributes to AssertNoFPClass SDValue lowerNoFPClassToAssertNoFPClass(SelectionDAG &DAG, >From 0ae088fbde03cb7dc0902568d5042c0d46917d24 Mon Sep 17 00:00:00 2001 From: Iris Shi <[email protected]> Date: Sun, 10 May 2026 15:30:45 +0800 Subject: [PATCH 2/3] add test --- llvm/test/CodeGen/X86/argument-range-attr.ll | 123 +++ 1 file changed, 123 insertions(+) create mode 100644 llvm/test/CodeGen/X86/argument-range-attr.ll diff --git a/llvm/test/CodeGen/X86/argument-range-attr.ll b/llvm/test/CodeGen/X86/argument-range-attr.ll new file mode 100644 index 0..376213bf6bd7c --- /dev/null +++ b/llvm/test/CodeGen/X86/argument-range-attr.ll @@ -0,0 +1,123 @@ +; NOTE: Assertions have been autogenerated by utils/update_llc_test_checks.py UTC_ARGS: --version 4 +; RUN: llc -mtriple=x86_64-unknown-linux-gnu < %s | FileCheck %s + +; range: 0..2^61 +; mask: 2^61 - 8 +define i64 @arg_range_top3(i64 range(i64 0, 2305843009213693952) %n) { +; CHECK-LABEL: arg_range_top3: +; CHECK: # %bb.0: +; CHECK-NEXT:movabsq $2305843009213693944, %rax # imm = 0x1FF8 +; CHECK-NEXT:andq %rdi, %rax +; CHECK-NEXT:retq + %r = and i64 %n, 2305843009213693944 + ret i64 %r +} + +; range: 0..256 +; mask: 0xF8 = 248 +define i64 @arg_range_byte(i64 range(i64 0, 256) %n) { +; CHECK-LABEL: arg_range_byte: +; CHECK: # %bb.0: +; CHECK-NEXT:movq %rdi, %rax +; CHECK-NEXT:andl $248, %eax +; CHECK-NEXT:retq + %r = and i64 %n, 248 + ret i64 %r +} + +define i64 @arg_range_nonzero_lo(i64 range(i64 1, 2305843009213693952) %n) { +; CHECK-LABEL: arg_range_nonzero_lo: +; CHECK: # %bb.0: +; CHECK-NEXT:movabsq $2305843009213693944, %rax # imm = 0x1FF8 +; CHECK-NEXT:andq %rdi, %rax +; CHECK-NEXT:retq + %r = and i64 %n, 2305843009213693944 + ret i64 %r +} + +define i64 @arg_range_byte_nonzero_lo(i64 range(i64 1, 256) %n) { +; CHECK-LABEL: arg_range_byte_nonzero_lo: +; CHECK: # %bb.0: +; CHECK-NEXT:movq %rdi, %rax +; CHECK-NEXT:andl $248, %eax +; CHECK-NEXT:retq + %r = and i64 %n, 248 + ret i64 %r +} + +define i32 @arg_range_i32_byte(i32 range(i32 0, 256) %n) { +; CHECK-LABEL: arg_range_i32_byte: +; CHECK: # %bb.0: +; CHECK-NEXT:movl %edi, %eax +; CHECK-NEXT:andl $248, %eax +; CHECK-NEXT:retq + %r = and i32 %n, 248 + ret i32 %r +} + +define i64 @arg_range_top1(i64 range(i64 0, 9223372036854775808) %n) { +; CHECK-LABEL: arg_range_top1: +; CHECK: # %bb.0: +; CHECK-NEXT:movq %rdi, %rax +; CHECK-NEXT:shrq $63, %rax +; CHECK-NEXT:retq + %r = lshr
[llvm-branch-commits] [llvm] [SelectionDAG] Emit `AssertZext` for function argument range attributes (PR #196786)
https://github.com/el-ev updated https://github.com/llvm/llvm-project/pull/196786 >From ccb3861e2d938c5d1c4002b18c7462320bad32b1 Mon Sep 17 00:00:00 2001 From: Iris Shi <[email protected]> Date: Sun, 10 May 2026 15:30:20 +0800 Subject: [PATCH 1/3] [SelectionDAG] Emit `AssertZext` for function argument range attributes --- llvm/lib/CodeGen/SelectionDAG/SelectionDAGBuilder.cpp | 7 ++- llvm/lib/CodeGen/SelectionDAG/SelectionDAGBuilder.h | 2 ++ 2 files changed, 8 insertions(+), 1 deletion(-) diff --git a/llvm/lib/CodeGen/SelectionDAG/SelectionDAGBuilder.cpp b/llvm/lib/CodeGen/SelectionDAG/SelectionDAGBuilder.cpp index c001f0e0bd450..08fc33644e5b7 100644 --- a/llvm/lib/CodeGen/SelectionDAG/SelectionDAGBuilder.cpp +++ b/llvm/lib/CodeGen/SelectionDAG/SelectionDAGBuilder.cpp @@ -10848,8 +10848,11 @@ void SelectionDAGBuilder::visitVACopy(const CallInst &I) { SDValue SelectionDAGBuilder::lowerRangeToAssertZExt(SelectionDAG &DAG, const Instruction &I, SDValue Op) { - std::optional CR = getRange(I); + return lowerRangeToAssertZExt(DAG, getRange(I), Op); +} +SDValue SelectionDAGBuilder::lowerRangeToAssertZExt( +SelectionDAG &DAG, std::optional CR, SDValue Op) { if (!CR || CR->isFullSet() || CR->isEmptySet() || CR->isUpperWrapped()) return Op; @@ -12199,6 +12202,8 @@ void SelectionDAGISel::LowerArguments(const Function &F) { OutVal = DAG.getNode(ISD::AssertNoFPClass, dl, OutVal.getValueType(), OutVal, SDNoFPClass); } +if (NumValues == 1 && VT.isInteger()) + OutVal = SDB->lowerRangeToAssertZExt(DAG, Arg.getRange(), OutVal); ArgValues.push_back(OutVal); } diff --git a/llvm/lib/CodeGen/SelectionDAG/SelectionDAGBuilder.h b/llvm/lib/CodeGen/SelectionDAG/SelectionDAGBuilder.h index 21aac333a73cd..7edf005586989 100644 --- a/llvm/lib/CodeGen/SelectionDAG/SelectionDAGBuilder.h +++ b/llvm/lib/CodeGen/SelectionDAG/SelectionDAGBuilder.h @@ -429,6 +429,8 @@ class SelectionDAGBuilder { // floor power of two. SDValue lowerRangeToAssertZExt(SelectionDAG &DAG, const Instruction &I, SDValue Op); + SDValue lowerRangeToAssertZExt(SelectionDAG &DAG, + std::optional CR, SDValue Op); // Lower nofpclass attributes to AssertNoFPClass SDValue lowerNoFPClassToAssertNoFPClass(SelectionDAG &DAG, >From 0ae088fbde03cb7dc0902568d5042c0d46917d24 Mon Sep 17 00:00:00 2001 From: Iris Shi <[email protected]> Date: Sun, 10 May 2026 15:30:45 +0800 Subject: [PATCH 2/3] add test --- llvm/test/CodeGen/X86/argument-range-attr.ll | 123 +++ 1 file changed, 123 insertions(+) create mode 100644 llvm/test/CodeGen/X86/argument-range-attr.ll diff --git a/llvm/test/CodeGen/X86/argument-range-attr.ll b/llvm/test/CodeGen/X86/argument-range-attr.ll new file mode 100644 index 0..376213bf6bd7c --- /dev/null +++ b/llvm/test/CodeGen/X86/argument-range-attr.ll @@ -0,0 +1,123 @@ +; NOTE: Assertions have been autogenerated by utils/update_llc_test_checks.py UTC_ARGS: --version 4 +; RUN: llc -mtriple=x86_64-unknown-linux-gnu < %s | FileCheck %s + +; range: 0..2^61 +; mask: 2^61 - 8 +define i64 @arg_range_top3(i64 range(i64 0, 2305843009213693952) %n) { +; CHECK-LABEL: arg_range_top3: +; CHECK: # %bb.0: +; CHECK-NEXT:movabsq $2305843009213693944, %rax # imm = 0x1FF8 +; CHECK-NEXT:andq %rdi, %rax +; CHECK-NEXT:retq + %r = and i64 %n, 2305843009213693944 + ret i64 %r +} + +; range: 0..256 +; mask: 0xF8 = 248 +define i64 @arg_range_byte(i64 range(i64 0, 256) %n) { +; CHECK-LABEL: arg_range_byte: +; CHECK: # %bb.0: +; CHECK-NEXT:movq %rdi, %rax +; CHECK-NEXT:andl $248, %eax +; CHECK-NEXT:retq + %r = and i64 %n, 248 + ret i64 %r +} + +define i64 @arg_range_nonzero_lo(i64 range(i64 1, 2305843009213693952) %n) { +; CHECK-LABEL: arg_range_nonzero_lo: +; CHECK: # %bb.0: +; CHECK-NEXT:movabsq $2305843009213693944, %rax # imm = 0x1FF8 +; CHECK-NEXT:andq %rdi, %rax +; CHECK-NEXT:retq + %r = and i64 %n, 2305843009213693944 + ret i64 %r +} + +define i64 @arg_range_byte_nonzero_lo(i64 range(i64 1, 256) %n) { +; CHECK-LABEL: arg_range_byte_nonzero_lo: +; CHECK: # %bb.0: +; CHECK-NEXT:movq %rdi, %rax +; CHECK-NEXT:andl $248, %eax +; CHECK-NEXT:retq + %r = and i64 %n, 248 + ret i64 %r +} + +define i32 @arg_range_i32_byte(i32 range(i32 0, 256) %n) { +; CHECK-LABEL: arg_range_i32_byte: +; CHECK: # %bb.0: +; CHECK-NEXT:movl %edi, %eax +; CHECK-NEXT:andl $248, %eax +; CHECK-NEXT:retq + %r = and i32 %n, 248 + ret i32 %r +} + +define i64 @arg_range_top1(i64 range(i64 0, 9223372036854775808) %n) { +; CHECK-LABEL: arg_range_top1: +; CHECK: # %bb.0: +; CHECK-NEXT:movq %rdi, %rax +; CHECK-NEXT:shrq $63, %rax +; CHECK-NEXT:retq + %r = lshr
[llvm-branch-commits] [llvm] [SelectionDAG] Emit `AssertZext` for function argument range attributes (PR #196786)
https://github.com/el-ev updated https://github.com/llvm/llvm-project/pull/196786 >From 5ec2116d60b86d34733d2aa98c0cc36d6205d53d Mon Sep 17 00:00:00 2001 From: Iris Shi <[email protected]> Date: Sun, 10 May 2026 15:30:20 +0800 Subject: [PATCH 1/3] [SelectionDAG] Emit `AssertZext` for function argument range attributes --- llvm/lib/CodeGen/SelectionDAG/SelectionDAGBuilder.cpp | 7 ++- llvm/lib/CodeGen/SelectionDAG/SelectionDAGBuilder.h | 2 ++ 2 files changed, 8 insertions(+), 1 deletion(-) diff --git a/llvm/lib/CodeGen/SelectionDAG/SelectionDAGBuilder.cpp b/llvm/lib/CodeGen/SelectionDAG/SelectionDAGBuilder.cpp index c001f0e0bd450..08fc33644e5b7 100644 --- a/llvm/lib/CodeGen/SelectionDAG/SelectionDAGBuilder.cpp +++ b/llvm/lib/CodeGen/SelectionDAG/SelectionDAGBuilder.cpp @@ -10848,8 +10848,11 @@ void SelectionDAGBuilder::visitVACopy(const CallInst &I) { SDValue SelectionDAGBuilder::lowerRangeToAssertZExt(SelectionDAG &DAG, const Instruction &I, SDValue Op) { - std::optional CR = getRange(I); + return lowerRangeToAssertZExt(DAG, getRange(I), Op); +} +SDValue SelectionDAGBuilder::lowerRangeToAssertZExt( +SelectionDAG &DAG, std::optional CR, SDValue Op) { if (!CR || CR->isFullSet() || CR->isEmptySet() || CR->isUpperWrapped()) return Op; @@ -12199,6 +12202,8 @@ void SelectionDAGISel::LowerArguments(const Function &F) { OutVal = DAG.getNode(ISD::AssertNoFPClass, dl, OutVal.getValueType(), OutVal, SDNoFPClass); } +if (NumValues == 1 && VT.isInteger()) + OutVal = SDB->lowerRangeToAssertZExt(DAG, Arg.getRange(), OutVal); ArgValues.push_back(OutVal); } diff --git a/llvm/lib/CodeGen/SelectionDAG/SelectionDAGBuilder.h b/llvm/lib/CodeGen/SelectionDAG/SelectionDAGBuilder.h index 21aac333a73cd..7edf005586989 100644 --- a/llvm/lib/CodeGen/SelectionDAG/SelectionDAGBuilder.h +++ b/llvm/lib/CodeGen/SelectionDAG/SelectionDAGBuilder.h @@ -429,6 +429,8 @@ class SelectionDAGBuilder { // floor power of two. SDValue lowerRangeToAssertZExt(SelectionDAG &DAG, const Instruction &I, SDValue Op); + SDValue lowerRangeToAssertZExt(SelectionDAG &DAG, + std::optional CR, SDValue Op); // Lower nofpclass attributes to AssertNoFPClass SDValue lowerNoFPClassToAssertNoFPClass(SelectionDAG &DAG, >From 2d1c25bb487054f2bdc92fc44bc8a7c103b6c4fe Mon Sep 17 00:00:00 2001 From: Iris Shi <[email protected]> Date: Sun, 10 May 2026 15:30:45 +0800 Subject: [PATCH 2/3] add test --- llvm/test/CodeGen/X86/argument-range-attr.ll | 123 +++ 1 file changed, 123 insertions(+) create mode 100644 llvm/test/CodeGen/X86/argument-range-attr.ll diff --git a/llvm/test/CodeGen/X86/argument-range-attr.ll b/llvm/test/CodeGen/X86/argument-range-attr.ll new file mode 100644 index 0..376213bf6bd7c --- /dev/null +++ b/llvm/test/CodeGen/X86/argument-range-attr.ll @@ -0,0 +1,123 @@ +; NOTE: Assertions have been autogenerated by utils/update_llc_test_checks.py UTC_ARGS: --version 4 +; RUN: llc -mtriple=x86_64-unknown-linux-gnu < %s | FileCheck %s + +; range: 0..2^61 +; mask: 2^61 - 8 +define i64 @arg_range_top3(i64 range(i64 0, 2305843009213693952) %n) { +; CHECK-LABEL: arg_range_top3: +; CHECK: # %bb.0: +; CHECK-NEXT:movabsq $2305843009213693944, %rax # imm = 0x1FF8 +; CHECK-NEXT:andq %rdi, %rax +; CHECK-NEXT:retq + %r = and i64 %n, 2305843009213693944 + ret i64 %r +} + +; range: 0..256 +; mask: 0xF8 = 248 +define i64 @arg_range_byte(i64 range(i64 0, 256) %n) { +; CHECK-LABEL: arg_range_byte: +; CHECK: # %bb.0: +; CHECK-NEXT:movq %rdi, %rax +; CHECK-NEXT:andl $248, %eax +; CHECK-NEXT:retq + %r = and i64 %n, 248 + ret i64 %r +} + +define i64 @arg_range_nonzero_lo(i64 range(i64 1, 2305843009213693952) %n) { +; CHECK-LABEL: arg_range_nonzero_lo: +; CHECK: # %bb.0: +; CHECK-NEXT:movabsq $2305843009213693944, %rax # imm = 0x1FF8 +; CHECK-NEXT:andq %rdi, %rax +; CHECK-NEXT:retq + %r = and i64 %n, 2305843009213693944 + ret i64 %r +} + +define i64 @arg_range_byte_nonzero_lo(i64 range(i64 1, 256) %n) { +; CHECK-LABEL: arg_range_byte_nonzero_lo: +; CHECK: # %bb.0: +; CHECK-NEXT:movq %rdi, %rax +; CHECK-NEXT:andl $248, %eax +; CHECK-NEXT:retq + %r = and i64 %n, 248 + ret i64 %r +} + +define i32 @arg_range_i32_byte(i32 range(i32 0, 256) %n) { +; CHECK-LABEL: arg_range_i32_byte: +; CHECK: # %bb.0: +; CHECK-NEXT:movl %edi, %eax +; CHECK-NEXT:andl $248, %eax +; CHECK-NEXT:retq + %r = and i32 %n, 248 + ret i32 %r +} + +define i64 @arg_range_top1(i64 range(i64 0, 9223372036854775808) %n) { +; CHECK-LABEL: arg_range_top1: +; CHECK: # %bb.0: +; CHECK-NEXT:movq %rdi, %rax +; CHECK-NEXT:shrq $63, %rax +; CHECK-NEXT:retq + %r = lshr
[llvm-branch-commits] [llvm] [SelectionDAG] Emit `AssertZext` for function argument range attributes (PR #196786)
https://github.com/el-ev ready_for_review https://github.com/llvm/llvm-project/pull/196786 ___ llvm-branch-commits mailing list [email protected] https://lists.llvm.org/cgi-bin/mailman/listinfo/llvm-branch-commits
[llvm-branch-commits] [llvm] [SelectionDAG] Emit `AssertZext` for function argument range attributes (PR #196786)
https://github.com/el-ev edited https://github.com/llvm/llvm-project/pull/196786 ___ llvm-branch-commits mailing list [email protected] https://lists.llvm.org/cgi-bin/mailman/listinfo/llvm-branch-commits
[llvm-branch-commits] [llvm] [SelectionDAG] Emit `AssertZext` for function argument range attributes (PR #196786)
github-actions[bot] wrote:
:warning: C/C++ code formatter, clang-format found issues in your code.
:warning:
You can test this locally with the following command:
``bash
git-clang-format --diff origin/main HEAD --extensions h,cpp --
llvm/lib/CodeGen/SelectionDAG/SelectionDAGBuilder.cpp
llvm/lib/CodeGen/SelectionDAG/SelectionDAGBuilder.h --diff_from_common_commit
``
:warning:
The reproduction instructions above might return results for more than one PR
in a stack if you are using a stacked PR workflow. You can limit the results by
changing `origin/main` to the base branch/commit you want to compare against.
:warning:
View the diff from clang-format here.
``diff
diff --git a/llvm/lib/CodeGen/SelectionDAG/SelectionDAGBuilder.cpp
b/llvm/lib/CodeGen/SelectionDAG/SelectionDAGBuilder.cpp
index f159e3170..08fc33644 100644
--- a/llvm/lib/CodeGen/SelectionDAG/SelectionDAGBuilder.cpp
+++ b/llvm/lib/CodeGen/SelectionDAG/SelectionDAGBuilder.cpp
@@ -10851,9 +10851,8 @@ SDValue
SelectionDAGBuilder::lowerRangeToAssertZExt(SelectionDAG &DAG,
return lowerRangeToAssertZExt(DAG, getRange(I), Op);
}
-SDValue SelectionDAGBuilder::lowerRangeToAssertZExt(SelectionDAG &DAG,
-
std::optional CR,
-SDValue Op) {
+SDValue SelectionDAGBuilder::lowerRangeToAssertZExt(
+SelectionDAG &DAG, std::optional CR, SDValue Op) {
if (!CR || CR->isFullSet() || CR->isEmptySet() || CR->isUpperWrapped())
return Op;
diff --git a/llvm/lib/CodeGen/SelectionDAG/SelectionDAGBuilder.h
b/llvm/lib/CodeGen/SelectionDAG/SelectionDAGBuilder.h
index 3c40b1dec..7edf00558 100644
--- a/llvm/lib/CodeGen/SelectionDAG/SelectionDAGBuilder.h
+++ b/llvm/lib/CodeGen/SelectionDAG/SelectionDAGBuilder.h
@@ -429,8 +429,8 @@ public:
// floor power of two.
SDValue lowerRangeToAssertZExt(SelectionDAG &DAG, const Instruction &I,
SDValue Op);
- SDValue lowerRangeToAssertZExt(SelectionDAG &DAG,
std::optional CR,
- SDValue Op);
+ SDValue lowerRangeToAssertZExt(SelectionDAG &DAG,
+ std::optional CR, SDValue Op);
// Lower nofpclass attributes to AssertNoFPClass
SDValue lowerNoFPClassToAssertNoFPClass(SelectionDAG &DAG,
``
https://github.com/llvm/llvm-project/pull/196786
___
llvm-branch-commits mailing list
[email protected]
https://lists.llvm.org/cgi-bin/mailman/listinfo/llvm-branch-commits
[llvm-branch-commits] [llvm] [SelectionDAG] Emit `AssertZext` for function argument range attributes (PR #196786)
https://github.com/el-ev updated https://github.com/llvm/llvm-project/pull/196786 >From 5ec2116d60b86d34733d2aa98c0cc36d6205d53d Mon Sep 17 00:00:00 2001 From: Iris Shi <[email protected]> Date: Sun, 10 May 2026 15:30:20 +0800 Subject: [PATCH 1/3] [SelectionDAG] Emit `AssertZext` for function argument range attributes --- llvm/lib/CodeGen/SelectionDAG/SelectionDAGBuilder.cpp | 7 ++- llvm/lib/CodeGen/SelectionDAG/SelectionDAGBuilder.h | 2 ++ 2 files changed, 8 insertions(+), 1 deletion(-) diff --git a/llvm/lib/CodeGen/SelectionDAG/SelectionDAGBuilder.cpp b/llvm/lib/CodeGen/SelectionDAG/SelectionDAGBuilder.cpp index c001f0e0bd450..08fc33644e5b7 100644 --- a/llvm/lib/CodeGen/SelectionDAG/SelectionDAGBuilder.cpp +++ b/llvm/lib/CodeGen/SelectionDAG/SelectionDAGBuilder.cpp @@ -10848,8 +10848,11 @@ void SelectionDAGBuilder::visitVACopy(const CallInst &I) { SDValue SelectionDAGBuilder::lowerRangeToAssertZExt(SelectionDAG &DAG, const Instruction &I, SDValue Op) { - std::optional CR = getRange(I); + return lowerRangeToAssertZExt(DAG, getRange(I), Op); +} +SDValue SelectionDAGBuilder::lowerRangeToAssertZExt( +SelectionDAG &DAG, std::optional CR, SDValue Op) { if (!CR || CR->isFullSet() || CR->isEmptySet() || CR->isUpperWrapped()) return Op; @@ -12199,6 +12202,8 @@ void SelectionDAGISel::LowerArguments(const Function &F) { OutVal = DAG.getNode(ISD::AssertNoFPClass, dl, OutVal.getValueType(), OutVal, SDNoFPClass); } +if (NumValues == 1 && VT.isInteger()) + OutVal = SDB->lowerRangeToAssertZExt(DAG, Arg.getRange(), OutVal); ArgValues.push_back(OutVal); } diff --git a/llvm/lib/CodeGen/SelectionDAG/SelectionDAGBuilder.h b/llvm/lib/CodeGen/SelectionDAG/SelectionDAGBuilder.h index 21aac333a73cd..7edf005586989 100644 --- a/llvm/lib/CodeGen/SelectionDAG/SelectionDAGBuilder.h +++ b/llvm/lib/CodeGen/SelectionDAG/SelectionDAGBuilder.h @@ -429,6 +429,8 @@ class SelectionDAGBuilder { // floor power of two. SDValue lowerRangeToAssertZExt(SelectionDAG &DAG, const Instruction &I, SDValue Op); + SDValue lowerRangeToAssertZExt(SelectionDAG &DAG, + std::optional CR, SDValue Op); // Lower nofpclass attributes to AssertNoFPClass SDValue lowerNoFPClassToAssertNoFPClass(SelectionDAG &DAG, >From 2d1c25bb487054f2bdc92fc44bc8a7c103b6c4fe Mon Sep 17 00:00:00 2001 From: Iris Shi <[email protected]> Date: Sun, 10 May 2026 15:30:45 +0800 Subject: [PATCH 2/3] add test --- llvm/test/CodeGen/X86/argument-range-attr.ll | 123 +++ 1 file changed, 123 insertions(+) create mode 100644 llvm/test/CodeGen/X86/argument-range-attr.ll diff --git a/llvm/test/CodeGen/X86/argument-range-attr.ll b/llvm/test/CodeGen/X86/argument-range-attr.ll new file mode 100644 index 0..376213bf6bd7c --- /dev/null +++ b/llvm/test/CodeGen/X86/argument-range-attr.ll @@ -0,0 +1,123 @@ +; NOTE: Assertions have been autogenerated by utils/update_llc_test_checks.py UTC_ARGS: --version 4 +; RUN: llc -mtriple=x86_64-unknown-linux-gnu < %s | FileCheck %s + +; range: 0..2^61 +; mask: 2^61 - 8 +define i64 @arg_range_top3(i64 range(i64 0, 2305843009213693952) %n) { +; CHECK-LABEL: arg_range_top3: +; CHECK: # %bb.0: +; CHECK-NEXT:movabsq $2305843009213693944, %rax # imm = 0x1FF8 +; CHECK-NEXT:andq %rdi, %rax +; CHECK-NEXT:retq + %r = and i64 %n, 2305843009213693944 + ret i64 %r +} + +; range: 0..256 +; mask: 0xF8 = 248 +define i64 @arg_range_byte(i64 range(i64 0, 256) %n) { +; CHECK-LABEL: arg_range_byte: +; CHECK: # %bb.0: +; CHECK-NEXT:movq %rdi, %rax +; CHECK-NEXT:andl $248, %eax +; CHECK-NEXT:retq + %r = and i64 %n, 248 + ret i64 %r +} + +define i64 @arg_range_nonzero_lo(i64 range(i64 1, 2305843009213693952) %n) { +; CHECK-LABEL: arg_range_nonzero_lo: +; CHECK: # %bb.0: +; CHECK-NEXT:movabsq $2305843009213693944, %rax # imm = 0x1FF8 +; CHECK-NEXT:andq %rdi, %rax +; CHECK-NEXT:retq + %r = and i64 %n, 2305843009213693944 + ret i64 %r +} + +define i64 @arg_range_byte_nonzero_lo(i64 range(i64 1, 256) %n) { +; CHECK-LABEL: arg_range_byte_nonzero_lo: +; CHECK: # %bb.0: +; CHECK-NEXT:movq %rdi, %rax +; CHECK-NEXT:andl $248, %eax +; CHECK-NEXT:retq + %r = and i64 %n, 248 + ret i64 %r +} + +define i32 @arg_range_i32_byte(i32 range(i32 0, 256) %n) { +; CHECK-LABEL: arg_range_i32_byte: +; CHECK: # %bb.0: +; CHECK-NEXT:movl %edi, %eax +; CHECK-NEXT:andl $248, %eax +; CHECK-NEXT:retq + %r = and i32 %n, 248 + ret i32 %r +} + +define i64 @arg_range_top1(i64 range(i64 0, 9223372036854775808) %n) { +; CHECK-LABEL: arg_range_top1: +; CHECK: # %bb.0: +; CHECK-NEXT:movq %rdi, %rax +; CHECK-NEXT:shrq $63, %rax +; CHECK-NEXT:retq + %r = lshr
[llvm-branch-commits] [llvm] [SelectionDAG] Emit `AssertZext` for function argument range attributes (PR #196786)
https://github.com/el-ev created https://github.com/llvm/llvm-project/pull/196786 [SelectionDAG] Emit `AssertZext` for function argument range attributes add test update test >From 99876cf3b35cdb539b91b72ea4eca75fdf06fbac Mon Sep 17 00:00:00 2001 From: Iris Shi <[email protected]> Date: Sun, 10 May 2026 15:30:20 +0800 Subject: [PATCH 1/3] [SelectionDAG] Emit `AssertZext` for function argument range attributes --- llvm/lib/CodeGen/SelectionDAG/SelectionDAGBuilder.cpp | 8 +++- llvm/lib/CodeGen/SelectionDAG/SelectionDAGBuilder.h | 2 ++ 2 files changed, 9 insertions(+), 1 deletion(-) diff --git a/llvm/lib/CodeGen/SelectionDAG/SelectionDAGBuilder.cpp b/llvm/lib/CodeGen/SelectionDAG/SelectionDAGBuilder.cpp index c001f0e0bd450..f159e3170a5bd 100644 --- a/llvm/lib/CodeGen/SelectionDAG/SelectionDAGBuilder.cpp +++ b/llvm/lib/CodeGen/SelectionDAG/SelectionDAGBuilder.cpp @@ -10848,8 +10848,12 @@ void SelectionDAGBuilder::visitVACopy(const CallInst &I) { SDValue SelectionDAGBuilder::lowerRangeToAssertZExt(SelectionDAG &DAG, const Instruction &I, SDValue Op) { - std::optional CR = getRange(I); + return lowerRangeToAssertZExt(DAG, getRange(I), Op); +} +SDValue SelectionDAGBuilder::lowerRangeToAssertZExt(SelectionDAG &DAG, + std::optional CR, +SDValue Op) { if (!CR || CR->isFullSet() || CR->isEmptySet() || CR->isUpperWrapped()) return Op; @@ -12199,6 +12203,8 @@ void SelectionDAGISel::LowerArguments(const Function &F) { OutVal = DAG.getNode(ISD::AssertNoFPClass, dl, OutVal.getValueType(), OutVal, SDNoFPClass); } +if (NumValues == 1 && VT.isInteger()) + OutVal = SDB->lowerRangeToAssertZExt(DAG, Arg.getRange(), OutVal); ArgValues.push_back(OutVal); } diff --git a/llvm/lib/CodeGen/SelectionDAG/SelectionDAGBuilder.h b/llvm/lib/CodeGen/SelectionDAG/SelectionDAGBuilder.h index 21aac333a73cd..3c40b1dec4151 100644 --- a/llvm/lib/CodeGen/SelectionDAG/SelectionDAGBuilder.h +++ b/llvm/lib/CodeGen/SelectionDAG/SelectionDAGBuilder.h @@ -429,6 +429,8 @@ class SelectionDAGBuilder { // floor power of two. SDValue lowerRangeToAssertZExt(SelectionDAG &DAG, const Instruction &I, SDValue Op); + SDValue lowerRangeToAssertZExt(SelectionDAG &DAG, std::optional CR, + SDValue Op); // Lower nofpclass attributes to AssertNoFPClass SDValue lowerNoFPClassToAssertNoFPClass(SelectionDAG &DAG, >From f7d49ccdb534e35517cb0e42f3bbb1b100643dc5 Mon Sep 17 00:00:00 2001 From: Iris Shi <[email protected]> Date: Sun, 10 May 2026 15:30:45 +0800 Subject: [PATCH 2/3] add test --- llvm/test/CodeGen/X86/argument-range-attr.ll | 123 +++ 1 file changed, 123 insertions(+) create mode 100644 llvm/test/CodeGen/X86/argument-range-attr.ll diff --git a/llvm/test/CodeGen/X86/argument-range-attr.ll b/llvm/test/CodeGen/X86/argument-range-attr.ll new file mode 100644 index 0..376213bf6bd7c --- /dev/null +++ b/llvm/test/CodeGen/X86/argument-range-attr.ll @@ -0,0 +1,123 @@ +; NOTE: Assertions have been autogenerated by utils/update_llc_test_checks.py UTC_ARGS: --version 4 +; RUN: llc -mtriple=x86_64-unknown-linux-gnu < %s | FileCheck %s + +; range: 0..2^61 +; mask: 2^61 - 8 +define i64 @arg_range_top3(i64 range(i64 0, 2305843009213693952) %n) { +; CHECK-LABEL: arg_range_top3: +; CHECK: # %bb.0: +; CHECK-NEXT:movabsq $2305843009213693944, %rax # imm = 0x1FF8 +; CHECK-NEXT:andq %rdi, %rax +; CHECK-NEXT:retq + %r = and i64 %n, 2305843009213693944 + ret i64 %r +} + +; range: 0..256 +; mask: 0xF8 = 248 +define i64 @arg_range_byte(i64 range(i64 0, 256) %n) { +; CHECK-LABEL: arg_range_byte: +; CHECK: # %bb.0: +; CHECK-NEXT:movq %rdi, %rax +; CHECK-NEXT:andl $248, %eax +; CHECK-NEXT:retq + %r = and i64 %n, 248 + ret i64 %r +} + +define i64 @arg_range_nonzero_lo(i64 range(i64 1, 2305843009213693952) %n) { +; CHECK-LABEL: arg_range_nonzero_lo: +; CHECK: # %bb.0: +; CHECK-NEXT:movabsq $2305843009213693944, %rax # imm = 0x1FF8 +; CHECK-NEXT:andq %rdi, %rax +; CHECK-NEXT:retq + %r = and i64 %n, 2305843009213693944 + ret i64 %r +} + +define i64 @arg_range_byte_nonzero_lo(i64 range(i64 1, 256) %n) { +; CHECK-LABEL: arg_range_byte_nonzero_lo: +; CHECK: # %bb.0: +; CHECK-NEXT:movq %rdi, %rax +; CHECK-NEXT:andl $248, %eax +; CHECK-NEXT:retq + %r = and i64 %n, 248 + ret i64 %r +} + +define i32 @arg_range_i32_byte(i32 range(i32 0, 256) %n) { +; CHECK-LABEL: arg_range_i32_byte: +; CHECK: # %bb.0: +; CHECK-NEXT:movl %edi, %eax +; CHECK-NEXT:andl $248, %eax +; CHECK-NEXT:retq + %r = and i32 %n, 248 + ret i32 %r +} + +define i64 @arg_range_top1(i64 r
[llvm-branch-commits] [llvm] [SelectionDAG] Emit `AssertZext` for function argument range attributes (PR #196786)
llvmorg-github-actions[bot] wrote:
@llvm/pr-subscribers-backend-x86
Author: Iris Shi (el-ev)
Changes
Lower range attributes on function arguments to AssertZext nodes during
argument lowering.
Downstream issue: rust-lang/rust#149673
---
Full diff: https://github.com/llvm/llvm-project/pull/196786.diff
4 Files Affected:
- (modified) llvm/lib/CodeGen/SelectionDAG/SelectionDAGBuilder.cpp (+6-1)
- (modified) llvm/lib/CodeGen/SelectionDAG/SelectionDAGBuilder.h (+2)
- (modified) llvm/test/CodeGen/AMDGPU/bit-op-reduce-width-known-bits.ll (+3-3)
- (added) llvm/test/CodeGen/X86/argument-range-attr.ll (+121)
``diff
diff --git a/llvm/lib/CodeGen/SelectionDAG/SelectionDAGBuilder.cpp
b/llvm/lib/CodeGen/SelectionDAG/SelectionDAGBuilder.cpp
index c001f0e0bd450..08fc33644e5b7 100644
--- a/llvm/lib/CodeGen/SelectionDAG/SelectionDAGBuilder.cpp
+++ b/llvm/lib/CodeGen/SelectionDAG/SelectionDAGBuilder.cpp
@@ -10848,8 +10848,11 @@ void SelectionDAGBuilder::visitVACopy(const CallInst
&I) {
SDValue SelectionDAGBuilder::lowerRangeToAssertZExt(SelectionDAG &DAG,
const Instruction &I,
SDValue Op) {
- std::optional CR = getRange(I);
+ return lowerRangeToAssertZExt(DAG, getRange(I), Op);
+}
+SDValue SelectionDAGBuilder::lowerRangeToAssertZExt(
+SelectionDAG &DAG, std::optional CR, SDValue Op) {
if (!CR || CR->isFullSet() || CR->isEmptySet() || CR->isUpperWrapped())
return Op;
@@ -12199,6 +12202,8 @@ void SelectionDAGISel::LowerArguments(const Function
&F) {
OutVal = DAG.getNode(ISD::AssertNoFPClass, dl, OutVal.getValueType(),
OutVal, SDNoFPClass);
}
+if (NumValues == 1 && VT.isInteger())
+ OutVal = SDB->lowerRangeToAssertZExt(DAG, Arg.getRange(), OutVal);
ArgValues.push_back(OutVal);
}
diff --git a/llvm/lib/CodeGen/SelectionDAG/SelectionDAGBuilder.h
b/llvm/lib/CodeGen/SelectionDAG/SelectionDAGBuilder.h
index 21aac333a73cd..7edf005586989 100644
--- a/llvm/lib/CodeGen/SelectionDAG/SelectionDAGBuilder.h
+++ b/llvm/lib/CodeGen/SelectionDAG/SelectionDAGBuilder.h
@@ -429,6 +429,8 @@ class SelectionDAGBuilder {
// floor power of two.
SDValue lowerRangeToAssertZExt(SelectionDAG &DAG, const Instruction &I,
SDValue Op);
+ SDValue lowerRangeToAssertZExt(SelectionDAG &DAG,
+ std::optional CR, SDValue Op);
// Lower nofpclass attributes to AssertNoFPClass
SDValue lowerNoFPClassToAssertNoFPClass(SelectionDAG &DAG,
diff --git a/llvm/test/CodeGen/AMDGPU/bit-op-reduce-width-known-bits.ll
b/llvm/test/CodeGen/AMDGPU/bit-op-reduce-width-known-bits.ll
index ad26dfa7f93e8..a8be7e5827af0 100644
--- a/llvm/test/CodeGen/AMDGPU/bit-op-reduce-width-known-bits.ll
+++ b/llvm/test/CodeGen/AMDGPU/bit-op-reduce-width-known-bits.ll
@@ -11,7 +11,7 @@ define i64 @v_xor_i64_known_hi_i32_from_arg_range(i64
range(i64 0, 4294967296) %
; CHECK-LABEL: v_xor_i64_known_hi_i32_from_arg_range:
; CHECK: ; %bb.0:
; CHECK-NEXT:s_waitcnt vmcnt(0) expcnt(0) lgkmcnt(0)
-; CHECK-NEXT:v_xor_b32_e32 v1, v1, v3
+; CHECK-NEXT:v_mov_b32_e32 v1, v3
; CHECK-NEXT:v_xor_b32_e32 v0, v0, v2
; CHECK-NEXT:s_setpc_b64 s[30:31]
%xor = xor i64 %arg0, %arg1
@@ -24,7 +24,7 @@ define i64 @v_or_i64_known_hi_i32_from_arg_range(i64
range(i64 0, 4294967296) %a
; CHECK-LABEL: v_or_i64_known_hi_i32_from_arg_range:
; CHECK: ; %bb.0:
; CHECK-NEXT:s_waitcnt vmcnt(0) expcnt(0) lgkmcnt(0)
-; CHECK-NEXT:v_or_b32_e32 v1, v1, v3
+; CHECK-NEXT:v_mov_b32_e32 v1, v3
; CHECK-NEXT:v_or_b32_e32 v0, v0, v2
; CHECK-NEXT:s_setpc_b64 s[30:31]
%or = or i64 %arg0, %arg1
@@ -50,7 +50,7 @@ define i64 @s_xor_i64_known_i32_from_arg_range(i64 range(i64
0, 65) inreg %arg)
; CHECK-NEXT:s_waitcnt vmcnt(0) expcnt(0) lgkmcnt(0)
; CHECK-NEXT:s_not_b64 s[4:5], s[16:17]
; CHECK-NEXT:v_mov_b32_e32 v0, s4
-; CHECK-NEXT:v_mov_b32_e32 v1, s5
+; CHECK-NEXT:v_mov_b32_e32 v1, -1
; CHECK-NEXT:s_setpc_b64 s[30:31]
%xor = xor i64 %arg, -1
ret i64 %xor
diff --git a/llvm/test/CodeGen/X86/argument-range-attr.ll
b/llvm/test/CodeGen/X86/argument-range-attr.ll
new file mode 100644
index 0..9d684f7f596b2
--- /dev/null
+++ b/llvm/test/CodeGen/X86/argument-range-attr.ll
@@ -0,0 +1,121 @@
+; NOTE: Assertions have been autogenerated by utils/update_llc_test_checks.py
UTC_ARGS: --version 4
+; RUN: llc -mtriple=x86_64-unknown-linux-gnu < %s | FileCheck %s
+
+; range: 0..2^61
+; mask: 2^61 - 8
+define i64 @arg_range_top3(i64 range(i64 0, 2305843009213693952) %n) {
+; CHECK-LABEL: arg_range_top3:
+; CHECK: # %bb.0:
+; CHECK-NEXT:movq %rdi, %rax
+; CHECK-NEXT:andq $-8, %rax
+; CHECK-NEXT:retq
+ %r = and i64 %n, 2305843009213693944
+ ret i64 %r
+}
+
+; range: 0..256
+; mask: 0xF8 = 248
+define i64 @arg_range_byte(i
[llvm-branch-commits] [llvm] [SelectionDAG] Emit `AssertZext` for function argument range attributes (PR #196786)
el-ev wrote: > [!WARNING] > This pull request is not mergeable via GitHub because a downstack PR is > open. Once all requirements are satisfied, merge this PR as a stack href="https://app.graphite.com/github/pr/llvm/llvm-project/196786?utm_source=stack-comment-downstack-mergeability-warning"; > >on Graphite. > https://graphite.dev/docs/merge-pull-requests";>Learn more * **#196786** https://app.graphite.com/github/pr/llvm/llvm-project/196786?utm_source=stack-comment-icon"; target="_blank">https://static.graphite.dev/graphite-32x32-black.png"; alt="Graphite" width="10px" height="10px"/> 👈 https://app.graphite.com/github/pr/llvm/llvm-project/196786?utm_source=stack-comment-view-in-graphite"; target="_blank">(View in Graphite) * **#196785** https://app.graphite.com/github/pr/llvm/llvm-project/196785?utm_source=stack-comment-icon"; target="_blank">https://static.graphite.dev/graphite-32x32-black.png"; alt="Graphite" width="10px" height="10px"/> * **#196782** https://app.graphite.com/github/pr/llvm/llvm-project/196782?utm_source=stack-comment-icon"; target="_blank">https://static.graphite.dev/graphite-32x32-black.png"; alt="Graphite" width="10px" height="10px"/> * `main` This stack of pull requests is managed by https://graphite.dev?utm-source=stack-comment";>Graphite. Learn more about https://stacking.dev/?utm_source=stack-comment";>stacking. https://github.com/llvm/llvm-project/pull/196786 ___ llvm-branch-commits mailing list [email protected] https://lists.llvm.org/cgi-bin/mailman/listinfo/llvm-branch-commits
