Skip to content

[Test] Add and update tests for lrint/llrint (NFC) #152662

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Open
wants to merge 8 commits into
base: main
Choose a base branch
from

Conversation

tgross35
Copy link
Contributor

@tgross35 tgross35 commented Aug 8, 2025

Many backends are missing either all tests for lrint, or specifically those for f16, which currently crashes for softPromoteHalf targets. For a number of popular backends, do the following:

  • Ensure f16, f32, f64, and f128 are all covered
  • Ensure both a 32- and 64-bit target are tested, if relevant
  • Add nounwind to clean up CFI output
  • Add a test covering the above if one did not exist
  • Always specify the integer type in intrinsic calls

There are quite a few FIXMEs here, especially for f16, but much of this will be resolved in the near future.

@tgross35 tgross35 force-pushed the lrint-test-update branch from d7a8ac2 to 4b790f3 Compare August 8, 2025 08:30
@tgross35 tgross35 changed the title [Test] Add and update tests for lrint [Test] Add and update tests for lrint (NFC) Aug 8, 2025
@tgross35 tgross35 force-pushed the lrint-test-update branch 2 times, most recently from 603976e to e5afccf Compare August 8, 2025 09:03
@tgross35 tgross35 changed the title [Test] Add and update tests for lrint (NFC) [Test] Add and update tests for lrint/llrint (NFC) Aug 8, 2025
@tgross35 tgross35 force-pushed the lrint-test-update branch from e5afccf to 15ce4cf Compare August 8, 2025 09:08
@tgross35 tgross35 marked this pull request as ready for review August 8, 2025 09:12
@llvmbot
Copy link
Member

llvmbot commented Aug 8, 2025

@llvm/pr-subscribers-backend-aarch64
@llvm/pr-subscribers-backend-webassembly
@llvm/pr-subscribers-backend-loongarch
@llvm/pr-subscribers-backend-risc-v

@llvm/pr-subscribers-backend-x86

Author: Trevor Gross (tgross35)

Changes

Many backends are missing either all tests for lrint, or specifically those for f16, which currently crashes for softPromoteHalf targets. For a number of popular backends, do the following:

  • Ensure f16, f32, f64, and f128 are all covered
  • Ensure both a 32- and 64-bit target are tested, if relevant
  • Add nounwind to clean up CFI output
  • Add a test covering the above if one did not exist

There are quite a few FIXMEs here, especially for f16, but much of this will be resolved in the near future.


Patch is 34.46 KiB, truncated to 20.00 KiB below, full version: https://github.com/llvm/llvm-project/pull/152662.diff

16 Files Affected:

  • (modified) llvm/test/CodeGen/ARM/llrint-conv.ll (+21)
  • (modified) llvm/test/CodeGen/ARM/lrint-conv.ll (+18)
  • (modified) llvm/test/CodeGen/AVR/llrint.ll (+18)
  • (modified) llvm/test/CodeGen/AVR/lrint.ll (+18)
  • (added) llvm/test/CodeGen/LoongArch/lrint-conv.ll (+96)
  • (added) llvm/test/CodeGen/MSP430/lrint-conv.ll (+60)
  • (modified) llvm/test/CodeGen/Mips/llrint-conv.ll (+15)
  • (modified) llvm/test/CodeGen/Mips/lrint-conv.ll (+15)
  • (modified) llvm/test/CodeGen/PowerPC/llrint-conv.ll (+32)
  • (modified) llvm/test/CodeGen/PowerPC/lrint-conv.ll (+32)
  • (added) llvm/test/CodeGen/RISCV/lrint-conv.ll (+76)
  • (added) llvm/test/CodeGen/SPARC/lrint-conv.ll (+68)
  • (added) llvm/test/CodeGen/WebAssembly/lrint-conv.ll (+62)
  • (modified) llvm/test/CodeGen/X86/llrint-conv.ll (+97-31)
  • (modified) llvm/test/CodeGen/X86/lrint-conv-i32.ll (+65-9)
  • (modified) llvm/test/CodeGen/X86/lrint-conv-i64.ll (+30-4)
diff --git a/llvm/test/CodeGen/ARM/llrint-conv.ll b/llvm/test/CodeGen/ARM/llrint-conv.ll
index 017955bb43afb..f0fb2e7543be6 100644
--- a/llvm/test/CodeGen/ARM/llrint-conv.ll
+++ b/llvm/test/CodeGen/ARM/llrint-conv.ll
@@ -1,6 +1,16 @@
 ; RUN: llc < %s -mtriple=arm-eabi -float-abi=soft | FileCheck %s --check-prefix=SOFTFP
 ; RUN: llc < %s -mtriple=arm-eabi -float-abi=hard | FileCheck %s --check-prefix=HARDFP
 
+; SOFTFP-LABEL: testmsxh_builtin:
+; SOFTFP:       bl      llrintf
+; HARDFP-LABEL: testmsxh_builtin:
+; HARDFP:       bl      llrintf
+define i64 @testmsxh_builtin(half %x) {
+entry:
+  %0 = tail call i64 @llvm.llrint.f16(half %x)
+  ret i64 %0
+}
+
 ; SOFTFP-LABEL: testmsxs_builtin:
 ; SOFTFP:       bl      llrintf
 ; HARDFP-LABEL: testmsxs_builtin:
@@ -21,5 +31,16 @@ entry:
   ret i64 %0
 }
 
+; FIXME(#44744): incorrect libcall
+; SOFTFP-LABEL: testmsxq_builtin:
+; SOFTFP:       bl      llrintl
+; HARDFP-LABEL: testmsxq_builtin:
+; HARDFP:       bl      llrintl
+define i64 @testmsxq_builtin(fp128 %x) {
+entry:
+  %0 = tail call i64 @llvm.llrint.f128(fp128 %x)
+  ret i64 %0
+}
+
 declare i64 @llvm.llrint.f32(float) nounwind readnone
 declare i64 @llvm.llrint.f64(double) nounwind readnone
diff --git a/llvm/test/CodeGen/ARM/lrint-conv.ll b/llvm/test/CodeGen/ARM/lrint-conv.ll
index 192da565c12fd..9aa95112af533 100644
--- a/llvm/test/CodeGen/ARM/lrint-conv.ll
+++ b/llvm/test/CodeGen/ARM/lrint-conv.ll
@@ -1,6 +1,13 @@
 ; RUN: llc < %s -mtriple=arm-eabi -float-abi=soft | FileCheck %s --check-prefix=SOFTFP
 ; RUN: llc < %s -mtriple=arm-eabi -float-abi=hard | FileCheck %s --check-prefix=HARDFP
 
+; FIXME: crash
+; define i32 @testmswh_builtin(half %x) {
+; entry:
+;   %0 = tail call i32 @llvm.lrint.i32.f16(half %x)
+;   ret i32 %0
+; }
+
 ; SOFTFP-LABEL: testmsws_builtin:
 ; SOFTFP:       bl      lrintf
 ; HARDFP-LABEL: testmsws_builtin:
@@ -21,5 +28,16 @@ entry:
   ret i32 %0
 }
 
