[llvm] [WASM] Constant fold SIMD wasm intrinsics: any/alltrue (PR #148074)

via llvm-commits llvm-commits at lists.llvm.org
Sun Jul 13 07:18:06 PDT 2025


https://github.com/badumbatish updated https://github.com/llvm/llvm-project/pull/148074

>From 637e45c63c2392f250a20e3714b7d6e16b8c6fa6 Mon Sep 17 00:00:00 2001
From: Jasmine Tang <jjasmine at igalia.com>
Date: Wed, 9 Jul 2025 15:17:39 -0700
Subject: [PATCH 1/6] Precommit test for const fold wasm intrinsics for any/all
 true.

---
 .../WebAssembly/const_fold_simd_intrinsics.ll | 147 ++++++++++++++++++
 1 file changed, 147 insertions(+)
 create mode 100644 llvm/test/CodeGen/WebAssembly/const_fold_simd_intrinsics.ll

diff --git a/llvm/test/CodeGen/WebAssembly/const_fold_simd_intrinsics.ll b/llvm/test/CodeGen/WebAssembly/const_fold_simd_intrinsics.ll
new file mode 100644
index 0000000000000..a57b70c905a49
--- /dev/null
+++ b/llvm/test/CodeGen/WebAssembly/const_fold_simd_intrinsics.ll
@@ -0,0 +1,147 @@
+; NOTE: Assertions have been autogenerated by utils/update_test_checks.py UTC_ARGS: --version 5
+
+; RUN: opt -passes=instcombine -S < %s | FileCheck %s
+
+; Test that intrinsics wasm call are constant folded
+
+; all_one: a splat that is all one
+; not_all_one: a splat that is all one, except for 0 in the first location
+
+; all_zero: a splat that is all zero
+; not_all_zero: a splat that is all zero, except for 1 in the first location
+
+target triple = "wasm32-unknown-unknown"
+
+define void @all_true_splat_not_all_one(ptr %ptr) {
+; CHECK-LABEL: define void @all_true_splat_not_all_one(
+; CHECK-SAME: ptr [[PTR:%.*]]) {
+; CHECK-NEXT:    [[A:%.*]] = tail call i32 @llvm.wasm.alltrue.v16i8(<16 x i8> <i8 0, i8 1, i8 1, i8 1, i8 1, i8 1, i8 1, i8 1, i8 1, i8 1, i8 1, i8 1, i8 1, i8 1, i8 1, i8 1>)
+; CHECK-NEXT:    store volatile i32 [[A]], ptr [[PTR]], align 4
+; CHECK-NEXT:    [[B:%.*]] = tail call i32 @llvm.wasm.alltrue.v8i16(<8 x i16> <i16 0, i16 1, i16 1, i16 1, i16 1, i16 1, i16 1, i16 1>)
+; CHECK-NEXT:    store volatile i32 [[B]], ptr [[PTR]], align 4
+; CHECK-NEXT:    [[C:%.*]] = tail call i32 @llvm.wasm.alltrue.v4i32(<4 x i32> <i32 0, i32 1, i32 1, i32 1>)
+; CHECK-NEXT:    store volatile i32 [[C]], ptr [[PTR]], align 4
+; CHECK-NEXT:    [[D:%.*]] = tail call i32 @llvm.wasm.alltrue.v2i64(<2 x i64> <i64 0, i64 1>)
+; CHECK-NEXT:    store volatile i32 [[D]], ptr [[PTR]], align 4
+; CHECK-NEXT:    [[E:%.*]] = tail call i32 @llvm.wasm.alltrue.v4i64(<4 x i64> <i64 0, i64 1, i64 1, i64 1>)
+; CHECK-NEXT:    store volatile i32 [[E]], ptr [[PTR]], align 4
+; CHECK-NEXT:    ret void
+;
+  %a = tail call i32 @llvm.wasm.alltrue(<16 x i8> <i8 0, i8 1, i8 1, i8 1, i8 1, i8 1, i8 1, i8 1, i8 1, i8 1, i8 1, i8 1, i8 1, i8 1, i8 1, i8 1>)
+  store volatile i32 %a, ptr %ptr
+
+  %b = tail call i32 @llvm.wasm.alltrue(<8 x i16> <i16 0, i16 1, i16 1, i16 1, i16 1, i16 1, i16 1, i16 1>)
+  store volatile i32 %b, ptr %ptr
+
+  %c = tail call i32 @llvm.wasm.alltrue(<4 x i32> <i32 0, i32 1, i32 1, i32 1>)
+  store volatile i32 %c, ptr %ptr
+
+  %d = tail call i32 @llvm.wasm.alltrue(<2 x i64> <i64 0, i64 1>)
+  store volatile i32 %d, ptr %ptr
+
+  %e = tail call i32 @llvm.wasm.alltrue(<4 x i64> <i64 0, i64 1, i64 1, i64 1>)
+  store volatile i32 %e, ptr %ptr
+
+  ret void
+}
+
+define void @all_true_splat_one(ptr %ptr) {
+; CHECK-LABEL: define void @all_true_splat_one(
+; CHECK-SAME: ptr [[PTR:%.*]]) {
+; CHECK-NEXT:    [[A:%.*]] = tail call i32 @llvm.wasm.alltrue.v16i8(<16 x i8> splat (i8 1))
+; CHECK-NEXT:    store volatile i32 [[A]], ptr [[PTR]], align 4
+; CHECK-NEXT:    [[B:%.*]] = tail call i32 @llvm.wasm.alltrue.v8i16(<8 x i16> splat (i16 1))
+; CHECK-NEXT:    store volatile i32 [[B]], ptr [[PTR]], align 4
+; CHECK-NEXT:    [[C:%.*]] = tail call i32 @llvm.wasm.alltrue.v4i32(<4 x i32> splat (i32 1))
+; CHECK-NEXT:    store volatile i32 [[C]], ptr [[PTR]], align 4
+; CHECK-NEXT:    [[D:%.*]] = tail call i32 @llvm.wasm.alltrue.v2i64(<2 x i64> splat (i64 1))
+; CHECK-NEXT:    store volatile i32 [[D]], ptr [[PTR]], align 4
+; CHECK-NEXT:    [[E:%.*]] = tail call i32 @llvm.wasm.alltrue.v4i64(<4 x i64> splat (i64 1))
+; CHECK-NEXT:    store volatile i32 [[E]], ptr [[PTR]], align 4
+; CHECK-NEXT:    ret void
+;
+  %a = tail call i32 @llvm.wasm.alltrue(<16 x i8> <i8 1, i8 1, i8 1, i8 1, i8 1, i8 1, i8 1, i8 1, i8 1, i8 1, i8 1, i8 1, i8 1, i8 1, i8 1, i8 1>)
+  store volatile i32 %a, ptr %ptr
+
+  %b = tail call i32 @llvm.wasm.alltrue(<8 x i16> <i16 1, i16 1, i16 1, i16 1, i16 1, i16 1, i16 1, i16 1>)
+  store volatile i32 %b, ptr %ptr
+
+  %c = tail call i32 @llvm.wasm.alltrue(<4 x i32> <i32 1, i32 1, i32 1, i32 1>)
+  store volatile i32 %c, ptr %ptr
+
+  %d = tail call i32 @llvm.wasm.alltrue(<2 x i64> <i64 1, i64 1>)
+  store volatile i32 %d, ptr %ptr
+
+  %e = tail call i32 @llvm.wasm.alltrue(<4 x i64> <i64 1, i64 1, i64 1, i64 1>)
+  store volatile i32 %e, ptr %ptr
+
+  ret void
+}
+
+
+define void @any_true_splat_zero(ptr %ptr) {
+; CHECK-LABEL: define void @any_true_splat_zero(
+; CHECK-SAME: ptr [[PTR:%.*]]) {
+; CHECK-NEXT:    [[A:%.*]] = tail call i32 @llvm.wasm.anytrue.v16i8(<16 x i8> zeroinitializer)
+; CHECK-NEXT:    store volatile i32 [[A]], ptr [[PTR]], align 4
+; CHECK-NEXT:    [[B:%.*]] = tail call i32 @llvm.wasm.anytrue.v8i16(<8 x i16> zeroinitializer)
+; CHECK-NEXT:    store volatile i32 [[B]], ptr [[PTR]], align 4
+; CHECK-NEXT:    [[C:%.*]] = tail call i32 @llvm.wasm.anytrue.v4i32(<4 x i32> zeroinitializer)
+; CHECK-NEXT:    store volatile i32 [[C]], ptr [[PTR]], align 4
+; CHECK-NEXT:    [[D:%.*]] = tail call i32 @llvm.wasm.anytrue.v2i64(<2 x i64> zeroinitializer)
+; CHECK-NEXT:    store volatile i32 [[D]], ptr [[PTR]], align 4
+; CHECK-NEXT:    [[E:%.*]] = tail call i32 @llvm.wasm.anytrue.v4i64(<4 x i64> zeroinitializer)
+; CHECK-NEXT:    store volatile i32 [[E]], ptr [[PTR]], align 4
+; CHECK-NEXT:    ret void
+;
+  %a = tail call i32 @llvm.wasm.anytrue(<16 x i8> <i8 0, i8 0, i8 0, i8 0, i8 0, i8 0, i8 0, i8 0, i8 0, i8 0, i8 0, i8 0, i8 0, i8 0, i8 0, i8 0>)
+  store volatile i32 %a, ptr %ptr
+
+  %b = tail call i32 @llvm.wasm.anytrue(<8 x i16> <i16 0, i16 0, i16 0, i16 0, i16 0, i16 0, i16 0, i16 0>)
+  store volatile i32 %b, ptr %ptr
+
+  %c = tail call i32 @llvm.wasm.anytrue(<4 x i32> <i32 0, i32 0, i32 0, i32 0>)
+  store volatile i32 %c, ptr %ptr
+
+  %d = tail call i32 @llvm.wasm.anytrue(<2 x i64> <i64 0, i64 0>)
+  store volatile i32 %d, ptr %ptr
+
+  %e = tail call i32 @llvm.wasm.anytrue(<4 x i64> <i64 0, i64 0, i64 0, i64 0>)
+  store volatile i32 %e, ptr %ptr
+
+  ret void
+}
+
+
+define void @any_true_splat_not_all_zero(ptr %ptr) {
+; CHECK-LABEL: define void @any_true_splat_not_all_zero(
+; CHECK-SAME: ptr [[PTR:%.*]]) {
+; CHECK-NEXT:    [[A:%.*]] = tail call i32 @llvm.wasm.anytrue.v16i8(<16 x i8> <i8 1, i8 0, i8 0, i8 0, i8 0, i8 0, i8 0, i8 0, i8 0, i8 0, i8 0, i8 0, i8 0, i8 0, i8 0, i8 0>)
+; CHECK-NEXT:    store volatile i32 [[A]], ptr [[PTR]], align 4
+; CHECK-NEXT:    [[B:%.*]] = tail call i32 @llvm.wasm.anytrue.v8i16(<8 x i16> <i16 1, i16 0, i16 0, i16 0, i16 0, i16 0, i16 0, i16 0>)
+; CHECK-NEXT:    store volatile i32 [[B]], ptr [[PTR]], align 4
+; CHECK-NEXT:    [[C:%.*]] = tail call i32 @llvm.wasm.anytrue.v4i32(<4 x i32> <i32 1, i32 0, i32 0, i32 0>)
+; CHECK-NEXT:    store volatile i32 [[C]], ptr [[PTR]], align 4
+; CHECK-NEXT:    [[D:%.*]] = tail call i32 @llvm.wasm.anytrue.v2i64(<2 x i64> <i64 1, i64 0>)
+; CHECK-NEXT:    store volatile i32 [[D]], ptr [[PTR]], align 4
+; CHECK-NEXT:    [[E:%.*]] = tail call i32 @llvm.wasm.anytrue.v4i64(<4 x i64> <i64 1, i64 0, i64 0, i64 0>)
+; CHECK-NEXT:    store volatile i32 [[E]], ptr [[PTR]], align 4
+; CHECK-NEXT:    ret void
+;
+  %a = tail call i32 @llvm.wasm.anytrue(<16 x i8> <i8 1, i8 0, i8 0, i8 0, i8 0, i8 0, i8 0, i8 0, i8 0, i8 0, i8 0, i8 0, i8 0, i8 0, i8 0, i8 0>)
+  store volatile i32 %a, ptr %ptr
+
+  %b = tail call i32 @llvm.wasm.anytrue(<8 x i16> <i16 1, i16 0, i16 0, i16 0, i16 0, i16 0, i16 0, i16 0>)
+  store volatile i32 %b, ptr %ptr
+
+  %c = tail call i32 @llvm.wasm.anytrue(<4 x i32> <i32 1, i32 0, i32 0, i32 0>)
+  store volatile i32 %c, ptr %ptr
+
+  %d = tail call i32 @llvm.wasm.anytrue(<2 x i64> <i64 1, i64 0>)
+  store volatile i32 %d, ptr %ptr
+
+  %e = tail call i32 @llvm.wasm.anytrue(<4 x i64> <i64 1, i64 0, i64 0, i64 0>)
+  store volatile i32 %e, ptr %ptr
+
+  ret void
+}

>From e27f5bc3cff07f242a0e29b4786126efc79897bb Mon Sep 17 00:00:00 2001
From: Jasmine Tang <jjasmine at igalia.com>
Date: Wed, 9 Jul 2025 20:32:12 -0700
Subject: [PATCH 2/6] Added support for constant folding of wasm
 anytrue/alltrue

---
 llvm/lib/Analysis/ConstantFolding.cpp         | 13 +++-
 .../WebAssembly/const_fold_simd_intrinsics.ll | 60 +++++++------------
 2 files changed, 32 insertions(+), 41 deletions(-)

diff --git a/llvm/lib/Analysis/ConstantFolding.cpp b/llvm/lib/Analysis/ConstantFolding.cpp
index 6e469c034d9c8..ddd3f137ad84d 100644
--- a/llvm/lib/Analysis/ConstantFolding.cpp
+++ b/llvm/lib/Analysis/ConstantFolding.cpp
@@ -1655,6 +1655,8 @@ bool llvm::canConstantFoldCallTo(const CallBase *Call, const Function *F) {
   case Intrinsic::arm_mve_vctp32:
   case Intrinsic::arm_mve_vctp64:
   case Intrinsic::aarch64_sve_convert_from_svbool:
+  case Intrinsic::wasm_alltrue:
+  case Intrinsic::wasm_anytrue:
   // WebAssembly float semantics are always known
   case Intrinsic::wasm_trunc_signed:
   case Intrinsic::wasm_trunc_unsigned:
@@ -2832,7 +2834,8 @@ static Constant *ConstantFoldScalarCall1(StringRef Name,
 
   // Support ConstantVector in case we have an Undef in the top.
   if (isa<ConstantVector>(Operands[0]) ||
-      isa<ConstantDataVector>(Operands[0])) {
+      isa<ConstantDataVector>(Operands[0]) ||
+      isa<ConstantAggregateZero>(Operands[0])) {
     auto *Op = cast<Constant>(Operands[0]);
     switch (IntrinsicID) {
     default: break;
@@ -2856,6 +2859,14 @@ static Constant *ConstantFoldScalarCall1(StringRef Name,
                                            /*roundTowardZero=*/true, Ty,
                                            /*IsSigned*/true);
       break;
+
+    case Intrinsic::wasm_anytrue:
+      return Op->isZeroValue() ? ConstantInt::get(Ty, 1)
+                               : ConstantInt::get(Ty, 0);
+
+    case Intrinsic::wasm_alltrue:
+      return Op->isAllOnesValue() ? ConstantInt::get(Ty, 1)
+                                  : ConstantInt::get(Ty, 0);
     }
   }
 
diff --git a/llvm/test/CodeGen/WebAssembly/const_fold_simd_intrinsics.ll b/llvm/test/CodeGen/WebAssembly/const_fold_simd_intrinsics.ll
index a57b70c905a49..4d29b82f64d0d 100644
--- a/llvm/test/CodeGen/WebAssembly/const_fold_simd_intrinsics.ll
+++ b/llvm/test/CodeGen/WebAssembly/const_fold_simd_intrinsics.ll
@@ -15,16 +15,11 @@ target triple = "wasm32-unknown-unknown"
 define void @all_true_splat_not_all_one(ptr %ptr) {
 ; CHECK-LABEL: define void @all_true_splat_not_all_one(
 ; CHECK-SAME: ptr [[PTR:%.*]]) {
-; CHECK-NEXT:    [[A:%.*]] = tail call i32 @llvm.wasm.alltrue.v16i8(<16 x i8> <i8 0, i8 1, i8 1, i8 1, i8 1, i8 1, i8 1, i8 1, i8 1, i8 1, i8 1, i8 1, i8 1, i8 1, i8 1, i8 1>)
-; CHECK-NEXT:    store volatile i32 [[A]], ptr [[PTR]], align 4
-; CHECK-NEXT:    [[B:%.*]] = tail call i32 @llvm.wasm.alltrue.v8i16(<8 x i16> <i16 0, i16 1, i16 1, i16 1, i16 1, i16 1, i16 1, i16 1>)
-; CHECK-NEXT:    store volatile i32 [[B]], ptr [[PTR]], align 4
-; CHECK-NEXT:    [[C:%.*]] = tail call i32 @llvm.wasm.alltrue.v4i32(<4 x i32> <i32 0, i32 1, i32 1, i32 1>)
-; CHECK-NEXT:    store volatile i32 [[C]], ptr [[PTR]], align 4
-; CHECK-NEXT:    [[D:%.*]] = tail call i32 @llvm.wasm.alltrue.v2i64(<2 x i64> <i64 0, i64 1>)
-; CHECK-NEXT:    store volatile i32 [[D]], ptr [[PTR]], align 4
-; CHECK-NEXT:    [[E:%.*]] = tail call i32 @llvm.wasm.alltrue.v4i64(<4 x i64> <i64 0, i64 1, i64 1, i64 1>)
-; CHECK-NEXT:    store volatile i32 [[E]], ptr [[PTR]], align 4
+; CHECK-NEXT:    store volatile i32 0, ptr [[PTR]], align 4
+; CHECK-NEXT:    store volatile i32 0, ptr [[PTR]], align 4
+; CHECK-NEXT:    store volatile i32 0, ptr [[PTR]], align 4
+; CHECK-NEXT:    store volatile i32 0, ptr [[PTR]], align 4
+; CHECK-NEXT:    store volatile i32 0, ptr [[PTR]], align 4
 ; CHECK-NEXT:    ret void
 ;
   %a = tail call i32 @llvm.wasm.alltrue(<16 x i8> <i8 0, i8 1, i8 1, i8 1, i8 1, i8 1, i8 1, i8 1, i8 1, i8 1, i8 1, i8 1, i8 1, i8 1, i8 1, i8 1>)
@@ -48,16 +43,11 @@ define void @all_true_splat_not_all_one(ptr %ptr) {
 define void @all_true_splat_one(ptr %ptr) {
 ; CHECK-LABEL: define void @all_true_splat_one(
 ; CHECK-SAME: ptr [[PTR:%.*]]) {
-; CHECK-NEXT:    [[A:%.*]] = tail call i32 @llvm.wasm.alltrue.v16i8(<16 x i8> splat (i8 1))
-; CHECK-NEXT:    store volatile i32 [[A]], ptr [[PTR]], align 4
-; CHECK-NEXT:    [[B:%.*]] = tail call i32 @llvm.wasm.alltrue.v8i16(<8 x i16> splat (i16 1))
-; CHECK-NEXT:    store volatile i32 [[B]], ptr [[PTR]], align 4
-; CHECK-NEXT:    [[C:%.*]] = tail call i32 @llvm.wasm.alltrue.v4i32(<4 x i32> splat (i32 1))
-; CHECK-NEXT:    store volatile i32 [[C]], ptr [[PTR]], align 4
-; CHECK-NEXT:    [[D:%.*]] = tail call i32 @llvm.wasm.alltrue.v2i64(<2 x i64> splat (i64 1))
-; CHECK-NEXT:    store volatile i32 [[D]], ptr [[PTR]], align 4
-; CHECK-NEXT:    [[E:%.*]] = tail call i32 @llvm.wasm.alltrue.v4i64(<4 x i64> splat (i64 1))
-; CHECK-NEXT:    store volatile i32 [[E]], ptr [[PTR]], align 4
+; CHECK-NEXT:    store volatile i32 0, ptr [[PTR]], align 4
+; CHECK-NEXT:    store volatile i32 0, ptr [[PTR]], align 4
+; CHECK-NEXT:    store volatile i32 0, ptr [[PTR]], align 4
+; CHECK-NEXT:    store volatile i32 0, ptr [[PTR]], align 4
+; CHECK-NEXT:    store volatile i32 0, ptr [[PTR]], align 4
 ; CHECK-NEXT:    ret void
 ;
   %a = tail call i32 @llvm.wasm.alltrue(<16 x i8> <i8 1, i8 1, i8 1, i8 1, i8 1, i8 1, i8 1, i8 1, i8 1, i8 1, i8 1, i8 1, i8 1, i8 1, i8 1, i8 1>)
@@ -82,16 +72,11 @@ define void @all_true_splat_one(ptr %ptr) {
 define void @any_true_splat_zero(ptr %ptr) {
 ; CHECK-LABEL: define void @any_true_splat_zero(
 ; CHECK-SAME: ptr [[PTR:%.*]]) {
-; CHECK-NEXT:    [[A:%.*]] = tail call i32 @llvm.wasm.anytrue.v16i8(<16 x i8> zeroinitializer)
-; CHECK-NEXT:    store volatile i32 [[A]], ptr [[PTR]], align 4
-; CHECK-NEXT:    [[B:%.*]] = tail call i32 @llvm.wasm.anytrue.v8i16(<8 x i16> zeroinitializer)
-; CHECK-NEXT:    store volatile i32 [[B]], ptr [[PTR]], align 4
-; CHECK-NEXT:    [[C:%.*]] = tail call i32 @llvm.wasm.anytrue.v4i32(<4 x i32> zeroinitializer)
-; CHECK-NEXT:    store volatile i32 [[C]], ptr [[PTR]], align 4
-; CHECK-NEXT:    [[D:%.*]] = tail call i32 @llvm.wasm.anytrue.v2i64(<2 x i64> zeroinitializer)
-; CHECK-NEXT:    store volatile i32 [[D]], ptr [[PTR]], align 4
-; CHECK-NEXT:    [[E:%.*]] = tail call i32 @llvm.wasm.anytrue.v4i64(<4 x i64> zeroinitializer)
-; CHECK-NEXT:    store volatile i32 [[E]], ptr [[PTR]], align 4
+; CHECK-NEXT:    store volatile i32 1, ptr [[PTR]], align 4
+; CHECK-NEXT:    store volatile i32 1, ptr [[PTR]], align 4
+; CHECK-NEXT:    store volatile i32 1, ptr [[PTR]], align 4
+; CHECK-NEXT:    store volatile i32 1, ptr [[PTR]], align 4
+; CHECK-NEXT:    store volatile i32 1, ptr [[PTR]], align 4
 ; CHECK-NEXT:    ret void
 ;
   %a = tail call i32 @llvm.wasm.anytrue(<16 x i8> <i8 0, i8 0, i8 0, i8 0, i8 0, i8 0, i8 0, i8 0, i8 0, i8 0, i8 0, i8 0, i8 0, i8 0, i8 0, i8 0>)
@@ -116,16 +101,11 @@ define void @any_true_splat_zero(ptr %ptr) {
 define void @any_true_splat_not_all_zero(ptr %ptr) {
 ; CHECK-LABEL: define void @any_true_splat_not_all_zero(
 ; CHECK-SAME: ptr [[PTR:%.*]]) {
-; CHECK-NEXT:    [[A:%.*]] = tail call i32 @llvm.wasm.anytrue.v16i8(<16 x i8> <i8 1, i8 0, i8 0, i8 0, i8 0, i8 0, i8 0, i8 0, i8 0, i8 0, i8 0, i8 0, i8 0, i8 0, i8 0, i8 0>)
-; CHECK-NEXT:    store volatile i32 [[A]], ptr [[PTR]], align 4
-; CHECK-NEXT:    [[B:%.*]] = tail call i32 @llvm.wasm.anytrue.v8i16(<8 x i16> <i16 1, i16 0, i16 0, i16 0, i16 0, i16 0, i16 0, i16 0>)
-; CHECK-NEXT:    store volatile i32 [[B]], ptr [[PTR]], align 4
-; CHECK-NEXT:    [[C:%.*]] = tail call i32 @llvm.wasm.anytrue.v4i32(<4 x i32> <i32 1, i32 0, i32 0, i32 0>)
-; CHECK-NEXT:    store volatile i32 [[C]], ptr [[PTR]], align 4
-; CHECK-NEXT:    [[D:%.*]] = tail call i32 @llvm.wasm.anytrue.v2i64(<2 x i64> <i64 1, i64 0>)
-; CHECK-NEXT:    store volatile i32 [[D]], ptr [[PTR]], align 4
-; CHECK-NEXT:    [[E:%.*]] = tail call i32 @llvm.wasm.anytrue.v4i64(<4 x i64> <i64 1, i64 0, i64 0, i64 0>)
-; CHECK-NEXT:    store volatile i32 [[E]], ptr [[PTR]], align 4
+; CHECK-NEXT:    store volatile i32 0, ptr [[PTR]], align 4
+; CHECK-NEXT:    store volatile i32 0, ptr [[PTR]], align 4
+; CHECK-NEXT:    store volatile i32 0, ptr [[PTR]], align 4
+; CHECK-NEXT:    store volatile i32 0, ptr [[PTR]], align 4
+; CHECK-NEXT:    store volatile i32 0, ptr [[PTR]], align 4
 ; CHECK-NEXT:    ret void
 ;
   %a = tail call i32 @llvm.wasm.anytrue(<16 x i8> <i8 1, i8 0, i8 0, i8 0, i8 0, i8 0, i8 0, i8 0, i8 0, i8 0, i8 0, i8 0, i8 0, i8 0, i8 0, i8 0>)

>From e8d1ff2546f1229fc6cfa83d43e1cd1ff3b091ef Mon Sep 17 00:00:00 2001
From: Jasmine Tang <jjasmine at igalia.com>
Date: Thu, 10 Jul 2025 18:11:33 -0700
Subject: [PATCH 3/6] Fix logic error in wasm_all_true, update tests

---
 llvm/lib/Analysis/ConstantFolding.cpp         | 15 +++--
 .../WebAssembly/const_fold_simd_intrinsics.ll | 66 +++++++++----------
 2 files changed, 44 insertions(+), 37 deletions(-)

diff --git a/llvm/lib/Analysis/ConstantFolding.cpp b/llvm/lib/Analysis/ConstantFolding.cpp
index ddd3f137ad84d..f0c3fdaa4e50d 100644
--- a/llvm/lib/Analysis/ConstantFolding.cpp
+++ b/llvm/lib/Analysis/ConstantFolding.cpp
@@ -2861,12 +2861,19 @@ static Constant *ConstantFoldScalarCall1(StringRef Name,
       break;
 
     case Intrinsic::wasm_anytrue:
-      return Op->isZeroValue() ? ConstantInt::get(Ty, 1)
-                               : ConstantInt::get(Ty, 0);
+      return Op->isZeroValue() ? ConstantInt::get(Ty, 0)
+                               : ConstantInt::get(Ty, 1);
 
     case Intrinsic::wasm_alltrue:
-      return Op->isAllOnesValue() ? ConstantInt::get(Ty, 1)
-                                  : ConstantInt::get(Ty, 0);
+      // Check each element individually
+      unsigned E = cast<FixedVectorType>(Op->getType())->getNumElements();
+      for (unsigned I = 0; I != E; ++I) 
+        if (Constant *Elt = Op->getAggregateElement(I)) 
+          if (Elt->isZeroValue())
+            return ConstantInt::get(Ty, 0);
+        
+      
+      return ConstantInt::get(Ty, 1);
     }
   }
 
diff --git a/llvm/test/CodeGen/WebAssembly/const_fold_simd_intrinsics.ll b/llvm/test/CodeGen/WebAssembly/const_fold_simd_intrinsics.ll
index 4d29b82f64d0d..063bb8a810384 100644
--- a/llvm/test/CodeGen/WebAssembly/const_fold_simd_intrinsics.ll
+++ b/llvm/test/CodeGen/WebAssembly/const_fold_simd_intrinsics.ll
@@ -4,16 +4,16 @@
 
 ; Test that intrinsics wasm call are constant folded
 
-; all_one: a splat that is all one
-; not_all_one: a splat that is all one, except for 0 in the first location
+; all_non_zero: a splat that is all non_zero
+; not_all_non_zero: a splat that is all one, except for 0 in the first location
 
 ; all_zero: a splat that is all zero
-; not_all_zero: a splat that is all zero, except for 1 in the first location
+; not_all_zero: a splat that is all zero, except for a non-zero in the first location
 
 target triple = "wasm32-unknown-unknown"
 
-define void @all_true_splat_not_all_one(ptr %ptr) {
-; CHECK-LABEL: define void @all_true_splat_not_all_one(
+define void @all_true_splat_not_all_none_zero(ptr %ptr) {
+; CHECK-LABEL: define void @all_true_splat_not_all_none_zero(
 ; CHECK-SAME: ptr [[PTR:%.*]]) {
 ; CHECK-NEXT:    store volatile i32 0, ptr [[PTR]], align 4
 ; CHECK-NEXT:    store volatile i32 0, ptr [[PTR]], align 4
@@ -22,16 +22,16 @@ define void @all_true_splat_not_all_one(ptr %ptr) {
 ; CHECK-NEXT:    store volatile i32 0, ptr [[PTR]], align 4
 ; CHECK-NEXT:    ret void
 ;
-  %a = tail call i32 @llvm.wasm.alltrue(<16 x i8> <i8 0, i8 1, i8 1, i8 1, i8 1, i8 1, i8 1, i8 1, i8 1, i8 1, i8 1, i8 1, i8 1, i8 1, i8 1, i8 1>)
+  %a = tail call i32 @llvm.wasm.alltrue(<16 x i8> <i8 0, i8 1, i8 2, i8 1, i8 1, i8 1, i8 1, i8 1, i8 1, i8 1, i8 1, i8 1, i8 1, i8 1, i8 1, i8 1>)
   store volatile i32 %a, ptr %ptr
 
-  %b = tail call i32 @llvm.wasm.alltrue(<8 x i16> <i16 0, i16 1, i16 1, i16 1, i16 1, i16 1, i16 1, i16 1>)
+  %b = tail call i32 @llvm.wasm.alltrue(<8 x i16> <i16 0, i16 1, i16 2, i16 1, i16 1, i16 1, i16 1, i16 1>)
   store volatile i32 %b, ptr %ptr
 
   %c = tail call i32 @llvm.wasm.alltrue(<4 x i32> <i32 0, i32 1, i32 1, i32 1>)
   store volatile i32 %c, ptr %ptr
 
-  %d = tail call i32 @llvm.wasm.alltrue(<2 x i64> <i64 0, i64 1>)
+  %d = tail call i32 @llvm.wasm.alltrue(<2 x i64> <i64 0, i64 42>)
   store volatile i32 %d, ptr %ptr
 
   %e = tail call i32 @llvm.wasm.alltrue(<4 x i64> <i64 0, i64 1, i64 1, i64 1>)
@@ -40,17 +40,17 @@ define void @all_true_splat_not_all_one(ptr %ptr) {
   ret void
 }
 
-define void @all_true_splat_one(ptr %ptr) {
-; CHECK-LABEL: define void @all_true_splat_one(
+define void @all_true_splat_all_non_zero(ptr %ptr) {
+; CHECK-LABEL: define void @all_true_splat_all_non_zero(
 ; CHECK-SAME: ptr [[PTR:%.*]]) {
-; CHECK-NEXT:    store volatile i32 0, ptr [[PTR]], align 4
-; CHECK-NEXT:    store volatile i32 0, ptr [[PTR]], align 4
-; CHECK-NEXT:    store volatile i32 0, ptr [[PTR]], align 4
-; CHECK-NEXT:    store volatile i32 0, ptr [[PTR]], align 4
-; CHECK-NEXT:    store volatile i32 0, ptr [[PTR]], align 4
+; CHECK-NEXT:    store volatile i32 1, ptr [[PTR]], align 4
+; CHECK-NEXT:    store volatile i32 1, ptr [[PTR]], align 4
+; CHECK-NEXT:    store volatile i32 1, ptr [[PTR]], align 4
+; CHECK-NEXT:    store volatile i32 1, ptr [[PTR]], align 4
+; CHECK-NEXT:    store volatile i32 1, ptr [[PTR]], align 4
 ; CHECK-NEXT:    ret void
 ;
-  %a = tail call i32 @llvm.wasm.alltrue(<16 x i8> <i8 1, i8 1, i8 1, i8 1, i8 1, i8 1, i8 1, i8 1, i8 1, i8 1, i8 1, i8 1, i8 1, i8 1, i8 1, i8 1>)
+  %a = tail call i32 @llvm.wasm.alltrue(<16 x i8> <i8 1, i8 3, i8 1, i8 1, i8 1, i8 1, i8 1, i8 1, i8 1, i8 1, i8 1, i8 1, i8 1, i8 1, i8 1, i8 1>)
   store volatile i32 %a, ptr %ptr
 
   %b = tail call i32 @llvm.wasm.alltrue(<8 x i16> <i16 1, i16 1, i16 1, i16 1, i16 1, i16 1, i16 1, i16 1>)
@@ -59,24 +59,24 @@ define void @all_true_splat_one(ptr %ptr) {
   %c = tail call i32 @llvm.wasm.alltrue(<4 x i32> <i32 1, i32 1, i32 1, i32 1>)
   store volatile i32 %c, ptr %ptr
 
-  %d = tail call i32 @llvm.wasm.alltrue(<2 x i64> <i64 1, i64 1>)
+  %d = tail call i32 @llvm.wasm.alltrue(<2 x i64> <i64 2, i64 2>)
   store volatile i32 %d, ptr %ptr
 
-  %e = tail call i32 @llvm.wasm.alltrue(<4 x i64> <i64 1, i64 1, i64 1, i64 1>)
+  %e = tail call i32 @llvm.wasm.alltrue(<4 x i64> <i64 1, i64 2, i64 1, i64 1>)
   store volatile i32 %e, ptr %ptr
 
   ret void
 }
 
 
-define void @any_true_splat_zero(ptr %ptr) {
-; CHECK-LABEL: define void @any_true_splat_zero(
+define void @any_true_splat_all_zero(ptr %ptr) {
+; CHECK-LABEL: define void @any_true_splat_all_zero(
 ; CHECK-SAME: ptr [[PTR:%.*]]) {
-; CHECK-NEXT:    store volatile i32 1, ptr [[PTR]], align 4
-; CHECK-NEXT:    store volatile i32 1, ptr [[PTR]], align 4
-; CHECK-NEXT:    store volatile i32 1, ptr [[PTR]], align 4
-; CHECK-NEXT:    store volatile i32 1, ptr [[PTR]], align 4
-; CHECK-NEXT:    store volatile i32 1, ptr [[PTR]], align 4
+; CHECK-NEXT:    store volatile i32 0, ptr [[PTR]], align 4
+; CHECK-NEXT:    store volatile i32 0, ptr [[PTR]], align 4
+; CHECK-NEXT:    store volatile i32 0, ptr [[PTR]], align 4
+; CHECK-NEXT:    store volatile i32 0, ptr [[PTR]], align 4
+; CHECK-NEXT:    store volatile i32 0, ptr [[PTR]], align 4
 ; CHECK-NEXT:    ret void
 ;
   %a = tail call i32 @llvm.wasm.anytrue(<16 x i8> <i8 0, i8 0, i8 0, i8 0, i8 0, i8 0, i8 0, i8 0, i8 0, i8 0, i8 0, i8 0, i8 0, i8 0, i8 0, i8 0>)
@@ -101,26 +101,26 @@ define void @any_true_splat_zero(ptr %ptr) {
 define void @any_true_splat_not_all_zero(ptr %ptr) {
 ; CHECK-LABEL: define void @any_true_splat_not_all_zero(
 ; CHECK-SAME: ptr [[PTR:%.*]]) {
-; CHECK-NEXT:    store volatile i32 0, ptr [[PTR]], align 4
-; CHECK-NEXT:    store volatile i32 0, ptr [[PTR]], align 4
-; CHECK-NEXT:    store volatile i32 0, ptr [[PTR]], align 4
-; CHECK-NEXT:    store volatile i32 0, ptr [[PTR]], align 4
-; CHECK-NEXT:    store volatile i32 0, ptr [[PTR]], align 4
+; CHECK-NEXT:    store volatile i32 1, ptr [[PTR]], align 4
+; CHECK-NEXT:    store volatile i32 1, ptr [[PTR]], align 4
+; CHECK-NEXT:    store volatile i32 1, ptr [[PTR]], align 4
+; CHECK-NEXT:    store volatile i32 1, ptr [[PTR]], align 4
+; CHECK-NEXT:    store volatile i32 1, ptr [[PTR]], align 4
 ; CHECK-NEXT:    ret void
 ;
   %a = tail call i32 @llvm.wasm.anytrue(<16 x i8> <i8 1, i8 0, i8 0, i8 0, i8 0, i8 0, i8 0, i8 0, i8 0, i8 0, i8 0, i8 0, i8 0, i8 0, i8 0, i8 0>)
   store volatile i32 %a, ptr %ptr
 
-  %b = tail call i32 @llvm.wasm.anytrue(<8 x i16> <i16 1, i16 0, i16 0, i16 0, i16 0, i16 0, i16 0, i16 0>)
+  %b = tail call i32 @llvm.wasm.anytrue(<8 x i16> <i16 3, i16 0, i16 0, i16 0, i16 0, i16 0, i16 0, i16 0>)
   store volatile i32 %b, ptr %ptr
 
   %c = tail call i32 @llvm.wasm.anytrue(<4 x i32> <i32 1, i32 0, i32 0, i32 0>)
   store volatile i32 %c, ptr %ptr
 
-  %d = tail call i32 @llvm.wasm.anytrue(<2 x i64> <i64 1, i64 0>)
+  %d = tail call i32 @llvm.wasm.anytrue(<2 x i64> <i64 -1, i64 0>)
   store volatile i32 %d, ptr %ptr
 
-  %e = tail call i32 @llvm.wasm.anytrue(<4 x i64> <i64 1, i64 0, i64 0, i64 0>)
+  %e = tail call i32 @llvm.wasm.anytrue(<4 x i64> <i64 2, i64 0, i64 0, i64 0>)
   store volatile i32 %e, ptr %ptr
 
   ret void

>From 06b2e1101b6ae7becbe78714da83503f256cf26f Mon Sep 17 00:00:00 2001
From: Jasmine Tang <jjasmine at igalia.com>
Date: Thu, 10 Jul 2025 18:43:29 -0700
Subject: [PATCH 4/6] Fix code formatting error

---
 llvm/lib/Analysis/ConstantFolding.cpp | 7 +++----
 1 file changed, 3 insertions(+), 4 deletions(-)

diff --git a/llvm/lib/Analysis/ConstantFolding.cpp b/llvm/lib/Analysis/ConstantFolding.cpp
index f0c3fdaa4e50d..9c1c2c6e60f02 100644
--- a/llvm/lib/Analysis/ConstantFolding.cpp
+++ b/llvm/lib/Analysis/ConstantFolding.cpp
@@ -2867,12 +2867,11 @@ static Constant *ConstantFoldScalarCall1(StringRef Name,
     case Intrinsic::wasm_alltrue:
       // Check each element individually
       unsigned E = cast<FixedVectorType>(Op->getType())->getNumElements();
-      for (unsigned I = 0; I != E; ++I) 
-        if (Constant *Elt = Op->getAggregateElement(I)) 
+      for (unsigned I = 0; I != E; ++I)
+        if (Constant *Elt = Op->getAggregateElement(I))
           if (Elt->isZeroValue())
             return ConstantInt::get(Ty, 0);
-        
-      
+
       return ConstantInt::get(Ty, 1);
     }
   }

>From 2a3f33a0d28e95d5a126306a20addea09cf76573 Mon Sep 17 00:00:00 2001
From: Jasmine Tang <jjasmine at igalia.com>
Date: Fri, 11 Jul 2025 14:43:15 -0700
Subject: [PATCH 5/6] Remove tail from tail call

---
 .../WebAssembly/const_fold_simd_intrinsics.ll | 44 +++++++++----------
 1 file changed, 22 insertions(+), 22 deletions(-)

diff --git a/llvm/test/CodeGen/WebAssembly/const_fold_simd_intrinsics.ll b/llvm/test/CodeGen/WebAssembly/const_fold_simd_intrinsics.ll
index 063bb8a810384..9dc11204a671b 100644
--- a/llvm/test/CodeGen/WebAssembly/const_fold_simd_intrinsics.ll
+++ b/llvm/test/CodeGen/WebAssembly/const_fold_simd_intrinsics.ll
@@ -12,8 +12,8 @@
 
 target triple = "wasm32-unknown-unknown"
 
-define void @all_true_splat_not_all_none_zero(ptr %ptr) {
-; CHECK-LABEL: define void @all_true_splat_not_all_none_zero(
+define void @all_true_splat_not_all_non_zero(ptr %ptr) {
+; CHECK-LABEL: define void @all_true_splat_not_all_non_zero(
 ; CHECK-SAME: ptr [[PTR:%.*]]) {
 ; CHECK-NEXT:    store volatile i32 0, ptr [[PTR]], align 4
 ; CHECK-NEXT:    store volatile i32 0, ptr [[PTR]], align 4
@@ -22,19 +22,19 @@ define void @all_true_splat_not_all_none_zero(ptr %ptr) {
 ; CHECK-NEXT:    store volatile i32 0, ptr [[PTR]], align 4
 ; CHECK-NEXT:    ret void
 ;
-  %a = tail call i32 @llvm.wasm.alltrue(<16 x i8> <i8 0, i8 1, i8 2, i8 1, i8 1, i8 1, i8 1, i8 1, i8 1, i8 1, i8 1, i8 1, i8 1, i8 1, i8 1, i8 1>)
+  %a = call i32 @llvm.wasm.alltrue(<16 x i8> <i8 0, i8 1, i8 2, i8 1, i8 1, i8 1, i8 1, i8 1, i8 1, i8 1, i8 1, i8 1, i8 1, i8 1, i8 1, i8 1>)
   store volatile i32 %a, ptr %ptr
 
-  %b = tail call i32 @llvm.wasm.alltrue(<8 x i16> <i16 0, i16 1, i16 2, i16 1, i16 1, i16 1, i16 1, i16 1>)
+  %b = call i32 @llvm.wasm.alltrue(<8 x i16> <i16 0, i16 1, i16 2, i16 1, i16 1, i16 1, i16 1, i16 1>)
   store volatile i32 %b, ptr %ptr
 
-  %c = tail call i32 @llvm.wasm.alltrue(<4 x i32> <i32 0, i32 1, i32 1, i32 1>)
+  %c = call i32 @llvm.wasm.alltrue(<4 x i32> <i32 0, i32 1, i32 1, i32 1>)
   store volatile i32 %c, ptr %ptr
 
-  %d = tail call i32 @llvm.wasm.alltrue(<2 x i64> <i64 0, i64 42>)
+  %d = call i32 @llvm.wasm.alltrue(<2 x i64> <i64 0, i64 42>)
   store volatile i32 %d, ptr %ptr
 
-  %e = tail call i32 @llvm.wasm.alltrue(<4 x i64> <i64 0, i64 1, i64 1, i64 1>)
+  %e = call i32 @llvm.wasm.alltrue(<4 x i64> <i64 0, i64 1, i64 1, i64 1>)
   store volatile i32 %e, ptr %ptr
 
   ret void
@@ -50,19 +50,19 @@ define void @all_true_splat_all_non_zero(ptr %ptr) {
 ; CHECK-NEXT:    store volatile i32 1, ptr [[PTR]], align 4
 ; CHECK-NEXT:    ret void
 ;
-  %a = tail call i32 @llvm.wasm.alltrue(<16 x i8> <i8 1, i8 3, i8 1, i8 1, i8 1, i8 1, i8 1, i8 1, i8 1, i8 1, i8 1, i8 1, i8 1, i8 1, i8 1, i8 1>)
+  %a = call i32 @llvm.wasm.alltrue(<16 x i8> <i8 1, i8 3, i8 1, i8 1, i8 1, i8 1, i8 1, i8 1, i8 1, i8 1, i8 1, i8 1, i8 1, i8 1, i8 1, i8 1>)
   store volatile i32 %a, ptr %ptr
 
-  %b = tail call i32 @llvm.wasm.alltrue(<8 x i16> <i16 1, i16 1, i16 1, i16 1, i16 1, i16 1, i16 1, i16 1>)
+  %b = call i32 @llvm.wasm.alltrue(<8 x i16> <i16 1, i16 1, i16 1, i16 1, i16 1, i16 1, i16 1, i16 1>)
   store volatile i32 %b, ptr %ptr
 
-  %c = tail call i32 @llvm.wasm.alltrue(<4 x i32> <i32 1, i32 1, i32 1, i32 1>)
+  %c = call i32 @llvm.wasm.alltrue(<4 x i32> <i32 1, i32 1, i32 1, i32 1>)
   store volatile i32 %c, ptr %ptr
 
-  %d = tail call i32 @llvm.wasm.alltrue(<2 x i64> <i64 2, i64 2>)
+  %d = call i32 @llvm.wasm.alltrue(<2 x i64> <i64 2, i64 2>)
   store volatile i32 %d, ptr %ptr
 
-  %e = tail call i32 @llvm.wasm.alltrue(<4 x i64> <i64 1, i64 2, i64 1, i64 1>)
+  %e = call i32 @llvm.wasm.alltrue(<4 x i64> <i64 1, i64 2, i64 1, i64 1>)
   store volatile i32 %e, ptr %ptr
 
   ret void
@@ -79,19 +79,19 @@ define void @any_true_splat_all_zero(ptr %ptr) {
 ; CHECK-NEXT:    store volatile i32 0, ptr [[PTR]], align 4
 ; CHECK-NEXT:    ret void
 ;
-  %a = tail call i32 @llvm.wasm.anytrue(<16 x i8> <i8 0, i8 0, i8 0, i8 0, i8 0, i8 0, i8 0, i8 0, i8 0, i8 0, i8 0, i8 0, i8 0, i8 0, i8 0, i8 0>)
+  %a = call i32 @llvm.wasm.anytrue(<16 x i8> <i8 0, i8 0, i8 0, i8 0, i8 0, i8 0, i8 0, i8 0, i8 0, i8 0, i8 0, i8 0, i8 0, i8 0, i8 0, i8 0>)
   store volatile i32 %a, ptr %ptr
 
-  %b = tail call i32 @llvm.wasm.anytrue(<8 x i16> <i16 0, i16 0, i16 0, i16 0, i16 0, i16 0, i16 0, i16 0>)
+  %b = call i32 @llvm.wasm.anytrue(<8 x i16> <i16 0, i16 0, i16 0, i16 0, i16 0, i16 0, i16 0, i16 0>)
   store volatile i32 %b, ptr %ptr
 
-  %c = tail call i32 @llvm.wasm.anytrue(<4 x i32> <i32 0, i32 0, i32 0, i32 0>)
+  %c = call i32 @llvm.wasm.anytrue(<4 x i32> <i32 0, i32 0, i32 0, i32 0>)
   store volatile i32 %c, ptr %ptr
 
-  %d = tail call i32 @llvm.wasm.anytrue(<2 x i64> <i64 0, i64 0>)
+  %d = call i32 @llvm.wasm.anytrue(<2 x i64> <i64 0, i64 0>)
   store volatile i32 %d, ptr %ptr
 
-  %e = tail call i32 @llvm.wasm.anytrue(<4 x i64> <i64 0, i64 0, i64 0, i64 0>)
+  %e = call i32 @llvm.wasm.anytrue(<4 x i64> <i64 0, i64 0, i64 0, i64 0>)
   store volatile i32 %e, ptr %ptr
 
   ret void
@@ -108,19 +108,19 @@ define void @any_true_splat_not_all_zero(ptr %ptr) {
 ; CHECK-NEXT:    store volatile i32 1, ptr [[PTR]], align 4
 ; CHECK-NEXT:    ret void
 ;
-  %a = tail call i32 @llvm.wasm.anytrue(<16 x i8> <i8 1, i8 0, i8 0, i8 0, i8 0, i8 0, i8 0, i8 0, i8 0, i8 0, i8 0, i8 0, i8 0, i8 0, i8 0, i8 0>)
+  %a = call i32 @llvm.wasm.anytrue(<16 x i8> <i8 1, i8 0, i8 0, i8 0, i8 0, i8 0, i8 0, i8 0, i8 0, i8 0, i8 0, i8 0, i8 0, i8 0, i8 0, i8 0>)
   store volatile i32 %a, ptr %ptr
 
-  %b = tail call i32 @llvm.wasm.anytrue(<8 x i16> <i16 3, i16 0, i16 0, i16 0, i16 0, i16 0, i16 0, i16 0>)
+  %b = call i32 @llvm.wasm.anytrue(<8 x i16> <i16 3, i16 0, i16 0, i16 0, i16 0, i16 0, i16 0, i16 0>)
   store volatile i32 %b, ptr %ptr
 
-  %c = tail call i32 @llvm.wasm.anytrue(<4 x i32> <i32 1, i32 0, i32 0, i32 0>)
+  %c = call i32 @llvm.wasm.anytrue(<4 x i32> <i32 1, i32 0, i32 0, i32 0>)
   store volatile i32 %c, ptr %ptr
 
-  %d = tail call i32 @llvm.wasm.anytrue(<2 x i64> <i64 -1, i64 0>)
+  %d = call i32 @llvm.wasm.anytrue(<2 x i64> <i64 -1, i64 0>)
   store volatile i32 %d, ptr %ptr
 
-  %e = tail call i32 @llvm.wasm.anytrue(<4 x i64> <i64 2, i64 0, i64 0, i64 0>)
+  %e = call i32 @llvm.wasm.anytrue(<4 x i64> <i64 2, i64 0, i64 0, i64 0>)
   store volatile i32 %e, ptr %ptr
 
   ret void

>From e8c031c06cd45567e0318be0d3c4c3b24e62592f Mon Sep 17 00:00:00 2001
From: Jasmine Tang <jjasmine at igalia.com>
Date: Sun, 13 Jul 2025 07:17:29 -0700
Subject: [PATCH 6/6] Move test from codegen to transform/, use instsimplify

---
 .../InstSimplify/const-fold-wasm-simd-intrinsics.ll}            | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)
 rename llvm/test/{CodeGen/WebAssembly/const_fold_simd_intrinsics.ll => Transforms/InstSimplify/const-fold-wasm-simd-intrinsics.ll} (98%)

diff --git a/llvm/test/CodeGen/WebAssembly/const_fold_simd_intrinsics.ll b/llvm/test/Transforms/InstSimplify/const-fold-wasm-simd-intrinsics.ll
similarity index 98%
rename from llvm/test/CodeGen/WebAssembly/const_fold_simd_intrinsics.ll
rename to llvm/test/Transforms/InstSimplify/const-fold-wasm-simd-intrinsics.ll
index 9dc11204a671b..7b30edbf7792b 100644
--- a/llvm/test/CodeGen/WebAssembly/const_fold_simd_intrinsics.ll
+++ b/llvm/test/Transforms/InstSimplify/const-fold-wasm-simd-intrinsics.ll
@@ -1,6 +1,6 @@
 ; NOTE: Assertions have been autogenerated by utils/update_test_checks.py UTC_ARGS: --version 5
 
-; RUN: opt -passes=instcombine -S < %s | FileCheck %s
+; RUN: opt -passes=instsimplify -S < %s | FileCheck %s
 
 ; Test that intrinsics wasm call are constant folded
 



More information about the llvm-commits mailing list