1; RUN: llc < %s -asm-verbose=false -verify-machineinstrs -wasm-keep-registers -disable-wasm-fallthrough-return-opt -wasm-disable-explicit-locals -mcpu=mvp -mattr=+simd128 | FileCheck %s --check-prefixes CHECK,SIMD128 2; RUN: llc < %s -asm-verbose=false -verify-machineinstrs -wasm-keep-registers -disable-wasm-fallthrough-return-opt -wasm-disable-explicit-locals | FileCheck %s --check-prefixes CHECK,NO-SIMD128 3 4; Test that vector sign extensions lower to shifts 5 6target triple = "wasm32-unknown-unknown" 7 8; CHECK-LABEL: sext_v16i8: 9; NO-SIMD128-NOT: i8x16 10; SIMD128-NEXT: .functype sext_v16i8 (v128) -> (v128){{$}} 11; SIMD128-NEXT: i32.const $push[[T0:[0-9]+]]=, 7{{$}} 12; SIMD128-NEXT: i8x16.shl $push[[T1:[0-9]+]]=, $0, $pop[[T0]]{{$}} 13; SIMD128-NEXT: i32.const $push[[T2:[0-9]+]]=, 7{{$}} 14; SIMD128-NEXT: i8x16.shr_s $push[[R:[0-9]+]]=, $pop[[T1]], $pop[[T2]]{{$}} 15; SIMD128-NEXT: return $pop[[R]]{{$}} 16define <16 x i8> @sext_v16i8(<16 x i1> %x) { 17 %res = sext <16 x i1> %x to <16 x i8> 18 ret <16 x i8> %res 19} 20 21; CHECK-LABEL: sext_v8i16: 22; NO-SIMD128-NOT: i16x8 23; SIMD128-NEXT: .functype sext_v8i16 (v128) -> (v128){{$}} 24; SIMD128-NEXT: i32.const $push[[T0:[0-9]+]]=, 15{{$}} 25; SIMD128-NEXT: i16x8.shl $push[[T1:[0-9]+]]=, $0, $pop[[T0]]{{$}} 26; SIMD128-NEXT: i32.const $push[[T2:[0-9]+]]=, 15{{$}} 27; SIMD128-NEXT: i16x8.shr_s $push[[R:[0-9]+]]=, $pop[[T1]], $pop[[T2]]{{$}} 28; SIMD128-NEXT: return $pop[[R]]{{$}} 29define <8 x i16> @sext_v8i16(<8 x i1> %x) { 30 %res = sext <8 x i1> %x to <8 x i16> 31 ret <8 x i16> %res 32} 33 34; CHECK-LABEL: sext_v4i32: 35; NO-SIMD128-NOT: i32x4 36; SIMD128-NEXT: .functype sext_v4i32 (v128) -> (v128){{$}} 37; SIMD128-NEXT: i32.const $push[[T0:[0-9]+]]=, 31{{$}} 38; SIMD128-NEXT: i32x4.shl $push[[T1:[0-9]+]]=, $0, $pop[[T0]]{{$}} 39; SIMD128-NEXT: i32.const $push[[T2:[0-9]+]]=, 31{{$}} 40; SIMD128-NEXT: i32x4.shr_s $push[[R:[0-9]+]]=, $pop[[T1]], $pop[[T2]]{{$}} 41; SIMD128-NEXT: return $pop[[R]]{{$}} 42define <4 x i32> @sext_v4i32(<4 x i1> %x) { 43 %res = sext <4 x i1> %x to <4 x i32> 44 ret <4 x i32> %res 45} 46 47; CHECK-LABEL: sext_v2i64: 48; NO-SIMD128-NOT: i64x2 49; SIMD128-NEXT: .functype sext_v2i64 (v128) -> (v128){{$}} 50; SIMD128-NEXT: i32.const $push[[T0:[0-9]+]]=, 63{{$}} 51; SIMD128-NEXT: i64x2.shl $push[[T1:[0-9]+]]=, $0, $pop[[T0]]{{$}} 52; SIMD128-NEXT: i32.const $push[[T2:[0-9]+]]=, 63{{$}} 53; SIMD128-NEXT: i64x2.shr_s $push[[R:[0-9]+]]=, $pop[[T1]], $pop[[T2]]{{$}} 54; SIMD128-NEXT: return $pop[[R]]{{$}} 55define <2 x i64> @sext_v2i64(<2 x i1> %x) { 56 %res = sext <2 x i1> %x to <2 x i64> 57 ret <2 x i64> %res 58} 59 60; CHECK-LABEL: sext_inreg_i8_to_i16: 61; SIMD128-NEXT: .functype sext_inreg_i8_to_i16 (v128) -> (i32){{$}} 62; SIMD128-NEXT: i8x16.extract_lane_s $push[[R:[0-9]+]]=, $0, 2{{$}} 63; SIMD128-NEXT: return $pop[[R]]{{$}} 64define i16 @sext_inreg_i8_to_i16(<8 x i16> %x) { 65 %lane = extractelement <8 x i16> %x, i32 1 66 %a = shl i16 %lane, 8 67 %res = ashr i16 %a, 8 68 ret i16 %res 69} 70 71; CHECK-LABEL: sext_inreg_i8_to_i32: 72; SIMD128-NEXT: .functype sext_inreg_i8_to_i32 (v128) -> (i32){{$}} 73; SIMD128-NEXT: i8x16.extract_lane_s $push[[R:[0-9]+]]=, $0, 4{{$}} 74; SIMD128-NEXT: return $pop[[R]]{{$}} 75define i32 @sext_inreg_i8_to_i32(<4 x i32> %x) { 76 %lane = extractelement <4 x i32> %x, i32 1 77 %a = shl i32 %lane, 24 78 %res = ashr i32 %a, 24 79 ret i32 %res 80} 81 82; CHECK-LABEL: sext_inreg_i16_to_i32: 83; SIMD128-NEXT: .functype sext_inreg_i16_to_i32 (v128) -> (i32){{$}} 84; SIMD128-NEXT: i16x8.extract_lane_s $push[[R:[0-9]+]]=, $0, 2{{$}} 85; SIMD128-NEXT: return $pop[[R]]{{$}} 86define i32 @sext_inreg_i16_to_i32(<4 x i32> %x) { 87 %lane = extractelement <4 x i32> %x, i32 1 88 %a = shl i32 %lane, 16 89 %res = ashr i32 %a, 16 90 ret i32 %res 91} 92 93; CHECK-LABEL: sext_inreg_i8_to_i64: 94; SIMD128-NEXT: .functype sext_inreg_i8_to_i64 (v128) -> (i64){{$}} 95; SIMD128-NEXT: i64x2.extract_lane $push[[T0:[0-9]+]]=, $0, 1{{$}} 96; SIMD128-NEXT: i64.const $push[[T1:[0-9]+]]=, 56{{$}} 97; SIMD128-NEXT: i64.shl $push[[T2:[0-9]+]]=, $pop[[T0]], $pop[[T1]]{{$}} 98; SIMD128-NEXT: i64.const $push[[T3:[0-9]+]]=, 56{{$}} 99; SIMD128-NEXT: i64.shr_s $push[[R:[0-9]+]]=, $pop[[T2]], $pop[[T3]]{{$}} 100; SIMD128-NEXT: return $pop[[R]]{{$}} 101define i64 @sext_inreg_i8_to_i64(<2 x i64> %x) { 102 %lane = extractelement <2 x i64> %x, i32 1 103 %a = shl i64 %lane, 56 104 %res = ashr i64 %a, 56 105 ret i64 %res 106} 107 108; CHECK-LABEL: sext_inreg_i16_to_i64: 109; SIMD128-NEXT: .functype sext_inreg_i16_to_i64 (v128) -> (i64){{$}} 110; SIMD128-NEXT: i64x2.extract_lane $push[[T0:[0-9]+]]=, $0, 1{{$}} 111; SIMD128-NEXT: i64.const $push[[T1:[0-9]+]]=, 48{{$}} 112; SIMD128-NEXT: i64.shl $push[[T2:[0-9]+]]=, $pop[[T0]], $pop[[T1]]{{$}} 113; SIMD128-NEXT: i64.const $push[[T3:[0-9]+]]=, 48{{$}} 114; SIMD128-NEXT: i64.shr_s $push[[R:[0-9]+]]=, $pop[[T2]], $pop[[T3]]{{$}} 115; SIMD128-NEXT: return $pop[[R]]{{$}} 116define i64 @sext_inreg_i16_to_i64(<2 x i64> %x) { 117 %lane = extractelement <2 x i64> %x, i32 1 118 %a = shl i64 %lane, 48 119 %res = ashr i64 %a, 48 120 ret i64 %res 121} 122 123; CHECK-LABEL: sext_inreg_i32_to_i64: 124; NO-SIMD128-NOT: i64x2 125; SIMD128-NEXT: .functype sext_inreg_i32_to_i64 (v128) -> (i64){{$}} 126; SIMD128-NEXT: i64x2.extract_lane $push[[T0:[0-9]+]]=, $0, 1{{$}} 127; SIMD128-NEXT: i64.const $push[[T1:[0-9]+]]=, 32{{$}} 128; SIMD128-NEXT: i64.shl $push[[T2:[0-9]+]]=, $pop[[T0]], $pop[[T1]]{{$}} 129; SIMD128-NEXT: i64.const $push[[T3:[0-9]+]]=, 32{{$}} 130; SIMD128-NEXT: i64.shr_s $push[[R:[0-9]+]]=, $pop[[T2]], $pop[[T3]]{{$}} 131; SIMD128-NEXT: return $pop[[R]]{{$}} 132define i64 @sext_inreg_i32_to_i64(<2 x i64> %x) { 133 %lane = extractelement <2 x i64> %x, i32 1 134 %a = shl i64 %lane, 32 135 %res = ashr i64 %a, 32 136 ret i64 %res 137} 138