+; FIXME(#44744): incorrect libcall
+; SOFTFP-LABEL: testmswq_builtin:
+; SOFTFP:       bl      lrintl
+; HARDFP-LABEL: testmswq_builtin:
+; HARDFP:       bl      lrintl
+define i32 @testmswq_builtin(fp128 %x) {
+entry:
+  %0 = tail call i32 @llvm.lrint.i32.f128(fp128 %x)
+  ret i32 %0
+}
+
 declare i32 @llvm.lrint.i32.f32(float) nounwind readnone
 declare i32 @llvm.lrint.i32.f64(double) nounwind readnone
diff --git a/llvm/test/CodeGen/AVR/llrint.ll b/llvm/test/CodeGen/AVR/llrint.ll
index 32b4c7ab12a4b..0aefb92758260 100644
--- a/llvm/test/CodeGen/AVR/llrint.ll
+++ b/llvm/test/CodeGen/AVR/llrint.ll
@@ -1,6 +1,13 @@
 ; NOTE: Assertions have been autogenerated by utils/update_llc_test_checks.py
 ; RUN: llc < %s -mtriple=avr -mcpu=atmega328p | FileCheck %s
 
+; FIXME: crash
+; define i64 @testmsxh_builtin(half %x) {
+; entry:
+;   %0 = tail call i64 @llvm.llrint.f16(half %x)
+;   ret i64 %0
+; }
+
 define i64 @testmsxs_builtin(float %x) {
 ; CHECK-LABEL: testmsxs_builtin:
 ; CHECK:       ; %bb.0: ; %entry
@@ -21,5 +28,16 @@ entry:
   ret i64 %0
 }
 
+; FIXME(#44744): incorrect libcall
+define i64 @testmsxq_builtin(fp128 %x) {
+; CHECK-LABEL: testmsxq_builtin:
+; CHECK:       ; %bb.0: ; %entry
+; CHECK-NEXT:    call llrintl
+; CHECK-NEXT:    ret
+entry:
+  %0 = tail call i64 @llvm.llrint.fp128(fp128 %x)
+  ret i64 %0
+}
+
 declare i64 @llvm.llrint.f32(float) nounwind readnone
 declare i64 @llvm.llrint.f64(double) nounwind readnone
diff --git a/llvm/test/CodeGen/AVR/lrint.ll b/llvm/test/CodeGen/AVR/lrint.ll
index d7568305f7b51..87dc2df311567 100644
--- a/llvm/test/CodeGen/AVR/lrint.ll
+++ b/llvm/test/CodeGen/AVR/lrint.ll
@@ -1,6 +1,13 @@
 ; NOTE: Assertions have been autogenerated by utils/update_llc_test_checks.py
 ; RUN: llc < %s -mtriple=avr -mcpu=atmega328p | FileCheck %s
 
+; FIXME: crash
+; define i32 @testmswh_builtin(half %x) {
+; entry:
+;   %0 = tail call i32 @llvm.lrint.i32.f16(half %x)
+;   ret i32 %0
+; }
+
 define i32 @testmsws_builtin(float %x) {
 ; CHECK-LABEL: testmsws_builtin:
 ; CHECK:       ; %bb.0: ; %entry
@@ -21,5 +28,16 @@ entry:
   ret i32 %0
 }
 
+; FIXME(#44744): incorrect libcall
+define i32 @testmswq_builtin(fp128 %x) {
+; CHECK-LABEL: testmswq_builtin:
+; CHECK:       ; %bb.0: ; %entry
+; CHECK-NEXT:    call lrint
+; CHECK-NEXT:    ret
+entry:
+  %0 = tail call i32 @llvm.lrint.i32.fp128(fp128 %x)
+  ret i32 %0
+}
+
 declare i32 @llvm.lrint.i32.f32(float) nounwind readnone
 declare i32 @llvm.lrint.i32.f64(double) nounwind readnone
diff --git a/llvm/test/CodeGen/LoongArch/lrint-conv.ll b/llvm/test/CodeGen/LoongArch/lrint-conv.ll
new file mode 100644
index 0000000000000..85de820025614
--- /dev/null
+++ b/llvm/test/CodeGen/LoongArch/lrint-conv.ll
@@ -0,0 +1,96 @@
+; Tests for lrint and llrint, with both i32 and i64 checked.
+
+; RUN: sed 's/ITy/i32/g' %s | llc -mtriple=loongarch32 | FileCheck %s --check-prefixes=LA32
+; RUN: sed 's/ITy/i64/g' %s | llc -mtriple=loongarch32 | FileCheck %s --check-prefixes=LA32
+; RUN: sed 's/ITy/i32/g' %s | llc -mtriple=loongarch64 | FileCheck %s --check-prefixes=LA64-I32
+; RUN: sed 's/ITy/i64/g' %s | llc -mtriple=loongarch64 | FileCheck %s --check-prefixes=LA64-I64
+
+; FIXME: crash
+; define ITy @test_lrint_ixx_f16(half %x) nounwind {
+;   %res = tail call ITy @llvm.lrint.ITy.f16(half %x)
+;   ret ITy %res
+; }
+
+; define ITy @test_llrint_ixx_f16(half %x) nounwind {
+;   %res = tail call ITy @llvm.llrint.ITy.f16(half %x)
+;   ret ITy %res
+; }
+
+define ITy @test_lrint_ixx_f32(float %x) nounwind {
+; LA32-LABEL: test_lrint_ixx_f32:
+; LA32:         bl lrintf
+;
+; LA64-I32-LABEL: test_lrint_ixx_f32:
+; LA64-I32:         pcaddu18i $ra, %call36(lrintf)
+;
+; LA64-I64-LABEL: test_lrint_ixx_f32:
+; LA64-I64:         pcaddu18i $t8, %call36(lrintf)
+  %res = tail call ITy @llvm.lrint.ITy.f32(float %x)
+  ret ITy %res
+}
+
+define ITy @test_llrint_ixx_f32(float %x) nounwind {
+; LA32-LABEL: test_llrint_ixx_f32:
+; LA32:         bl llrintf
+;
+; LA64-I32-LABEL: test_llrint_ixx_f32:
+; LA64-I32:         pcaddu18i $ra, %call36(llrintf)
+;
+; LA64-I64-LABEL: test_llrint_ixx_f32:
+; LA64-I64:         pcaddu18i $t8, %call36(llrintf)
+  %res = tail call ITy @llvm.llrint.ITy.f32(float %x)
+  ret ITy %res
+}
+
+define ITy @test_lrint_ixx_f64(double %x) nounwind {
+; LA32-LABEL: test_lrint_ixx_f64:
+; LA32:         bl lrint
+;
+; LA64-I32-LABEL: test_lrint_ixx_f64:
+; LA64-I32:         pcaddu18i $ra, %call36(lrint)
+;
+; LA64-I64-LABEL: test_lrint_ixx_f64:
+; LA64-I64:         pcaddu18i $t8, %call36(lrint)
+  %res = tail call ITy @llvm.lrint.ITy.f64(double %x)
+  ret ITy %res
+}
+
+define ITy @test_llrint_ixx_f64(double %x) nounwind {
+; LA32-LABEL: test_llrint_ixx_f64:
+; LA32:         bl llrint
+;
+; LA64-I32-LABEL: test_llrint_ixx_f64:
+; LA64-I32:         pcaddu18i $ra, %call36(llrint)
+;
+; LA64-I64-LABEL: test_llrint_ixx_f64:
+; LA64-I64:         pcaddu18i $t8, %call36(llrint)
+  %res = tail call ITy @llvm.llrint.ITy.f64(double %x)
+  ret ITy %res
+}
+
+; FIXME(#44744): incorrect libcall on loongarch32
+define ITy @test_lrint_ixx_f128(fp128 %x) nounwind {
+; LA32-LABEL: test_lrint_ixx_f128:
+; LA32:         bl lrintl
+;
+; LA64-I32-LABEL: test_lrint_ixx_f128:
+; LA64-I32:         pcaddu18i $ra, %call36(lrintl)
+;
+; LA64-I64-LABEL: test_lrint_ixx_f128:
+; LA64-I64:         pcaddu18i $ra, %call36(lrintl)
+  %res = tail call ITy @llvm.lrint.ITy.f128(fp128 %x)
+  ret ITy %res
+}
+
+define ITy @test_llrint_ixx_f128(fp128 %x) nounwind {
+; LA32-LABEL: test_llrint_ixx_f128:
+; LA32:         bl llrintl
+;
+; LA64-I32-LABEL: test_llrint_ixx_f128:
+; LA64-I32:         pcaddu18i $ra, %call36(llrintl)
+;
+; LA64-I64-LABEL: test_llrint_ixx_f128:
+; LA64-I64:         pcaddu18i $ra, %call36(llrintl)
+  %res = tail call ITy @llvm.llrint.ITy.f128(fp128 %x)
+  ret ITy %res
+}
diff --git a/llvm/test/CodeGen/MSP430/lrint-conv.ll b/llvm/test/CodeGen/MSP430/lrint-conv.ll
new file mode 100644
index 0000000000000..7eee951893d3e
--- /dev/null
+++ b/llvm/test/CodeGen/MSP430/lrint-conv.ll
@@ -0,0 +1,60 @@
+; NOTE: Assertions have been autogenerated by utils/update_llc_test_checks.py
+
+; Tests for lrint and llrint, with both i32 and i64 checked.
+
+; RUN: sed 's/ITy/i32/g' %s | llc -mtriple=msp430-unknown-unknown | FileCheck %s --check-prefixes=CHECK
+; RUN: sed 's/ITy/i64/g' %s | llc -mtriple=msp430-unknown-unknown | FileCheck %s --check-prefixes=CHECK
+
+; FIXME: crash
+; define ITy @test_lrint_ixx_f16(half %x) nounwind {
+;   %res = tail call ITy @llvm.lrint.ITy.f16(half %x)
+;   ret ITy %res
+; }
+
+; define ITy @test_llrint_ixx_f16(half %x) nounwind {
+;   %res = tail call ITy @llvm.llrint.ITy.f16(half %x)
+;   ret ITy %res
+; }
+
+define ITy @test_lrint_ixx_f32(float %x) nounwind {
+; CHECK-LABEL: test_lrint_ixx_f32:
+; CHECK:         call #lrintf
+  %res = tail call ITy @llvm.lrint.ITy.f32(float %x)
+  ret ITy %res
+}
+
+define ITy @test_llrint_ixx_f32(float %x) nounwind {
+; CHECK-LABEL: test_llrint_ixx_f32:
+; CHECK:         call #llrintf
+  %res = tail call ITy @llvm.llrint.ITy.f32(float %x)
+  ret ITy %res
+}
+
+define ITy @test_lrint_ixx_f64(double %x) nounwind {
+; CHECK-LABEL: test_lrint_ixx_f64:
+; CHECK:         call #lrint
+  %res = tail call ITy @llvm.lrint.ITy.f64(double %x)
+  ret ITy %res
+}
+
+define ITy @test_llrint_ixx_f64(double %x) nounwind {
+; CHECK-LABEL: test_llrint_ixx_f64:
+; CHECK:         call #llrint
+  %res = tail call ITy @llvm.llrint.ITy.f64(double %x)
+  ret ITy %res
+}
+
+; FIXME(#44744): incorrect libcall
+define ITy @test_lrint_ixx_f128(fp128 %x) nounwind {
+; CHECK-LABEL: test_lrint_ixx_f128:
+; CHECK:         call #lrintl
+  %res = tail call ITy @llvm.lrint.ITy.f128(fp128 %x)
+  ret ITy %res
+}
+
+define ITy @test_llrint_ixx_f128(fp128 %x) nounwind {
+; CHECK-LABEL: test_llrint_ixx_f128:
+; CHECK:         call #llrintl
+  %res = tail call ITy @llvm.llrint.ITy.f128(fp128 %x)
+  ret ITy %res
+}
diff --git a/llvm/test/CodeGen/Mips/llrint-conv.ll b/llvm/test/CodeGen/Mips/llrint-conv.ll
index dcb4e5657e80b..ee3c0d99253a6 100644
--- a/llvm/test/CodeGen/Mips/llrint-conv.ll
+++ b/llvm/test/CodeGen/Mips/llrint-conv.ll
@@ -1,4 +1,19 @@
 ; RUN: llc < %s -mtriple=mips64el -mattr=+soft-float | FileCheck %s
+; RUN: llc < %s -mtriple=mips -mattr=+soft-float     | FileCheck %s
+
+; FIXME: crash
+; define signext i32 @testmswh(half %x) {
+; entry:
+;   %0 = tail call i64 @llvm.llrint.f16(half %x)
+;   %conv = trunc i64 %0 to i32
+;   ret i32 %conv
+; }
+
+; define i64 @testmsxh(half %x) {
+; entry:
+;   %0 = tail call i64 @llvm.llrint.f16(half %x)
+;   ret i64 %0
+; }
 
 define signext i32 @testmsws(float %x) {
 ; CHECK-LABEL: testmsws:
diff --git a/llvm/test/CodeGen/Mips/lrint-conv.ll b/llvm/test/CodeGen/Mips/lrint-conv.ll
index bd3f7b3babe10..6d2e392675f1c 100644
--- a/llvm/test/CodeGen/Mips/lrint-conv.ll
+++ b/llvm/test/CodeGen/Mips/lrint-conv.ll
@@ -1,4 +1,19 @@
 ; RUN: llc < %s -mtriple=mips64el -mattr=+soft-float | FileCheck %s
+; RUN: llc < %s -mtriple=mips -mattr=+soft-float     | FileCheck %s
+
+; FIXME: crash
+; define signext i32 @testmswh(half %x) {
+; entry:
+;   %0 = tail call i64 @llvm.lrint.i64.f16(half %x)
+;   %conv = trunc i64 %0 to i32
+;   ret i32 %conv
+; }
+
+; define i64 @testmsxh(half %x) {
+; entry:
+;   %0 = tail call i64 @llvm.lrint.i64.f16(half %x)
+;   ret i64 %0
+; }
 
 define signext i32 @testmsws(float %x) {
 ; CHECK-LABEL: testmsws:
diff --git a/llvm/test/CodeGen/PowerPC/llrint-conv.ll b/llvm/test/CodeGen/PowerPC/llrint-conv.ll
index daadf85b4085a..ff41a53464d8c 100644
--- a/llvm/test/CodeGen/PowerPC/llrint-conv.ll
+++ b/llvm/test/CodeGen/PowerPC/llrint-conv.ll
@@ -1,4 +1,19 @@
 ; RUN: llc < %s -mtriple=powerpc64le | FileCheck %s
+; RUN: llc < %s -mtriple=powerpc | FileCheck %s
+
+; FIXME: crash
+; define signext i32 @testmswh(half %x) {
+; entry:
+;   %0 = tail call i64 @llvm.llrint.f16(half %x)
+;   %conv = trunc i64 %0 to i32
+;   ret i32 %conv
+; }
+
+; define i64 @testmsxh(half %x) {
+; entry:
+;   %0 = tail call i64 @llvm.llrint.f16(half %x)
+;   ret i64 %0
+; }
 
 ; CHECK-LABEL: testmsws:
 ; CHECK:       bl      llrintf
@@ -51,6 +66,23 @@ entry:
   ret i64 %0
 }
 
+; CHECK-LABEL: testmswq:
+; CHECK:       bl      llrintf128
+define signext i32 @testmswq(fp128 %x) {
+entry:
+  %0 = tail call i64 @llvm.llrint.f128(fp128 %x)
+  %conv = trunc i64 %0 to i32
+  ret i32 %conv
+}
+
+; CHECK-LABEL: testmslq:
+; CHECK:       bl      llrintf128
+define i64 @testmslq(fp128 %x) {
+entry:
+  %0 = tail call i64 @llvm.llrint.f128(fp128 %x)
+  ret i64 %0
+}
+
 declare i64 @llvm.llrint.f32(float) nounwind readnone
 declare i64 @llvm.llrint.f64(double) nounwind readnone
 declare i64 @llvm.llrint.ppcf128(ppc_fp128) nounwind readnone
diff --git a/llvm/test/CodeGen/PowerPC/lrint-conv.ll b/llvm/test/CodeGen/PowerPC/lrint-conv.ll
index adfc994497323..7b1a9d6a9fc77 100644
--- a/llvm/test/CodeGen/PowerPC/lrint-conv.ll
+++ b/llvm/test/CodeGen/PowerPC/lrint-conv.ll
@@ -1,4 +1,19 @@
 ; RUN: llc < %s -mtriple=powerpc64le | FileCheck %s
+; RUN: llc < %s -mtriple=powerpc | FileCheck %s
+
+; FIXME: crash
+; define signext i32 @testmswh(half %x) {
+; entry:
+;   %0 = tail call i64 @llvm.lrint.i64.f16(half %x)
+;   %conv = trunc i64 %0 to i32
+;   ret i32 %conv
+; }
+
+; define i64 @testmsxh(half %x) {
+; entry:
+;   %0 = tail call i64 @llvm.lrint.i64.f16(half %x)
+;   ret i64 %0
+; }
 
 ; CHECK-LABEL: testmsws:
 ; CHECK:       bl      lrintf
@@ -51,6 +66,23 @@ entry:
   ret i64 %0
 }
 
+; CHECK-LABEL: testmswq:
+; CHECK:       bl      lrintf128
+define signext i32 @testmswq(fp128 %x) {
+entry:
+  %0 = tail call i64 @llvm.lrint.i64.f128(fp128 %x)
+  %conv = trunc i64 %0 to i32
+  ret i32 %conv
+}
+
+; CHECK-LABEL: testmslq:
+; CHECK:       bl      lrintf128
+define i64 @testmslq(fp128 %x) {
+entry:
+  %0 = tail call i64 @llvm.lrint.i64.f128(fp128 %x)
+  ret i64 %0
+}
+
 declare i64 @llvm.lrint.i64.f32(float) nounwind readnone
 declare i64 @llvm.lrint.i64.f64(double) nounwind readnone
 declare i64 @llvm.lrint.i64.ppcf128(ppc_fp128) nounwind readnone
diff --git a/llvm/test/CodeGen/RISCV/lrint-conv.ll b/llvm/test/CodeGen/RISCV/lrint-conv.ll
new file mode 100644
index 0000000000000..d3af2153588a1
--- /dev/null
+++ b/llvm/test/CodeGen/RISCV/lrint-conv.ll
@@ -0,0 +1,76 @@
+; Tests for lrint and llrint, with both i32 and i64 checked.
+
+; RUN: sed 's/ITy/i32/g' %s | llc -mtriple=riscv32 | FileCheck %s --check-prefixes=RV32
+; RUN: sed 's/ITy/i64/g' %s | llc -mtriple=riscv32 | FileCheck %s --check-prefixes=RV32
+; RUN: sed 's/ITy/i32/g' %s | llc -mtriple=riscv64 | FileCheck %s --check-prefixes=RV64
+; RUN: sed 's/ITy/i64/g' %s | llc -mtriple=riscv64 | FileCheck %s --check-prefixes=RV64
+
+; FIXME: crash
+; define ITy @test_lrint_ixx_f16(half %x) nounwind {
+;   %res = tail call ITy @llvm.lrint.ITy.f16(half %x)
+; }
+
+; define ITy @test_llrint_ixx_f16(half %x) nounwind {
+;   %res = tail call ITy @llvm.llrint.ITy.f16(half %x)
+; }
+
+define ITy @test_lrint_ixx_f32(float %x) nounwind {
+; RV32-LABEL: test_lrint_ixx_f32:
+; RV32:         call lrintf
+;
+; RV64-LABEL: test_lrint_ixx_f32:
+; RV64:         call lrintf
+  %res = tail call ITy @llvm.lrint.ITy.f32(float %x)
+  ret ITy %res
+}
+
+define ITy @test_llrint_ixx_f32(float %x) nounwind {
+; RV32-LABEL: test_llrint_ixx_f32:
+; RV32:         call llrintf
+;
+; RV64-LABEL: test_llrint_ixx_f32:
+; RV64:         call llrintf
+  %res = tail call ITy @llvm.llrint.ITy.f32(float %x)
+  ret ITy %res
+}
+
+define ITy @test_lrint_ixx_f64(double %x) nounwind {
+; RV32-LABEL: test_lrint_ixx_f64:
+; RV32:         call lrint
+;
+; RV64-LABEL: test_lrint_ixx_f64:
+; RV64:         call lrint
+  %res = tail call ITy @llvm.lrint.ITy.f64(double %x)
+  ret ITy %res
+}
+
+define ITy @test_llrint_ixx_f64(double %x) nounwind {
+; RV32-LABEL: test_llrint_ixx_f64:
+; RV32:         call llrint
+;
+; RV64-LABEL: test_llrint_ixx_f64:
+; RV64:         call llrint
+  %res = tail call ITy @llvm.llrint.ITy.f64(double %x)
+  ret ITy %res
+}
+
+; FIXME(#44744): incorrect libcall on riscv32
+define ITy @test_lrint_ixx_f128(fp128 %x) nounwind {
+; RV32-LABEL: test_lrint_ixx_f128:
+; RV32:         call lrintl
+;
+; RV64-LABEL: test_lrint_ixx_f128:
+; RV64:         call lrintl
+  %res = tail call ITy @llvm.lrint.ITy.f128(fp128 %x)
+  ret ITy %res
+}
+
+define ITy @test_llrint_ixx_f128(fp128 %x) nounwind {
+; RV32-LABEL: test_llrint_ixx_f128:
+; RV32:         call llrintl
+;
+; RV64-LABEL: test_llrint_ixx_f128:
+; RV64:         call llrintl
+  %res = tail call ITy @llvm.llrint.ITy.f128(fp128 %x)
+  ret ITy %res
+}
diff --git a/llvm/test/CodeGen/SPARC/lrint-conv.ll b/llvm/test/CodeGen/SPARC/lrint-conv.ll
new file mode 100644
index 0000000000000..81d541a056875
--- /dev/null
+++ b/llvm/test/CodeGen/SPARC/lrint-conv.ll
@@ -0,0 +1,68 @@
+; Tests for lrint and llrint, with both i32 and i64 checked.
+
+; RUN: sed 's/ITy/i32/g' %s | llc -mtriple=sparc   | FileCheck %s --check-prefixes=SPARC32
+; RUN: sed 's/ITy/i64/g' %s | llc -mtriple=sparc   | FileCheck %s --check-prefixes=SPARC32
+; RUN: sed 's/ITy/i32/g' %s | llc -mtriple=sparc64 | FileCheck %s --check-prefixes=SPARC64
+; RUN: sed 's/ITy/i64/g' %s | llc -mtriple=sparc64 | FileCheck %s --check-prefixes=SPARC64
+
+; FIXME: crash
+; define ITy @test_lrint_ixx_f16(half %x) nounwind {
+;   %res = tail call ITy @llvm.lrint.ITy.f16(half %x)
+;   ret ITy %res
+; }
+
+; define ITy @test_llrint_ixx_f16(half %x) nounwind {
+;   %res = tail call ITy @llvm.llrint.ITy.f16(half %x)
+;   ret ITy %res
+; }
+
+define ITy @test_lrint_ixx_f32(float %x) nounwind {
+; SPARC32-LABEL: test_lrint_ixx_f32:
+; SPARC32:         call lrintf
+;
+; SPARC64-LABEL: test_lrint_ixx_f32:
+; SPARC64:         call lrintf
+  %res = tail call ITy @llvm.lrint.ITy.f32(float %x)
+  ret ITy %res
+}
+
+define ITy @test_llrint_ixx_f32(float %x) nounwind {
+; SPARC32-LABEL: test_llrint_ixx_f32:
+; SPARC32:         call llrintf
+;
+; SPARC64-LABEL: test_llrint_ixx_f32:
+; SPARC64:         call llrintf
+  %res = tail call ITy @llvm.llrint.ITy.f32(float %x)
+  ret ITy %res
+}
+
+define ITy @test_lrint_ixx_f64(double %x) nounwind {
+; SPARC32-LABEL: test_lrint_ixx_f64:
+; SPARC32:         call lrint
+;
+; SPARC64-LABEL: test_lrint_ixx_f64:
+; SPARC64:         call lrint
+  %res = tail call ITy @llvm.lrint.ITy.f64(double %x)
+  ret ITy %res
+}
+
+define ITy @test_llrint_ixx_f64(double %x) nounwind {
+; SPARC32-LABEL: test_llrint_ixx_f64:
+; SPARC32:         call llrint
+;
+; SPARC64-LABEL: test_llrint_ixx_f64:
+; SPARC64:         call llrint
+  %res = tail call ITy @llvm.llrint.ITy.f64(double %x)
+  ret ITy %res
+}
+
+; FIXME(#41838): unsupported type
+; define ITy @test_lrint_ixx_f128(fp128 %x) nounwind {
+;   %res = tail call ITy @llvm.lrint.ITy.f128(fp128 %x)
+;   ret ITy %res
+; }
+
+; define ITy @test_llrint_ixx_f128(fp128 %x) nounwind {
+;   %res = tail call ITy @llvm.llrint.ITy.f128(fp128 %x)
+;   ret ITy %res
+; }
diff --git a/llvm/test/CodeGen/WebAssembly/lrint-conv.ll b/llvm/test/CodeGen/WebAssembly/lrint-conv.ll
new file mode 100644
index 0000000000000..0571150cb3505
--- /dev/null
+++ b/llvm/test/CodeGen/WebAssembly/lrint-conv.ll
@@ -0,0 +1,62 @@
+; NOTE: Assertions have been autogenerated by utils/update_llc_test_checks.py
+
+; Tests for lrint and llrint, with both i32 and i64 checked.
+
+; RUN: sed 's/ITy/i32/g' %s | llc -mtriple=wasm32-unknown-unknown | FileCheck %s
+; RUN: sed 's/ITy/i64/g' %s | llc -mtriple=wasm32-unknown-unknown | FileCheck %s
+
+define ITy @test_lrint_ixx_f16(half %x) nounwind {
+; CHECK-LABEL: test_lrint_ixx_f16:
+; CHECK:         call lrintf
+  %res = tail call ITy @llvm.lrint.ITy.f16(half %x)
+  ret ITy %res
+}
+
+define ITy @test_llrint_ixx_f16(half %x) nounwind {
+; CHECK-LABEL: test_llrint_ixx_f16:
+; CHECK:         call llrintf
+  %res = tail call ITy @llvm.llrint.ITy.f16(half %x)
+  ret ITy %res
+}
+
+define ITy @test_lrint_ixx_f32(float %x) nounwind {
+; CHECK-LABEL: test_lrint_ixx_f32:
+; CHECK:         call lrintf
+  %res = tail call ITy @llvm.lrint.ITy.f32(float %x)
+  ret ITy %res
+}
+
+define ITy @test_llrint_ixx_f32(float %x) nounwind {
+; CHECK-LABEL: test_llrint_ixx_f32:
+; CHECK:         call llrintf
+  %res = tail call ITy @llvm.llrint.ITy.f32(float %x)
+  ret ITy %res
+}
+
+define ITy @test_lrint_ixx_f64(double %x) nounwind {
+; CHECK-LABEL: test_lrint_ixx_f64:
+; CHECK:         call lrint
+  %res = tail call ITy @llvm.lrint.ITy.f64(double %x)
+  ret ITy %res
+}
+
+define ITy @test_llrint_ixx_f64(double %x) nounwind {
+; CHECK-LABEL: test_llrint_ixx_f64:
+; CHECK:         call llrint
+  %res = tail cal...
[truncated]

@llvmbot
Copy link
Member

llvmbot commented Aug 8, 2025

@llvm/pr-subscribers-backend-arm

Author: Trevor Gross (tgross35)

Changes

Many backends are missing either all tests for lrint, or specifically those for f16, which currently crashes for softPromoteHalf targets. For a number of popular backends, do the following:

  • Ensure f16, f32, f64, and f128 are all covered
  • Ensure both a 32- and 64-bit target are tested, if relevant
  • Add nounwind to clean up CFI output
  • Add a test covering the above if one did not exist

There are quite a few FIXMEs here, especially for f16, but much of this will be resolved in the near future.


Patch is 34.46 KiB, truncated to 20.00 KiB below, full version: https://github.com/llvm/llvm-project/pull/152662.diff

16 Files Affected:

  • (modified) llvm/test/CodeGen/ARM/llrint-conv.ll (+21)
  • (modified) llvm/test/CodeGen/ARM/lrint-conv.ll (+18)
  • (modified) llvm/test/CodeGen/AVR/llrint.ll (+18)
  • (modified) llvm/test/CodeGen/AVR/lrint.ll (+18)
  • (added) llvm/test/CodeGen/LoongArch/lrint-conv.ll (+96)
  • (added) llvm/test/CodeGen/MSP430/lrint-conv.ll (+60)
  • (modified) llvm/test/CodeGen/Mips/llrint-conv.ll (+15)
  • (modified) llvm/test/CodeGen/Mips/lrint-conv.ll (+15)
  • (modified) llvm/test/CodeGen/PowerPC/llrint-conv.ll (+32)
  • (modified) llvm/test/CodeGen/PowerPC/lrint-conv.ll (+32)
  • (added) llvm/test/CodeGen/RISCV/lrint-conv.ll (+76)
  • (added) llvm/test/CodeGen/SPARC/lrint-conv.ll (+68)
  • (added) llvm/test/CodeGen/WebAssembly/lrint-conv.ll (+62)
  • (modified) llvm/test/CodeGen/X86/llrint-conv.ll (+97-31)
  • (modified) llvm/test/CodeGen/X86/lrint-conv-i32.ll (+65-9)
  • (modified) llvm/test/CodeGen/X86/lrint-conv-i64.ll (+30-4)
diff --git a/llvm/test/CodeGen/ARM/llrint-conv.ll b/llvm/test/CodeGen/ARM/llrint-conv.ll
index 017955bb43afb..f0fb2e7543be6 100644
--- a/llvm/test/CodeGen/ARM/llrint-conv.ll
+++ b/llvm/test/CodeGen/ARM/llrint-conv.ll
@@ -1,6 +1,16 @@
 ; RUN: llc < %s -mtriple=arm-eabi -float-abi=soft | FileCheck %s --check-prefix=SOFTFP
 ; RUN: llc < %s -mtriple=arm-eabi -float-abi=hard | FileCheck %s --check-prefix=HARDFP
 
+; SOFTFP-LABEL: testmsxh_builtin:
+; SOFTFP:       bl      llrintf
+; HARDFP-LABEL: testmsxh_builtin:
+; HARDFP:       bl      llrintf
+define i64 @testmsxh_builtin(half %x) {
+entry:
+  %0 = tail call i64 @llvm.llrint.f16(half %x)
+  ret i64 %0
+}
+
 ; SOFTFP-LABEL: testmsxs_builtin:
 ; SOFTFP:       bl      llrintf
 ; HARDFP-LABEL: testmsxs_builtin:
@@ -21,5 +31,16 @@ entry:
   ret i64 %0
 }
 
+; FIXME(#44744): incorrect libcall
+; SOFTFP-LABEL: testmsxq_builtin:
+; SOFTFP:       bl      llrintl
+; HARDFP-LABEL: testmsxq_builtin:
+; HARDFP:       bl      llrintl
+define i64 @testmsxq_builtin(fp128 %x) {
+entry:
+  %0 = tail call i64 @llvm.llrint.f128(fp128 %x)
+  ret i64 %0
+}
+
 declare i64 @llvm.llrint.f32(float) nounwind readnone
 declare i64 @llvm.llrint.f64(double) nounwind readnone
diff --git a/llvm/test/CodeGen/ARM/lrint-conv.ll b/llvm/test/CodeGen/ARM/lrint-conv.ll
index 192da565c12fd..9aa95112af533 100644
--- a/llvm/test/CodeGen/ARM/lrint-conv.ll
+++ b/llvm/test/CodeGen/ARM/lrint-conv.ll
@@ -1,6 +1,13 @@
 ; RUN: llc < %s -mtriple=arm-eabi -float-abi=soft | FileCheck %s --check-prefix=SOFTFP
 ; RUN: llc < %s -mtriple=arm-eabi -float-abi=hard | FileCheck %s --check-prefix=HARDFP
 
+; FIXME: crash
+; define i32 @testmswh_builtin(half %x) {
+; entry:
+;   %0 = tail call i32 @llvm.lrint.i32.f16(half %x)
+;   ret i32 %0
+; }
+
 ; SOFTFP-LABEL: testmsws_builtin:
 ; SOFTFP:       bl      lrintf
 ; HARDFP-LABEL: testmsws_builtin:
@@ -21,5 +28,16 @@ entry:
   ret i32 %0
 }
 
+; FIXME(#44744): incorrect libcall
+; SOFTFP-LABEL: testmswq_builtin:
+; SOFTFP:       bl      lrintl
+; HARDFP-LABEL: testmswq_builtin:
+; HARDFP:       bl      lrintl
+define i32 @testmswq_builtin(fp128 %x) {
+entry:
+  %0 = tail call i32 @llvm.lrint.i32.f128(fp128 %x)
+  ret i32 %0
+}
+
 declare i32 @llvm.lrint.i32.f32(float) nounwind readnone
 declare i32 @llvm.lrint.i32.f64(double) nounwind readnone
diff --git a/llvm/test/CodeGen/AVR/llrint.ll b/llvm/test/CodeGen/AVR/llrint.ll
index 32b4c7ab12a4b..0aefb92758260 100644
--- a/llvm/test/CodeGen/AVR/llrint.ll
+++ b/llvm/test/CodeGen/AVR/llrint.ll
@@ -1,6 +1,13 @@
 ; NOTE: Assertions have been autogenerated by utils/update_llc_test_checks.py
 ; RUN: llc < %s -mtriple=avr -mcpu=atmega328p | FileCheck %s
 
+; FIXME: crash
+; define i64 @testmsxh_builtin(half %x) {
+; entry:
+;   %0 = tail call i64 @llvm.llrint.f16(half %x)
+;   ret i64 %0
+; }
+
 define i64 @testmsxs_builtin(float %x) {
 ; CHECK-LABEL: testmsxs_builtin:
 ; CHECK:       ; %bb.0: ; %entry
@@ -21,5 +28,16 @@ entry:
   ret i64 %0
 }
 
+; FIXME(#44744): incorrect libcall
+define i64 @testmsxq_builtin(fp128 %x) {
+; CHECK-LABEL: testmsxq_builtin:
+; CHECK:       ; %bb.0: ; %entry
+; CHECK-NEXT:    call llrintl
+; CHECK-NEXT:    ret
+entry:
+  %0 = tail call i64 @llvm.llrint.fp128(fp128 %x)
+  ret i64 %0
+}
+
 declare i64 @llvm.llrint.f32(float) nounwind readnone
 declare i64 @llvm.llrint.f64(double) nounwind readnone
diff --git a/llvm/test/CodeGen/AVR/lrint.ll b/llvm/test/CodeGen/AVR/lrint.ll
index d7568305f7b51..87dc2df311567 100644
--- a/llvm/test/CodeGen/AVR/lrint.ll
+++ b/llvm/test/CodeGen/AVR/lrint.ll
@@ -1,6 +1,13 @@
 ; NOTE: Assertions have been autogenerated by utils/update_llc_test_checks.py
 ; RUN: llc < %s -mtriple=avr -mcpu=atmega328p | FileCheck %s
 
+; FIXME: crash
+; define i32 @testmswh_builtin(half %x) {
+; entry:
+;   %0 = tail call i32 @llvm.lrint.i32.f16(half %x)
+;   ret i32 %0
+; }
+
 define i32 @testmsws_builtin(float %x) {
 ; CHECK-LABEL: testmsws_builtin:
 ; CHECK:       ; %bb.0: ; %entry
@@ -21,5 +28,16 @@ entry:
   ret i32 %0
 }
 
+; FIXME(#44744): incorrect libcall
+define i32 @testmswq_builtin(fp128 %x) {
+; CHECK-LABEL: testmswq_builtin:
+; CHECK:       ; %bb.0: ; %entry
+; CHECK-NEXT:    call lrint
+; CHECK-NEXT:    ret
+entry:
+  %0 = tail call i32 @llvm.lrint.i32.fp128(fp128 %x)
+  ret i32 %0
+}
+
 declare i32 @llvm.lrint.i32.f32(float) nounwind readnone
 declare i32 @llvm.lrint.i32.f64(double) nounwind readnone
diff --git a/llvm/test/CodeGen/LoongArch/lrint-conv.ll b/llvm/test/CodeGen/LoongArch/lrint-conv.ll
new file mode 100644
index 0000000000000..85de820025614
--- /dev/null
+++ b/llvm/test/CodeGen/LoongArch/lrint-conv.ll
@@ -0,0 +1,96 @@
+; Tests for lrint and llrint, with both i32 and i64 checked.
+
+; RUN: sed 's/ITy/i32/g' %s | llc -mtriple=loongarch32 | FileCheck %s --check-prefixes=LA32
+; RUN: sed 's/ITy/i64/g' %s | llc -mtriple=loongarch32 | FileCheck %s --check-prefixes=LA32
+; RUN: sed 's/ITy/i32/g' %s | llc -mtriple=loongarch64 | FileCheck %s --check-prefixes=LA64-I32
+; RUN: sed 's/ITy/i64/g' %s | llc -mtriple=loongarch64 | FileCheck %s --check-prefixes=LA64-I64
+
+; FIXME: crash
+; define ITy @test_lrint_ixx_f16(half %x) nounwind {
+;   %res = tail call ITy @llvm.lrint.ITy.f16(half %x)
+;   ret ITy %res
+; }
+
+; define ITy @test_llrint_ixx_f16(half %x) nounwind {
+;   %res = tail call ITy @llvm.llrint.ITy.f16(half %x)
+;   ret ITy %res
+; }
+
+define ITy @test_lrint_ixx_f32(float %x) nounwind {
+; LA32-LABEL: test_lrint_ixx_f32:
+; LA32:         bl lrintf
+;
+; LA64-I32-LABEL: test_lrint_ixx_f32:
+; LA64-I32:         pcaddu18i $ra, %call36(lrintf)
+;
+; LA64-I64-LABEL: test_lrint_ixx_f32:
+; LA64-I64:         pcaddu18i $t8, %call36(lrintf)
+  %res = tail call ITy @llvm.lrint.ITy.f32(float %x)
+  ret ITy %res
+}
+
+define ITy @test_llrint_ixx_f32(float %x) nounwind {
+; LA32-LABEL: test_llrint_ixx_f32:
+; LA32:         bl llrintf
+;
+; LA64-I32-LABEL: test_llrint_ixx_f32:
+; LA64-I32:         pcaddu18i $ra, %call36(llrintf)
+;
+; LA64-I64-LABEL: test_llrint_ixx_f32:
+; LA64-I64:         pcaddu18i $t8, %call36(llrintf)
+  %res = tail call ITy @llvm.llrint.ITy.f32(float %x)
+  ret ITy %res
+}
+
+define ITy @test_lrint_ixx_f64(double %x) nounwind {
+; LA32-LABEL: test_lrint_ixx_f64:
+; LA32:         bl lrint
+;
+; LA64-I32-LABEL: test_lrint_ixx_f64:
+; LA64-I32:         pcaddu18i $ra, %call36(lrint)
+;
+; LA64-I64-LABEL: test_lrint_ixx_f64:
+; LA64-I64:         pcaddu18i $t8, %call36(lrint)
+  %res = tail call ITy @llvm.lrint.ITy.f64(double %x)
+  ret ITy %res
+}
+
+define ITy @test_llrint_ixx_f64(double %x) nounwind {
+; LA32-LABEL: test_llrint_ixx_f64:
+; LA32:         bl llrint
+;
+; LA64-I32-LABEL: test_llrint_ixx_f64:
+; LA64-I32:         pcaddu18i $ra, %call36(llrint)
+;
+; LA64-I64-LABEL: test_llrint_ixx_f64:
+; LA64-I64:         pcaddu18i $t8, %call36(llrint)
+  %res = tail call ITy @llvm.llrint.ITy.f64(double %x)
+  ret ITy %res
+}
+
+; FIXME(#44744): incorrect libcall on loongarch32
+define ITy @test_lrint_ixx_f128(fp128 %x) nounwind {
+; LA32-LABEL: test_lrint_ixx_f128:
+; LA32:         bl lrintl
+;
+; LA64-I32-LABEL: test_lrint_ixx_f128:
+; LA64-I32:         pcaddu18i $ra, %call36(lrintl)
+;
+; LA64-I64-LABEL: test_lrint_ixx_f128:
+; LA64-I64:         pcaddu18i $ra, %call36(lrintl)
+  %res = tail call ITy @llvm.lrint.ITy.f128(fp128 %x)
+  ret ITy %res
+}
+
+define ITy @test_llrint_ixx_f128(fp128 %x) nounwind {
+; LA32-LABEL: test_llrint_ixx_f128:
+; LA32:         bl llrintl
+;
+; LA64-I32-LABEL: test_llrint_ixx_f128:
+; LA64-I32:         pcaddu18i $ra, %call36(llrintl)
+;
+; LA64-I64-LABEL: test_llrint_ixx_f128:
+; LA64-I64:         pcaddu18i $ra, %call36(llrintl)
+  %res = tail call ITy @llvm.llrint.ITy.f128(fp128 %x)
+  ret ITy %res
+}
diff --git a/llvm/test/CodeGen/MSP430/lrint-conv.ll b/llvm/test/CodeGen/MSP430/lrint-conv.ll
new file mode 100644
index 0000000000000..7eee951893d3e
--- /dev/null
+++ b/llvm/test/CodeGen/MSP430/lrint-conv.ll
@@ -0,0 +1,60 @@
+; NOTE: Assertions have been autogenerated by utils/update_llc_test_checks.py
+
+; Tests for lrint and llrint, with both i32 and i64 checked.
+
+; RUN: sed 's/ITy/i32/g' %s | llc -mtriple=msp430-unknown-unknown | FileCheck %s --check-prefixes=CHECK
+; RUN: sed 's/ITy/i64/g' %s | llc -mtriple=msp430-unknown-unknown | FileCheck %s --check-prefixes=CHECK
+
+; FIXME: crash
+; define ITy @test_lrint_ixx_f16(half %x) nounwind {
+;   %res = tail call ITy @llvm.lrint.ITy.f16(half %x)
+;   ret ITy %res
+; }
+
+; define ITy @test_llrint_ixx_f16(half %x) nounwind {
+;   %res = tail call ITy @llvm.llrint.ITy.f16(half %x)
+;   ret ITy %res
+; }
+
+define ITy @test_lrint_ixx_f32(float %x) nounwind {
+; CHECK-LABEL: test_lrint_ixx_f32:
+; CHECK:         call #lrintf
+  %res = tail call ITy @llvm.lrint.ITy.f32(float %x)
+  ret ITy %res
+}
+
+define ITy @test_llrint_ixx_f32(float %x) nounwind {
+; CHECK-LABEL: test_llrint_ixx_f32:
+; CHECK:         call #llrintf
+  %res = tail call ITy @llvm.llrint.ITy.f32(float %x)
+  ret ITy %res
+}
+
+define ITy @test_lrint_ixx_f64(double %x) nounwind {
+; CHECK-LABEL: test_lrint_ixx_f64:
+; CHECK:         call #lrint
+  %res = tail call ITy @llvm.lrint.ITy.f64(double %x)
+  ret ITy %res
+}
+
+define ITy @test_llrint_ixx_f64(double %x) nounwind {
+; CHECK-LABEL: test_llrint_ixx_f64:
+; CHECK:         call #llrint
+  %res = tail call ITy @llvm.llrint.ITy.f64(double %x)
+  ret ITy %res
+}
+
+; FIXME(#44744): incorrect libcall
+define ITy @test_lrint_ixx_f128(fp128 %x) nounwind {
+; CHECK-LABEL: test_lrint_ixx_f128:
+; CHECK:         call #lrintl
+  %res = tail call ITy @llvm.lrint.ITy.f128(fp128 %x)
+  ret ITy %res
+}
+
+define ITy @test_llrint_ixx_f128(fp128 %x) nounwind {
+; CHECK-LABEL: test_llrint_ixx_f128:
+; CHECK:         call #llrintl
+  %res = tail call ITy @llvm.llrint.ITy.f128(fp128 %x)
+  ret ITy %res
+}
diff --git a/llvm/test/CodeGen/Mips/llrint-conv.ll b/llvm/test/CodeGen/Mips/llrint-conv.ll
index dcb4e5657e80b..ee3c0d99253a6 100644
--- a/llvm/test/CodeGen/Mips/llrint-conv.ll
+++ b/llvm/test/CodeGen/Mips/llrint-conv.ll
@@ -1,4 +1,19 @@
 ; RUN: llc < %s -mtriple=mips64el -mattr=+soft-float | FileCheck %s
+; RUN: llc < %s -mtriple=mips -mattr=+soft-float     | FileCheck %s
+
+; FIXME: crash
+; define signext i32 @testmswh(half %x) {
+; entry:
+;   %0 = tail call i64 @llvm.llrint.f16(half %x)
+;   %conv = trunc i64 %0 to i32
+;   ret i32 %conv
+; }
+
+; define i64 @testmsxh(half %x) {
+; entry:
+;   %0 = tail call i64 @llvm.llrint.f16(half %x)
+;   ret i64 %0
+; }
 
 define signext i32 @testmsws(float %x) {
 ; CHECK-LABEL: testmsws:
diff --git a/llvm/test/CodeGen/Mips/lrint-conv.ll b/llvm/test/CodeGen/Mips/lrint-conv.ll
index bd3f7b3babe10..6d2e392675f1c 100644
--- a/llvm/test/CodeGen/Mips/lrint-conv.ll
+++ b/llvm/test/CodeGen/Mips/lrint-conv.ll
@@ -1,4 +1,19 @@
 ; RUN: llc < %s -mtriple=mips64el -mattr=+soft-float | FileCheck %s
+; RUN: llc < %s -mtriple=mips -mattr=+soft-float     | FileCheck %s
+
+; FIXME: crash
+; define signext i32 @testmswh(half %x) {
+; entry:
+;   %0 = tail call i64 @llvm.lrint.i64.f16(half %x)
+;   %conv = trunc i64 %0 to i32
+;   ret i32 %conv
+; }
+
+; define i64 @testmsxh(half %x) {
+; entry:
+;   %0 = tail call i64 @llvm.lrint.i64.f16(half %x)
+;   ret i64 %0
+; }
 
 define signext i32 @testmsws(float %x) {
 ; CHECK-LABEL: testmsws:
diff --git a/llvm/test/CodeGen/PowerPC/llrint-conv.ll b/llvm/test/CodeGen/PowerPC/llrint-conv.ll
index daadf85b4085a..ff41a53464d8c 100644
--- a/llvm/test/CodeGen/PowerPC/llrint-conv.ll
+++ b/llvm/test/CodeGen/PowerPC/llrint-conv.ll
@@ -1,4 +1,19 @@
 ; RUN: llc < %s -mtriple=powerpc64le | FileCheck %s
+; RUN: llc < %s -mtriple=powerpc | FileCheck %s
+
+; FIXME: crash
+; define signext i32 @testmswh(half %x) {
+; entry:
+;   %0 = tail call i64 @llvm.llrint.f16(half %x)
+;   %conv = trunc i64 %0 to i32
+;   ret i32 %conv
+; }
+
+; define i64 @testmsxh(half %x) {
+; entry:
+;   %0 = tail call i64 @llvm.llrint.f16(half %x)
+;   ret i64 %0
+; }
 
 ; CHECK-LABEL: testmsws:
 ; CHECK:       bl      llrintf
@@ -51,6 +66,23 @@ entry:
   ret i64 %0
 }
 
+; CHECK-LABEL: testmswq:
+; CHECK:       bl      llrintf128
+define signext i32 @testmswq(fp128 %x) {
+entry:
+  %0 = tail call i64 @llvm.llrint.f128(fp128 %x)
+  %conv = trunc i64 %0 to i32
+  ret i32 %conv
+}
+
+; CHECK-LABEL: testmslq:
+; CHECK:       bl      llrintf128
+define i64 @testmslq(fp128 %x) {
+entry:
+  %0 = tail call i64 @llvm.llrint.f128(fp128 %x)
+  ret i64 %0
+}
+
 declare i64 @llvm.llrint.f32(float) nounwind readnone
 declare i64 @llvm.llrint.f64(double) nounwind readnone
 declare i64 @llvm.llrint.ppcf128(ppc_fp128) nounwind readnone
diff --git a/llvm/test/CodeGen/PowerPC/lrint-conv.ll b/llvm/test/CodeGen/PowerPC/lrint-conv.ll
index adfc994497323..7b1a9d6a9fc77 100644
--- a/llvm/test/CodeGen/PowerPC/lrint-conv.ll
+++ b/llvm/test/CodeGen/PowerPC/lrint-conv.ll
@@ -1,4 +1,19 @@
 ; RUN: llc < %s -mtriple=powerpc64le | FileCheck %s
+; RUN: llc < %s -mtriple=powerpc | FileCheck %s
+
+; FIXME: crash
+; define signext i32 @testmswh(half %x) {
+; entry:
+;   %0 = tail call i64 @llvm.lrint.i64.f16(half %x)
+;   %conv = trunc i64 %0 to i32
+;   ret i32 %conv
+; }
+
+; define i64 @testmsxh(half %x) {
+; entry:
+;   %0 = tail call i64 @llvm.lrint.i64.f16(half %x)
+;   ret i64 %0
+; }
 
 ; CHECK-LABEL: testmsws:
 ; CHECK:       bl      lrintf
@@ -51,6 +66,23 @@ entry:
   ret i64 %0
 }
 
+; CHECK-LABEL: testmswq:
+; CHECK:       bl      lrintf128
+define signext i32 @testmswq(fp128 %x) {
+entry:
+  %0 = tail call i64 @llvm.lrint.i64.f128(fp128 %x)
+  %conv = trunc i64 %0 to i32
+  ret i32 %conv
+}
+
+; CHECK-LABEL: testmslq:
+; CHECK:       bl      lrintf128
+define i64 @testmslq(fp128 %x) {
+entry:
+  %0 = tail call i64 @llvm.lrint.i64.f128(fp128 %x)
+  ret i64 %0
+}
+
 declare i64 @llvm.lrint.i64.f32(float) nounwind readnone
 declare i64 @llvm.lrint.i64.f64(double) nounwind readnone
 declare i64 @llvm.lrint.i64.ppcf128(ppc_fp128) nounwind readnone
diff --git a/llvm/test/CodeGen/RISCV/lrint-conv.ll b/llvm/test/CodeGen/RISCV/lrint-conv.ll
new file mode 100644
index 0000000000000..d3af2153588a1
--- /dev/null
+++ b/llvm/test/CodeGen/RISCV/lrint-conv.ll
@@ -0,0 +1,76 @@
+; Tests for lrint and llrint, with both i32 and i64 checked.
+
+; RUN: sed 's/ITy/i32/g' %s | llc -mtriple=riscv32 | FileCheck %s --check-prefixes=RV32
+; RUN: sed 's/ITy/i64/g' %s | llc -mtriple=riscv32 | FileCheck %s --check-prefixes=RV32
+; RUN: sed 's/ITy/i32/g' %s | llc -mtriple=riscv64 | FileCheck %s --check-prefixes=RV64
+; RUN: sed 's/ITy/i64/g' %s | llc -mtriple=riscv64 | FileCheck %s --check-prefixes=RV64
+
+; FIXME: crash
+; define ITy @test_lrint_ixx_f16(half %x) nounwind {
+;   %res = tail call ITy @llvm.lrint.ITy.f16(half %x)
+; }
+
+; define ITy @test_llrint_ixx_f16(half %x) nounwind {
+;   %res = tail call ITy @llvm.llrint.ITy.f16(half %x)
+; }
+
+define ITy @test_lrint_ixx_f32(float %x) nounwind {
+; RV32-LABEL: test_lrint_ixx_f32:
+; RV32:         call lrintf
+;
+; RV64-LABEL: test_lrint_ixx_f32:
+; RV64:         call lrintf
+  %res = tail call ITy @llvm.lrint.ITy.f32(float %x)
+  ret ITy %res
+}
+
+define ITy @test_llrint_ixx_f32(float %x) nounwind {
+; RV32-LABEL: test_llrint_ixx_f32:
+; RV32:         call llrintf
+;
+; RV64-LABEL: test_llrint_ixx_f32:
+; RV64:         call llrintf
+  %res = tail call ITy @llvm.llrint.ITy.f32(float %x)
+  ret ITy %res
+}
+
+define ITy @test_lrint_ixx_f64(double %x) nounwind {
+; RV32-LABEL: test_lrint_ixx_f64:
+; RV32:         call lrint
+;
+; RV64-LABEL: test_lrint_ixx_f64:
+; RV64:         call lrint
+  %res = tail call ITy @llvm.lrint.ITy.f64(double %x)
+  ret ITy %res
+}
+
+define ITy @test_llrint_ixx_f64(double %x) nounwind {
+; RV32-LABEL: test_llrint_ixx_f64:
+; RV32:         call llrint
+;
+; RV64-LABEL: test_llrint_ixx_f64:
+; RV64:         call llrint
+  %res = tail call ITy @llvm.llrint.ITy.f64(double %x)
+  ret ITy %res
+}
+
+; FIXME(#44744): incorrect libcall on riscv32
+define ITy @test_lrint_ixx_f128(fp128 %x) nounwind {
+; RV32-LABEL: test_lrint_ixx_f128:
+; RV32:         call lrintl
+;
+; RV64-LABEL: test_lrint_ixx_f128:
+; RV64:         call lrintl
+  %res = tail call ITy @llvm.lrint.ITy.f128(fp128 %x)
+  ret ITy %res
+}
+
+define ITy @test_llrint_ixx_f128(fp128 %x) nounwind {
+; RV32-LABEL: test_llrint_ixx_f128:
+; RV32:         call llrintl
+;
+; RV64-LABEL: test_llrint_ixx_f128:
+; RV64:         call llrintl
+  %res = tail call ITy @llvm.llrint.ITy.f128(fp128 %x)
+  ret ITy %res
+}
diff --git a/llvm/test/CodeGen/SPARC/lrint-conv.ll b/llvm/test/CodeGen/SPARC/lrint-conv.ll
new file mode 100644
index 0000000000000..81d541a056875
--- /dev/null
+++ b/llvm/test/CodeGen/SPARC/lrint-conv.ll
@@ -0,0 +1,68 @@
+; Tests for lrint and llrint, with both i32 and i64 checked.
+
+; RUN: sed 's/ITy/i32/g' %s | llc -mtriple=sparc   | FileCheck %s --check-prefixes=SPARC32
+; RUN: sed 's/ITy/i64/g' %s | llc -mtriple=sparc   | FileCheck %s --check-prefixes=SPARC32
+; RUN: sed 's/ITy/i32/g' %s | llc -mtriple=sparc64 | FileCheck %s --check-prefixes=SPARC64
+; RUN: sed 's/ITy/i64/g' %s | llc -mtriple=sparc64 | FileCheck %s --check-prefixes=SPARC64
+
+; FIXME: crash
+; define ITy @test_lrint_ixx_f16(half %x) nounwind {
+;   %res = tail call ITy @llvm.lrint.ITy.f16(half %x)
+;   ret ITy %res
+; }
+
+; define ITy @test_llrint_ixx_f16(half %x) nounwind {
+;   %res = tail call ITy @llvm.llrint.ITy.f16(half %x)
+;   ret ITy %res
+; }
+
+define ITy @test_lrint_ixx_f32(float %x) nounwind {
+; SPARC32-LABEL: test_lrint_ixx_f32:
+; SPARC32:         call lrintf
+;
+; SPARC64-LABEL: test_lrint_ixx_f32:
+; SPARC64:         call lrintf
+  %res = tail call ITy @llvm.lrint.ITy.f32(float %x)
+  ret ITy %res
+}
+
+define ITy @test_llrint_ixx_f32(float %x) nounwind {
+; SPARC32-LABEL: test_llrint_ixx_f32:
+; SPARC32:         call llrintf
+;
+; SPARC64-LABEL: test_llrint_ixx_f32:
+; SPARC64:         call llrintf
+  %res = tail call ITy @llvm.llrint.ITy.f32(float %x)
+  ret ITy %res
+}
+
+define ITy @test_lrint_ixx_f64(double %x) nounwind {
+; SPARC32-LABEL: test_lrint_ixx_f64:
+; SPARC32:         call lrint
+;
+; SPARC64-LABEL: test_lrint_ixx_f64:
+; SPARC64:         call lrint
+  %res = tail call ITy @llvm.lrint.ITy.f64(double %x)
+  ret ITy %res
+}
+
+define ITy @test_llrint_ixx_f64(double %x) nounwind {
+; SPARC32-LABEL: test_llrint_ixx_f64:
+; SPARC32:         call llrint
+;
+; SPARC64-LABEL: test_llrint_ixx_f64:
+; SPARC64:         call llrint
+  %res = tail call ITy @llvm.llrint.ITy.f64(double %x)
+  ret ITy %res
+}
+
+; FIXME(#41838): unsupported type
+; define ITy @test_lrint_ixx_f128(fp128 %x) nounwind {
+;   %res = tail call ITy @llvm.lrint.ITy.f128(fp128 %x)
+;   ret ITy %res
+; }
+
+; define ITy @test_llrint_ixx_f128(fp128 %x) nounwind {
+;   %res = tail call ITy @llvm.llrint.ITy.f128(fp128 %x)
+;   ret ITy %res
+; }
diff --git a/llvm/test/CodeGen/WebAssembly/lrint-conv.ll b/llvm/test/CodeGen/WebAssembly/lrint-conv.ll
new file mode 100644
index 0000000000000..0571150cb3505
--- /dev/null
+++ b/llvm/test/CodeGen/WebAssembly/lrint-conv.ll
@@ -0,0 +1,62 @@
+; NOTE: Assertions have been autogenerated by utils/update_llc_test_checks.py
+
+; Tests for lrint and llrint, with both i32 and i64 checked.
+
+; RUN: sed 's/ITy/i32/g' %s | llc -mtriple=wasm32-unknown-unknown | FileCheck %s
+; RUN: sed 's/ITy/i64/g' %s | llc -mtriple=wasm32-unknown-unknown | FileCheck %s
+
+define ITy @test_lrint_ixx_f16(half %x) nounwind {
+; CHECK-LABEL: test_lrint_ixx_f16:
+; CHECK:         call lrintf
+  %res = tail call ITy @llvm.lrint.ITy.f16(half %x)
+  ret ITy %res
+}
+
+define ITy @test_llrint_ixx_f16(half %x) nounwind {
+; CHECK-LABEL: test_llrint_ixx_f16:
+; CHECK:         call llrintf
+  %res = tail call ITy @llvm.llrint.ITy.f16(half %x)
+  ret ITy %res
+}
+
+define ITy @test_lrint_ixx_f32(float %x) nounwind {
+; CHECK-LABEL: test_lrint_ixx_f32:
+; CHECK:         call lrintf
+  %res = tail call ITy @llvm.lrint.ITy.f32(float %x)
+  ret ITy %res
+}
+
+define ITy @test_llrint_ixx_f32(float %x) nounwind {
+; CHECK-LABEL: test_llrint_ixx_f32:
+; CHECK:         call llrintf
+  %res = tail call ITy @llvm.llrint.ITy.f32(float %x)
+  ret ITy %res
+}
+
+define ITy @test_lrint_ixx_f64(double %x) nounwind {
+; CHECK-LABEL: test_lrint_ixx_f64:
+; CHECK:         call lrint
+  %res = tail call ITy @llvm.lrint.ITy.f64(double %x)
+  ret ITy %res
+}
+
+define ITy @test_llrint_ixx_f64(double %x) nounwind {
+; CHECK-LABEL: test_llrint_ixx_f64:
+; CHECK:         call llrint
+  %res = tail cal...
[truncated]

@tgross35
Copy link
Contributor Author

tgross35 commented Aug 8, 2025

@arsenm could you review? This is a baseline for fixing the crash discussed on discord

A number of backends are missing either all tests for lrint, or
specifically those for f16 which currently crashes for `softPromoteHalf`
targets. For a number of popular backends, do the following:

* Ensure f16, f32, f64, and f128 are all covered
* Ensure both a 32- and 64-bit target are tested, if relevant
* Add `nounwind` to clean up CFI output
* Add a test covering the above if one did not exist
@tgross35
Copy link
Contributor Author

tgross35 commented Aug 8, 2025

Fix PR for many of the crashes: #152684

; X64-SSE-NEXT: popq %rcx
; X64-SSE-NEXT: retq
entry:
%0 = tail call i64 @llvm.llrint.f16(half %x)
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Missing int type in name mangling. Also I have no idea what the function name is supposed to mean

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I have no idea either, unfortunately it's everywhere. Best I can figure out is the last two letters are int and float size and the first is some kind of rounding op identifier.

Missing int type in name mangling

Meaning the intrinsic llvm.llrint.i64.f16 rather than llvm.llrint.f16? I was just being consistent with the rest of this file. Can add it to all tests here if you prefer.

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Yes, these should use canonical manglings for the signature

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Okay, I'll update.

Another question - a lot of tests seem to declare the intrinsics, but this doesn't seem needed. Any reason to do it anyway?

%0 = tail call i64 @llvm.llrint.fp128(fp128 %x)
ret i64 %0
}

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Also test vector cases?

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

These already has better coverage, but I updated all the tests to include a 32 bit target and also test f128.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Projects
None yet
Development

Successfully merging this pull request may close these issues.

3 participants