; NOTE: Assertions have been autogenerated by utils/update_test_checks.py UTC_ARGS: --version 5

; RUN: opt -passes=instsimplify -S < %s | FileCheck %s

; Test that intrinsics wasm call are constant folded

; 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 a non-zero in the first location

target triple = "wasm32-unknown-unknown"

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
; 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 = 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 = 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 = call i32 @llvm.wasm.alltrue(<4 x i32> <i32 0, i32 1, i32 1, i32 1>)
  store volatile i32 %c, ptr %ptr

  %d = call i32 @llvm.wasm.alltrue(<2 x i64> <i64 0, i64 42>)
  store volatile i32 %d, ptr %ptr

  %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
}

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 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 = 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 = 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 = call i32 @llvm.wasm.alltrue(<4 x i32> <i32 1, i32 1, i32 1, i32 1>)
  store volatile i32 %c, ptr %ptr

  %d = call i32 @llvm.wasm.alltrue(<2 x i64> <i64 2, i64 2>)
  store volatile i32 %d, ptr %ptr

  %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
}


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 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 = 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 = 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 = call i32 @llvm.wasm.anytrue(<4 x i32> <i32 0, i32 0, i32 0, i32 0>)
  store volatile i32 %c, ptr %ptr

  %d = call i32 @llvm.wasm.anytrue(<2 x i64> <i64 0, i64 0>)
  store volatile i32 %d, ptr %ptr

  %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
}


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 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 = 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 = 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 = call i32 @llvm.wasm.anytrue(<4 x i32> <i32 1, i32 0, i32 0, i32 0>)
  store volatile i32 %c, ptr %ptr

  %d = call i32 @llvm.wasm.anytrue(<2 x i64> <i64 -1, i64 0>)
  store volatile i32 %d, ptr %ptr

  %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
}
