| ; NOTE: Assertions have been autogenerated by utils/update_test_checks.py UTC_ARGS: --version 6 |
| ; RUN: opt < %s -passes=vector-combine -S -mtriple=x86_64-- -mattr=SSE2 | FileCheck %s --check-prefixes=CHECK,SSE |
| ; RUN: opt < %s -passes=vector-combine -S -mtriple=x86_64-- -mattr=AVX2 | FileCheck %s --check-prefixes=CHECK,AVX |
| |
| define i64 @fold_scalar_i64(i64 %0) { |
| ; SSE-LABEL: define i64 @fold_scalar_i64( |
| ; SSE-SAME: i64 [[TMP0:%.*]]) #[[ATTR0:[0-9]+]] { |
| ; SSE-NEXT: [[T1:%.*]] = tail call i64 @llvm.bswap.i64(i64 [[TMP0]]) |
| ; SSE-NEXT: [[T2:%.*]] = tail call i64 @llvm.bitreverse.i64(i64 [[T1]]) |
| ; SSE-NEXT: ret i64 [[T2]] |
| ; |
| ; AVX-LABEL: define i64 @fold_scalar_i64( |
| ; AVX-SAME: i64 [[TMP0:%.*]]) #[[ATTR0:[0-9]+]] { |
| ; AVX-NEXT: [[TMP2:%.*]] = bitcast i64 [[TMP0]] to <8 x i8> |
| ; AVX-NEXT: [[TMP3:%.*]] = call <8 x i8> @llvm.bitreverse.v8i8(<8 x i8> [[TMP2]]) |
| ; AVX-NEXT: [[T2:%.*]] = bitcast <8 x i8> [[TMP3]] to i64 |
| ; AVX-NEXT: ret i64 [[T2]] |
| ; |
| %t1 = tail call i64 @llvm.bswap.i64(i64 %0) |
| %t2 = tail call i64 @llvm.bitreverse.i64(i64 %t1) |
| ret i64 %t2 |
| } |
| |
| define <2 x i64> @fold_vector_v2i64(<2 x i64> %0) { |
| ; CHECK-LABEL: define <2 x i64> @fold_vector_v2i64( |
| ; CHECK-SAME: <2 x i64> [[TMP0:%.*]]) #[[ATTR0:[0-9]+]] { |
| ; CHECK-NEXT: [[TMP2:%.*]] = bitcast <2 x i64> [[TMP0]] to <16 x i8> |
| ; CHECK-NEXT: [[TMP3:%.*]] = call <16 x i8> @llvm.bitreverse.v16i8(<16 x i8> [[TMP2]]) |
| ; CHECK-NEXT: [[T2:%.*]] = bitcast <16 x i8> [[TMP3]] to <2 x i64> |
| ; CHECK-NEXT: ret <2 x i64> [[T2]] |
| ; |
| %t1 = tail call <2 x i64> @llvm.bitreverse.v2i64(<2 x i64> %0) |
| %t2 = tail call <2 x i64> @llvm.bswap.v2i64(<2 x i64> %t1) |
| ret <2 x i64> %t2 |
| } |
| |
| define i32 @fold_scalar_i32(i32 %0) { |
| ; SSE-LABEL: define i32 @fold_scalar_i32( |
| ; SSE-SAME: i32 [[TMP0:%.*]]) #[[ATTR0]] { |
| ; SSE-NEXT: [[T1:%.*]] = tail call i32 @llvm.bswap.i32(i32 [[TMP0]]) |
| ; SSE-NEXT: [[T2:%.*]] = tail call i32 @llvm.bitreverse.i32(i32 [[T1]]) |
| ; SSE-NEXT: ret i32 [[T2]] |
| ; |
| ; AVX-LABEL: define i32 @fold_scalar_i32( |
| ; AVX-SAME: i32 [[TMP0:%.*]]) #[[ATTR0]] { |
| ; AVX-NEXT: [[TMP2:%.*]] = bitcast i32 [[TMP0]] to <4 x i8> |
| ; AVX-NEXT: [[TMP3:%.*]] = call <4 x i8> @llvm.bitreverse.v4i8(<4 x i8> [[TMP2]]) |
| ; AVX-NEXT: [[T2:%.*]] = bitcast <4 x i8> [[TMP3]] to i32 |
| ; AVX-NEXT: ret i32 [[T2]] |
| ; |
| %t1 = tail call i32 @llvm.bswap.i32(i32 %0) |
| %t2 = tail call i32 @llvm.bitreverse.i32(i32 %t1) |
| ret i32 %t2 |
| } |
| |
| define <4 x i32> @fold_vector_v4i32(<4 x i32> %0) { |
| ; CHECK-LABEL: define <4 x i32> @fold_vector_v4i32( |
| ; CHECK-SAME: <4 x i32> [[TMP0:%.*]]) #[[ATTR0]] { |
| ; CHECK-NEXT: [[TMP2:%.*]] = bitcast <4 x i32> [[TMP0]] to <16 x i8> |
| ; CHECK-NEXT: [[TMP3:%.*]] = call <16 x i8> @llvm.bitreverse.v16i8(<16 x i8> [[TMP2]]) |
| ; CHECK-NEXT: [[T2:%.*]] = bitcast <16 x i8> [[TMP3]] to <4 x i32> |
| ; CHECK-NEXT: ret <4 x i32> [[T2]] |
| ; |
| %t1 = tail call <4 x i32> @llvm.bswap.v4i32(<4 x i32> %0) |
| %t2 = tail call <4 x i32> @llvm.bitreverse.v4i32(<4 x i32> %t1) |
| ret <4 x i32> %t2 |
| } |
| |
| define <vscale x 2 x i16> @fold_scalable(<vscale x 2 x i16> %x) { |
| ; CHECK-LABEL: define <vscale x 2 x i16> @fold_scalable( |
| ; CHECK-SAME: <vscale x 2 x i16> [[X:%.*]]) #[[ATTR0]] { |
| ; CHECK-NEXT: [[T1:%.*]] = call <vscale x 2 x i16> @llvm.bswap.nxv2i16(<vscale x 2 x i16> [[X]]) |
| ; CHECK-NEXT: [[T2:%.*]] = call <vscale x 2 x i16> @llvm.bitreverse.nxv2i16(<vscale x 2 x i16> [[T1]]) |
| ; CHECK-NEXT: ret <vscale x 2 x i16> [[T2]] |
| ; |
| %t1 = call <vscale x 2 x i16> @llvm.bswap.nxv2i16(<vscale x 2 x i16> %x) |
| %t2 = call <vscale x 2 x i16> @llvm.bitreverse.nxv2i16(<vscale x 2 x i16> %t1) |
| ret <vscale x 2 x i16> %t2 |
| } |