; NOTE: Assertions have been autogenerated by utils/update_test_checks.py UTC_ARGS: --version 6 ; RUN: opt < %s -passes=instcombine -mtriple=wasm32-unknown-unknown -S | FileCheck %s ; REQUIRES: testStabilty ; swizzle with a constant operand should be optimized to a shufflevector. ; Identity swizzle pattern define <16 x i8> @swizzle_identity(<16 x i8> %v) { ; CHECK-LABEL: define <16 x i8> @swizzle_identity( ; CHECK-SAME: <16 x i8> [[V:%.*]]) { ; CHECK-NEXT: ret <16 x i8> [[V]] ; %result = tail call <16 x i8> @llvm.wasm.swizzle(<16 x i8> %v, <16 x i8> ) ret <16 x i8> %result } ; Reverse swizzle pattern define <16 x i8> @swizzle_reverse(<16 x i8> %v) { ; CHECK-LABEL: define <16 x i8> @swizzle_reverse( ; CHECK-SAME: <16 x i8> [[V:%.*]]) { ; CHECK-NEXT: [[RESULT:%.*]] = shufflevector <16 x i8> [[V]], <16 x i8> poison, <16 x i32> ; CHECK-NEXT: ret <16 x i8> [[RESULT]] ; %result = tail call <16 x i8> @llvm.wasm.swizzle(<16 x i8> %v, <16 x i8> ) ret <16 x i8> %result } ; poison elements define <16 x i8> @swizzle_with_poison(<16 x i8> %v) { ; CHECK-LABEL: define <16 x i8> @swizzle_with_poison( ; CHECK-SAME: <16 x i8> [[V:%.*]]) { ; CHECK-NEXT: [[RESULT:%.*]] = shufflevector <16 x i8> [[V]], <16 x i8> poison, <16 x i32> ; CHECK-NEXT: ret <16 x i8> [[RESULT]] ; %result = tail call <16 x i8> @llvm.wasm.swizzle(<16 x i8> %v, <16 x i8> ) ret <16 x i8> %result } ; Negative test: non-constant operand define <16 x i8> @swizzle_non_constant(<16 x i8> %v, <16 x i8> %mask) { ; CHECK-LABEL: define <16 x i8> @swizzle_non_constant( ; CHECK-SAME: <16 x i8> [[V:%.*]], <16 x i8> [[MASK:%.*]]) { ; CHECK-NEXT: [[RESULT:%.*]] = tail call <16 x i8> @llvm.wasm.swizzle(<16 x i8> [[V]], <16 x i8> [[MASK]]) ; CHECK-NEXT: ret <16 x i8> [[RESULT]] ; %result = tail call <16 x i8> @llvm.wasm.swizzle(<16 x i8> %v, <16 x i8> %mask) ret <16 x i8> %result } ; Out-of-bounds index, otherwise identity pattern define <16 x i8> @swizzle_out_of_bounds_1(<16 x i8> %v) { ; CHECK-LABEL: define <16 x i8> @swizzle_out_of_bounds_1( ; CHECK-SAME: <16 x i8> [[V:%.*]]) { ; CHECK-NEXT: [[RESULT1:%.*]] = insertelement <16 x i8> [[V]], i8 0, i64 15 ; CHECK-NEXT: ret <16 x i8> [[RESULT1]] ; %result = tail call <16 x i8> @llvm.wasm.swizzle(<16 x i8> %v, <16 x i8> ) ret <16 x i8> %result } ; Out-of-bounds indices, both negative and positive define <16 x i8> @swizzle_out_of_bounds_2(<16 x i8> %v) { ; CHECK-LABEL: define <16 x i8> @swizzle_out_of_bounds_2( ; CHECK-SAME: <16 x i8> [[V:%.*]]) { ; CHECK-NEXT: [[RESULT:%.*]] = shufflevector <16 x i8> [[V]], <16 x i8> , <16 x i32> ; CHECK-NEXT: ret <16 x i8> [[RESULT]] ; %result = tail call <16 x i8> @llvm.wasm.swizzle(<16 x i8> %v, <16 x i8> ) ret <16 x i8> %result } ; Identity swizzle pattern (relaxed_swizzle) define <16 x i8> @relaxed_swizzle_identity(<16 x i8> %v) { ; CHECK-LABEL: define <16 x i8> @relaxed_swizzle_identity( ; CHECK-SAME: <16 x i8> [[V:%.*]]) { ; CHECK-NEXT: ret <16 x i8> [[V]] ; %result = tail call <16 x i8> @llvm.wasm.relaxed.swizzle(<16 x i8> %v, <16 x i8> ) ret <16 x i8> %result } ; Reverse swizzle pattern (relaxed_swizzle) define <16 x i8> @relaxed_swizzle_reverse(<16 x i8> %v) { ; CHECK-LABEL: define <16 x i8> @relaxed_swizzle_reverse( ; CHECK-SAME: <16 x i8> [[V:%.*]]) { ; CHECK-NEXT: [[RESULT:%.*]] = shufflevector <16 x i8> [[V]], <16 x i8> poison, <16 x i32> ; CHECK-NEXT: ret <16 x i8> [[RESULT]] ; %result = tail call <16 x i8> @llvm.wasm.relaxed.swizzle(<16 x i8> %v, <16 x i8> ) ret <16 x i8> %result } ; Out-of-bounds index, only negative (relaxed_swizzle) define <16 x i8> @relaxed_swizzle_out_of_bounds(<16 x i8> %v) { ; CHECK-LABEL: define <16 x i8> @relaxed_swizzle_out_of_bounds( ; CHECK-SAME: <16 x i8> [[V:%.*]]) { ; CHECK-NEXT: [[RESULT:%.*]] = shufflevector <16 x i8> [[V]], <16 x i8> , <16 x i32> ; CHECK-NEXT: ret <16 x i8> [[RESULT]] ; %result = tail call <16 x i8> @llvm.wasm.relaxed.swizzle(<16 x i8> %v, <16 x i8> ) ret <16 x i8> %result } ; Negative test: out-of-bounds index, both positive and negative (relaxed_swizzle) ; The choice between different relaxed semantics can only be made at runtime, since it must be consistent. define <16 x i8> @relaxed_swizzle_out_of_bounds_positive(<16 x i8> %v) { ; CHECK-LABEL: define <16 x i8> @relaxed_swizzle_out_of_bounds_positive( ; CHECK-SAME: <16 x i8> [[V:%.*]]) { ; CHECK-NEXT: [[RESULT:%.*]] = tail call <16 x i8> @llvm.wasm.relaxed.swizzle(<16 x i8> [[V]], <16 x i8> ) ; CHECK-NEXT: ret <16 x i8> [[RESULT]] ; %result = tail call <16 x i8> @llvm.wasm.relaxed.swizzle(<16 x i8> %v, <16 x i8> ) ret <16 x i8> %result }