blob: 00c6b6519646519874bbedfd00c8f546e9402589 [file] [edit]
; NOTE: Assertions have been autogenerated by utils/update_llc_test_checks.py UTC_ARGS: --version 6
; RUN: llc < %s -fast-isel -fast-isel-abort=0 -mattr=+simd128 -verify-machineinstrs | FileCheck %s
; RUN: llc < %s -mtriple=wasm64 -fast-isel -fast-isel-abort=0 -mattr=+simd128 -verify-machineinstrs | FileCheck %s
target triple = "wasm32-unknown-unknown"
define i8 @pr165438(<4 x i32> %0) {
; CHECK-LABEL: pr165438:
; CHECK: .functype pr165438 (v128) -> (i32)
; CHECK-NEXT: # %bb.0: # %entry
; CHECK-NEXT: local.get 0
; CHECK-NEXT: local.get 0
; CHECK-NEXT: i8x16.shuffle 0, 4, 8, 12, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0
; CHECK-NEXT: i8x16.extract_lane_u 0
; CHECK-NEXT: # fallthrough-return
entry:
%conv = trunc <4 x i32> %0 to <4 x i8>
br label %cond.true
cond.true: ; preds = %entry
%vecext = extractelement <4 x i8> %conv, i32 0
ret i8 %vecext
}
; selectICmp classifies any non-i64 operand as i32 and selectFCmp any
; non-f64 operand as f32, so without the vector bail-out a vector
; compare takes the FastISel path and emits a scalar i32.eq/f32.eq over
; v128 registers, failing module validation. FastISel has no vector
; compare lowering of its own, so a valid SIMD compare can only come
; from the SelectionDAG fallback; the wasm64 RUN re-runs the same checks
; under the triple the mis-lowering was found with. The scalar eq_i32
; guards that the bail-out is vector-only.
declare i1 @any16(<16 x i1>)
declare i1 @any4(<4 x i1>)
define i32 @eq_i8x16(<16 x i8> %a, <16 x i8> %b) {
; CHECK-LABEL: eq_i8x16:
; CHECK: .functype eq_i8x16 (v128, v128) -> (i32)
; CHECK-NEXT: # %bb.0: # %entry
; CHECK-NEXT: local.get 0
; CHECK-NEXT: local.get 1
; CHECK-NEXT: i8x16.ne
; CHECK-NEXT: call any16
; CHECK-NEXT: i32.const 1
; CHECK-NEXT: i32.and
; CHECK-NEXT: # fallthrough-return
entry:
%c = icmp ne <16 x i8> %a, %b
%r = call i1 @any16(<16 x i1> %c)
%z = zext i1 %r to i32
ret i32 %z
}
define i32 @eq_f32x4(<4 x float> %a, <4 x float> %b) {
; CHECK-LABEL: eq_f32x4:
; CHECK: .functype eq_f32x4 (v128, v128) -> (i32)
; CHECK-NEXT: # %bb.0: # %entry
; CHECK-NEXT: local.get 0
; CHECK-NEXT: local.get 1
; CHECK-NEXT: f32x4.eq
; CHECK-NEXT: call any4
; CHECK-NEXT: i32.const 1
; CHECK-NEXT: i32.and
; CHECK-NEXT: # fallthrough-return
entry:
%c = fcmp oeq <4 x float> %a, %b
%r = call i1 @any4(<4 x i1> %c)
%z = zext i1 %r to i32
ret i32 %z
}
define i32 @eq_i32(i32 %a, i32 %b) {
; CHECK-LABEL: eq_i32:
; CHECK: .functype eq_i32 (i32, i32) -> (i32)
; CHECK-NEXT: # %bb.0: # %entry
; CHECK-NEXT: local.get 0
; CHECK-NEXT: local.get 1
; CHECK-NEXT: i32.eq
; CHECK-NEXT: i32.const 1
; CHECK-NEXT: i32.and
; CHECK-NEXT: # fallthrough-return
entry:
%c = icmp eq i32 %a, %b
%z = zext i1 %c to i32
ret i32 %z
}