blob: 604695cb05b3a5ed615c7fe1392dd684df0c5136 [file]
; NOTE: Assertions have been autogenerated by utils/update_test_checks.py
; RUN: opt < %s -passes=slp-vectorizer -mtriple=riscv64 -mattr=+v \
; RUN: -riscv-v-vector-bits-min=-1 -riscv-v-slp-max-vf=0 -S | FileCheck %s
; RUN: opt < %s -passes=slp-vectorizer -mtriple=riscv64 -mattr=+v -S | FileCheck %s
define void @simple_copy(ptr %dest, ptr %p) {
; CHECK-LABEL: @simple_copy(
; CHECK-NEXT: entry:
; CHECK-NEXT: [[TMP0:%.*]] = load <2 x i16>, ptr [[P:%.*]], align 4
; CHECK-NEXT: store <2 x i16> [[TMP0]], ptr [[DEST:%.*]], align 4
; CHECK-NEXT: ret void
;
entry:
%e0 = load i16, ptr %p, align 4
%inc = getelementptr inbounds i16, ptr %p, i64 1
%e1 = load i16, ptr %inc, align 2
store i16 %e0, ptr %dest, align 4
%inc2 = getelementptr inbounds i16, ptr %dest, i64 1
store i16 %e1, ptr %inc2, align 2
ret void
}
define void @vec_add(ptr %dest, ptr %p) {
; CHECK-LABEL: @vec_add(
; CHECK-NEXT: entry:
; CHECK-NEXT: [[TMP0:%.*]] = load <2 x i16>, ptr [[P:%.*]], align 4
; CHECK-NEXT: [[TMP1:%.*]] = add <2 x i16> [[TMP0]], splat (i16 1)
; CHECK-NEXT: store <2 x i16> [[TMP1]], ptr [[DEST:%.*]], align 4
; CHECK-NEXT: ret void
;
entry:
%e0 = load i16, ptr %p, align 4
%inc = getelementptr inbounds i16, ptr %p, i64 1
%e1 = load i16, ptr %inc, align 2
%a0 = add i16 %e0, 1
%a1 = add i16 %e1, 1
store i16 %a0, ptr %dest, align 4
%inc2 = getelementptr inbounds i16, ptr %dest, i64 1
store i16 %a1, ptr %inc2, align 2
ret void
}
define void @splat_store_i16(ptr %dest, ptr %p) {
; CHECK-LABEL: @splat_store_i16(
; CHECK-NEXT: entry:
; CHECK-NEXT: [[E0:%.*]] = load i16, ptr [[P:%.*]], align 4
; CHECK-NEXT: store i16 [[E0]], ptr [[DEST:%.*]], align 4
; CHECK-NEXT: [[INC2:%.*]] = getelementptr inbounds i16, ptr [[DEST]], i64 1
; CHECK-NEXT: store i16 [[E0]], ptr [[INC2]], align 2
; CHECK-NEXT: ret void
;
entry:
%e0 = load i16, ptr %p, align 4
store i16 %e0, ptr %dest, align 4
%inc2 = getelementptr inbounds i16, ptr %dest, i64 1
store i16 %e0, ptr %inc2, align 2
ret void
}
define void @splat_store_i64(ptr %dest, ptr %p) {
; CHECK-LABEL: @splat_store_i64(
; CHECK-NEXT: entry:
; CHECK-NEXT: [[E0:%.*]] = load i64, ptr [[P:%.*]], align 4
; CHECK-NEXT: store i64 [[E0]], ptr [[DEST:%.*]], align 4
; CHECK-NEXT: [[INC2:%.*]] = getelementptr inbounds i64, ptr [[DEST]], i64 1
; CHECK-NEXT: store i64 [[E0]], ptr [[INC2]], align 2
; CHECK-NEXT: ret void
;
entry:
%e0 = load i64, ptr %p, align 4
store i64 %e0, ptr %dest, align 4
%inc2 = getelementptr inbounds i64, ptr %dest, i64 1
store i64 %e0, ptr %inc2, align 2
ret void
}
define void @splat_store_i64_zero(ptr %dest) {
; CHECK-LABEL: @splat_store_i64_zero(
; CHECK-NEXT: entry:
; CHECK-NEXT: store i64 0, ptr [[DEST:%.*]], align 4
; CHECK-NEXT: [[INC2:%.*]] = getelementptr inbounds i64, ptr [[DEST]], i64 1
; CHECK-NEXT: store i64 0, ptr [[INC2]], align 2
; CHECK-NEXT: ret void
;
entry:
store i64 0, ptr %dest, align 4
%inc2 = getelementptr inbounds i64, ptr %dest, i64 1
store i64 0, ptr %inc2, align 2
ret void
}
define void @splat_store_i64_one(ptr %dest) {
; CHECK-LABEL: @splat_store_i64_one(
; CHECK-NEXT: entry:
; CHECK-NEXT: store i64 1, ptr [[DEST:%.*]], align 4
; CHECK-NEXT: [[INC2:%.*]] = getelementptr inbounds i64, ptr [[DEST]], i64 1
; CHECK-NEXT: store i64 1, ptr [[INC2]], align 2
; CHECK-NEXT: ret void
;
entry:
store i64 1, ptr %dest, align 4
%inc2 = getelementptr inbounds i64, ptr %dest, i64 1
store i64 1, ptr %inc2, align 2
ret void
}
define void @splat_store_i32_zero(ptr %dest) {
; CHECK-LABEL: @splat_store_i32_zero(
; CHECK-NEXT: entry:
; CHECK-NEXT: store <4 x i32> zeroinitializer, ptr [[DEST:%.*]], align 4
; CHECK-NEXT: ret void
;
entry:
store i32 0, ptr %dest, align 4
%inc1 = getelementptr inbounds i32, ptr %dest, i64 1
store i32 0, ptr %inc1, align 2
%inc2 = getelementptr inbounds i32, ptr %dest, i64 2
store i32 0, ptr %inc2, align 2
%inc3 = getelementptr inbounds i32, ptr %dest, i64 3
store i32 0, ptr %inc3, align 2
ret void
}
define void @splat_store_i32_one(ptr %dest) {
; CHECK-LABEL: @splat_store_i32_one(
; CHECK-NEXT: entry:
; CHECK-NEXT: store <4 x i32> splat (i32 1), ptr [[DEST:%.*]], align 4
; CHECK-NEXT: ret void
;
entry:
store i32 1, ptr %dest, align 4
%inc1 = getelementptr inbounds i32, ptr %dest, i64 1
store i32 1, ptr %inc1, align 2
%inc2 = getelementptr inbounds i32, ptr %dest, i64 2
store i32 1, ptr %inc2, align 2
%inc3 = getelementptr inbounds i32, ptr %dest, i64 3
store i32 1, ptr %inc3, align 2
ret void
}
define void @store_stepvector_i32(ptr %dest) {
; CHECK-LABEL: @store_stepvector_i32(
; CHECK-NEXT: entry:
; CHECK-NEXT: store i32 0, ptr [[DEST:%.*]], align 4
; CHECK-NEXT: [[INC1:%.*]] = getelementptr inbounds i32, ptr [[DEST]], i64 1
; CHECK-NEXT: store i32 1, ptr [[INC1]], align 2
; CHECK-NEXT: [[INC2:%.*]] = getelementptr inbounds i32, ptr [[DEST]], i64 2
; CHECK-NEXT: store i32 2, ptr [[INC2]], align 2
; CHECK-NEXT: [[INC3:%.*]] = getelementptr inbounds i32, ptr [[DEST]], i64 3
; CHECK-NEXT: store i32 3, ptr [[INC3]], align 2
; CHECK-NEXT: ret void
;
entry:
store i32 0, ptr %dest, align 4
%inc1 = getelementptr inbounds i32, ptr %dest, i64 1
store i32 1, ptr %inc1, align 2
%inc2 = getelementptr inbounds i32, ptr %dest, i64 2
store i32 2, ptr %inc2, align 2
%inc3 = getelementptr inbounds i32, ptr %dest, i64 3
store i32 3, ptr %inc3, align 2
ret void
}
define void @store_arbitrary_constant_i32(ptr %dest) {
; CHECK-LABEL: @store_arbitrary_constant_i32(
; CHECK-NEXT: entry:
; CHECK-NEXT: store i32 0, ptr [[DEST:%.*]], align 4
; CHECK-NEXT: [[INC1:%.*]] = getelementptr inbounds i32, ptr [[DEST]], i64 1
; CHECK-NEXT: store i32 -33, ptr [[INC1]], align 2
; CHECK-NEXT: [[INC2:%.*]] = getelementptr inbounds i32, ptr [[DEST]], i64 2
; CHECK-NEXT: store i32 44, ptr [[INC2]], align 2
; CHECK-NEXT: [[INC3:%.*]] = getelementptr inbounds i32, ptr [[DEST]], i64 3
; CHECK-NEXT: store i32 77, ptr [[INC3]], align 2
; CHECK-NEXT: ret void
;
entry:
store i32 0, ptr %dest, align 4
%inc1 = getelementptr inbounds i32, ptr %dest, i64 1
store i32 -33, ptr %inc1, align 2
%inc2 = getelementptr inbounds i32, ptr %dest, i64 2
store i32 44, ptr %inc2, align 2
%inc3 = getelementptr inbounds i32, ptr %dest, i64 3
store i32 77, ptr %inc3, align 2
ret void
}
define void @shared-chain-ordering(ptr %dest, ptr %p, i64 %offset) {
; CHECK-LABEL: @shared-chain-ordering(
; CHECK-NEXT: entry:
; CHECK-NEXT: [[INC:%.*]] = getelementptr inbounds i16, ptr [[P:%.*]], i64 1
; CHECK-NEXT: [[INCS0:%.*]] = getelementptr inbounds i16, ptr [[DEST:%.*]], i64 [[OFFSET:%.*]]
; CHECK-NEXT: [[TMP0:%.*]] = load <4 x i16>, ptr [[P]], align 4
; CHECK-NEXT: [[E1:%.*]] = load i16, ptr [[INC]], align 2
; CHECK-NEXT: store <4 x i16> [[TMP0]], ptr [[INCS0]], align 4
; CHECK-NEXT: [[TMP1:%.*]] = shufflevector <4 x i16> [[TMP0]], <4 x i16> poison, <2 x i32> <i32 0, i32 poison>
; CHECK-NEXT: [[TMP2:%.*]] = insertelement <2 x i16> [[TMP1]], i16 [[E1]], i64 1
; CHECK-NEXT: store <2 x i16> [[TMP2]], ptr [[DEST]], align 4
; CHECK-NEXT: ret void
;
entry:
%e0 = load i16, ptr %p, align 4
%inc = getelementptr inbounds i16, ptr %p, i64 1
%e1 = load i16, ptr %inc, align 2
%inc1 = getelementptr inbounds i16, ptr %p, i64 2
%e2 = load i16, ptr %inc1, align 2
%inc2 = getelementptr inbounds i16, ptr %p, i64 3
%e3 = load i16, ptr %inc2, align 2
%incs0 = getelementptr inbounds i16, ptr %dest, i64 %offset
store i16 %e0, ptr %incs0, align 4
%incs1 = getelementptr inbounds i16, ptr %incs0, i64 1
store i16 %e1, ptr %incs1, align 2
%incs2 = getelementptr inbounds i16, ptr %incs0, i64 2
store i16 %e2, ptr %incs2, align 2
%incs3 = getelementptr inbounds i16, ptr %incs0, i64 3
store i16 %e3, ptr %incs3, align 2
store i16 %e0, ptr %dest, align 4
%incs = getelementptr inbounds i16, ptr %dest, i64 1
store i16 %e1, ptr %incs, align 2
ret void
}