[llvm] [WebAssembly] Select BUILD_VECTOR with large unsigned lane values (PR #85880)

Thomas Lively via llvm-commits llvm-commits at lists.llvm.org
Tue Mar 19 17:29:08 PDT 2024


https://github.com/tlively created https://github.com/llvm/llvm-project/pull/85880

Previously we expected lane constants to be in the range of signed values for each lane size, but the included test case produced large unsigned values that fall outside that range. Allow instruction selection to proceed in this case rather than failing.

Fixes #63817.

>From ef9339e3c5ae09b83a90e77616b099379c3ca62c Mon Sep 17 00:00:00 2001
From: Thomas Lively <tlively at google.com>
Date: Tue, 19 Mar 2024 17:26:56 -0700
Subject: [PATCH] [WebAssembly] Select BUILD_VECTOR with large unsigned lane
 values

Previously we expected lane constants to be in the range of signed values for
each lane size, but the included test case produced large unsigned values that
fall outside that range. Allow instruction selection to proceed in this case
rather than failing.

Fixes #63817.
---
 .../Target/WebAssembly/WebAssemblyInstrSIMD.td    |  6 ++++--
 llvm/test/CodeGen/WebAssembly/pr63817.ll          | 15 +++++++++++++++
 2 files changed, 19 insertions(+), 2 deletions(-)
 create mode 100644 llvm/test/CodeGen/WebAssembly/pr63817.ll

diff --git a/llvm/lib/Target/WebAssembly/WebAssemblyInstrSIMD.td b/llvm/lib/Target/WebAssembly/WebAssemblyInstrSIMD.td
index 8cd41d7017a023..35f7d49be7a965 100644
--- a/llvm/lib/Target/WebAssembly/WebAssemblyInstrSIMD.td
+++ b/llvm/lib/Target/WebAssembly/WebAssemblyInstrSIMD.td
@@ -46,10 +46,12 @@ defm "" : ARGUMENT<V128, v2i64>;
 defm "" : ARGUMENT<V128, v4f32>;
 defm "" : ARGUMENT<V128, v2f64>;
 
-// Constrained immediate argument types
+// Constrained immediate argument types. Allow any value from the minimum signed
+// value to the maximum unsigned value for the lane size.
 foreach SIZE = [8, 16] in
 def ImmI#SIZE : ImmLeaf<i32,
-  "return -(1 << ("#SIZE#" - 1)) <= Imm && Imm < (1 << ("#SIZE#" - 1));"
+  // -2^(n-1) <= Imm <= 2^n-1, avoiding UB when n == 64.
+  "return -(1 << ("#SIZE#" - 1)) <= Imm && Imm <= int64_t(uint64_t(1 << ("#SIZE#" - 1) << 1) - 1);"
 >;
 foreach SIZE = [2, 4, 8, 16, 32] in
 def LaneIdx#SIZE : ImmLeaf<i32, "return 0 <= Imm && Imm < "#SIZE#";">;
diff --git a/llvm/test/CodeGen/WebAssembly/pr63817.ll b/llvm/test/CodeGen/WebAssembly/pr63817.ll
new file mode 100644
index 00000000000000..252768d43f1888
--- /dev/null
+++ b/llvm/test/CodeGen/WebAssembly/pr63817.ll
@@ -0,0 +1,15 @@
+; NOTE: Assertions have been autogenerated by utils/update_llc_test_checks.py
+; RUN: llc < %s -mtriple=wasm32 -mattr=+simd128 | FileCheck %s
+
+;; Regression test for a bug in which BUILD_VECTOR nodes with large unsigned
+;; lane constants were not properly selected.
+define <4 x i8> @test(<4 x i8> %0) {
+; CHECK-LABEL: test:
+; CHECK:         .functype test (v128) -> (v128)
+; CHECK-NEXT:  # %bb.0:
+; CHECK-NEXT:    v128.const 255, 17, 255, 255, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0
+; CHECK-NEXT:    # fallthrough-return
+  %V1 = or <4 x i8> <i8 255, i8 255, i8 255, i8 255>, %0
+  %V2 = insertelement <4 x i8> %V1, i8 17, i32 1
+  ret <4 x i8> %V2
+}



More information about the llvm-commits mailing list