blob: a07bbf938cce5b56786b4154c786c7310e2340c9 [file] [log] [blame]
; NOTE: Assertions have been autogenerated by utils/update_test_checks.py UTC_ARGS: --version 5
; RUN: opt -S < %s -passes=slp-vectorizer -mtriple=riscv64 -mattr=+v | FileCheck %s
declare void @g()
; Shouldn't be vectorized
define void @f0(i1 %c, ptr %p, ptr %q) {
; CHECK-LABEL: define void @f0(
; CHECK-SAME: i1 [[C:%.*]], ptr [[P:%.*]], ptr [[Q:%.*]]) #[[ATTR0:[0-9]+]] {
; CHECK-NEXT: [[X0:%.*]] = load i64, ptr [[P]], align 8
; CHECK-NEXT: [[P1:%.*]] = getelementptr i64, ptr [[P]], i64 1
; CHECK-NEXT: [[X1:%.*]] = load i64, ptr [[P1]], align 8
; CHECK-NEXT: br i1 [[C]], label %[[FOO:.*]], label %[[BAR:.*]]
; CHECK: [[FOO]]:
; CHECK-NEXT: call void @g()
; CHECK-NEXT: call void @g()
; CHECK-NEXT: call void @g()
; CHECK-NEXT: br label %[[BAZ:.*]]
; CHECK: [[BAR]]:
; CHECK-NEXT: call void @g()
; CHECK-NEXT: call void @g()
; CHECK-NEXT: call void @g()
; CHECK-NEXT: br label %[[BAZ]]
; CHECK: [[BAZ]]:
; CHECK-NEXT: store i64 [[X0]], ptr [[Q]], align 8
; CHECK-NEXT: [[Q1:%.*]] = getelementptr i64, ptr [[Q]], i64 1
; CHECK-NEXT: store i64 [[X1]], ptr [[Q1]], align 8
; CHECK-NEXT: ret void
;
%x0 = load i64, ptr %p
%p1 = getelementptr i64, ptr %p, i64 1
%x1 = load i64, ptr %p1
br i1 %c, label %foo, label %bar
foo:
call void @g()
call void @g()
call void @g()
br label %baz
bar:
call void @g()
call void @g()
call void @g()
br label %baz
baz:
store i64 %x0, ptr %q
%q1 = getelementptr i64, ptr %q, i64 1
store i64 %x1, ptr %q1
ret void
}
; Should be vectorized - just one spill of TMP0
define void @f1(i1 %c, ptr %p, ptr %q, ptr %r) {
; CHECK-LABEL: define void @f1(
; CHECK-SAME: i1 [[C:%.*]], ptr [[P:%.*]], ptr [[Q:%.*]], ptr [[R:%.*]]) #[[ATTR0]] {
; CHECK-NEXT: [[ENTRY:.*:]]
; CHECK-NEXT: [[TMP0:%.*]] = load <2 x i64>, ptr [[P]], align 8
; CHECK-NEXT: br i1 [[C]], label %[[FOO:.*]], label %[[BAR:.*]]
; CHECK: [[FOO]]:
; CHECK-NEXT: [[TMP1:%.*]] = add <2 x i64> [[TMP0]], splat (i64 1)
; CHECK-NEXT: br label %[[BAZ:.*]]
; CHECK: [[BAR]]:
; CHECK-NEXT: call void @g()
; CHECK-NEXT: call void @g()
; CHECK-NEXT: call void @g()
; CHECK-NEXT: br label %[[BAZ]]
; CHECK: [[BAZ]]:
; CHECK-NEXT: [[TMP2:%.*]] = phi <2 x i64> [ [[TMP1]], %[[FOO]] ], [ [[TMP0]], %[[BAR]] ]
; CHECK-NEXT: store <2 x i64> [[TMP2]], ptr [[Q]], align 8
; CHECK-NEXT: ret void
;
entry:
%x0 = load i64, ptr %p
%p1 = getelementptr i64, ptr %p, i64 1
%x1 = load i64, ptr %p1
br i1 %c, label %foo, label %bar
foo:
%y0 = add i64 %x0, 1
%y1 = add i64 %x1, 1
br label %baz
bar:
call void @g()
call void @g()
call void @g()
br label %baz
baz:
%phi0 = phi i64 [%y0, %foo], [%x0, %bar]
%phi1 = phi i64 [%y1, %foo], [%x1, %bar]
store i64 %phi0, ptr %q
%q1 = getelementptr i64, ptr %q, i64 1
store i64 %phi1, ptr %q1
ret void
}
; Shouldn't be vectorized
define void @f11(i1 %c, ptr %p, ptr %q, ptr %r) {
; CHECK-LABEL: define void @f11(
; CHECK-SAME: i1 [[C:%.*]], ptr [[P:%.*]], ptr [[Q:%.*]], ptr [[R:%.*]]) #[[ATTR0]] {
; CHECK-NEXT: [[ENTRY:.*:]]
; CHECK-NEXT: [[X0:%.*]] = load i64, ptr [[P]], align 8
; CHECK-NEXT: [[P1:%.*]] = getelementptr i64, ptr [[P]], i64 1
; CHECK-NEXT: [[X1:%.*]] = load i64, ptr [[P1]], align 8
; CHECK-NEXT: br i1 [[C]], label %[[FOO:.*]], label %[[BAR:.*]]
; CHECK: [[FOO]]:
; CHECK-NEXT: br label %[[BAZ:.*]]
; CHECK: [[BAR]]:
; CHECK-NEXT: call void @g()
; CHECK-NEXT: call void @g()
; CHECK-NEXT: call void @g()
; CHECK-NEXT: br label %[[BAZ]]
; CHECK: [[BAZ]]:
; CHECK-NEXT: [[PHI0:%.*]] = phi i64 [ 0, %[[FOO]] ], [ [[X0]], %[[BAR]] ]
; CHECK-NEXT: [[PHI1:%.*]] = phi i64 [ 1, %[[FOO]] ], [ [[X1]], %[[BAR]] ]
; CHECK-NEXT: store i64 [[PHI0]], ptr [[Q]], align 8
; CHECK-NEXT: [[Q1:%.*]] = getelementptr i64, ptr [[Q]], i64 1
; CHECK-NEXT: store i64 [[PHI1]], ptr [[Q1]], align 8
; CHECK-NEXT: ret void
;
entry:
%x0 = load i64, ptr %p
%p1 = getelementptr i64, ptr %p, i64 1
%x1 = load i64, ptr %p1
br i1 %c, label %foo, label %bar
foo:
br label %baz
bar:
call void @g()
call void @g()
call void @g()
br label %baz
baz:
%phi0 = phi i64 [0, %foo], [%x0, %bar]
%phi1 = phi i64 [1, %foo], [%x1, %bar]
store i64 %phi0, ptr %q
%q1 = getelementptr i64, ptr %q, i64 1
store i64 %phi1, ptr %q1
ret void
}
; Should be vectorized
define void @f2(i1 %c, ptr %p, ptr %q, ptr %r) {
; CHECK-LABEL: define void @f2(
; CHECK-SAME: i1 [[C:%.*]], ptr [[P:%.*]], ptr [[Q:%.*]], ptr [[R:%.*]]) #[[ATTR0]] {
; CHECK-NEXT: [[ENTRY:.*]]:
; CHECK-NEXT: call void @g()
; CHECK-NEXT: call void @g()
; CHECK-NEXT: call void @g()
; CHECK-NEXT: br i1 [[C]], label %[[FOO:.*]], label %[[BAR:.*]]
; CHECK: [[FOO]]:
; CHECK-NEXT: [[TMP0:%.*]] = load <2 x i64>, ptr [[P]], align 8
; CHECK-NEXT: br label %[[BAR]]
; CHECK: [[BAR]]:
; CHECK-NEXT: [[TMP1:%.*]] = phi <2 x i64> [ zeroinitializer, %[[ENTRY]] ], [ [[TMP0]], %[[FOO]] ]
; CHECK-NEXT: store <2 x i64> [[TMP1]], ptr [[Q]], align 8
; CHECK-NEXT: ret void
;
entry:
call void @g()
call void @g()
call void @g()
br i1 %c, label %foo, label %bar
foo:
%x0 = load i64, ptr %p
%p1 = getelementptr i64, ptr %p, i64 1
%x1 = load i64, ptr %p1
br label %bar
bar:
%phi0 = phi i64 [0, %entry], [%x0, %foo]
%phi1 = phi i64 [0, %entry], [%x1, %foo]
store i64 %phi0, ptr %q
%q1 = getelementptr i64, ptr %q, i64 1
store i64 %phi1, ptr %q1
ret void
}
; Shouldn't be vectorized
define void @f3(i64 %n, double %f0, double %f1, ptr %q) {
; CHECK-LABEL: define void @f3(
; CHECK-SAME: i64 [[N:%.*]], double [[F0:%.*]], double [[F1:%.*]], ptr [[Q:%.*]]) #[[ATTR0]] {
; CHECK-NEXT: [[ENTRY:.*]]:
; CHECK-NEXT: br label %[[LOOP:.*]]
; CHECK: [[LOOP]]:
; CHECK-NEXT: [[IV:%.*]] = phi i64 [ 0, %[[ENTRY]] ], [ [[IV_NEXT:%.*]], %[[LATCH:.*]] ]
; CHECK-NEXT: [[PHI0:%.*]] = phi double [ [[F0]], %[[ENTRY]] ], [ [[X0:%.*]], %[[LATCH]] ]
; CHECK-NEXT: [[PHI1:%.*]] = phi double [ [[F1]], %[[ENTRY]] ], [ [[X1:%.*]], %[[LATCH]] ]
; CHECK-NEXT: call void @g()
; CHECK-NEXT: call void @g()
; CHECK-NEXT: call void @g()
; CHECK-NEXT: br label %[[LATCH]]
; CHECK: [[LATCH]]:
; CHECK-NEXT: [[X0]] = fadd double [[PHI0]], 1.000000e+00
; CHECK-NEXT: [[X1]] = fadd double [[PHI1]], 1.000000e+00
; CHECK-NEXT: [[IV_NEXT]] = add i64 [[IV]], 1
; CHECK-NEXT: [[DONE:%.*]] = icmp eq i64 [[IV_NEXT]], [[N]]
; CHECK-NEXT: br i1 [[DONE]], label %[[EXIT:.*]], label %[[LOOP]]
; CHECK: [[EXIT]]:
; CHECK-NEXT: [[Q_GEP0:%.*]] = getelementptr i64, ptr [[Q]], i64 [[IV]]
; CHECK-NEXT: store double [[X0]], ptr [[Q_GEP0]], align 8
; CHECK-NEXT: [[Q_GEP1:%.*]] = getelementptr i64, ptr [[Q_GEP0]], i64 1
; CHECK-NEXT: store double [[X1]], ptr [[Q_GEP1]], align 8
; CHECK-NEXT: ret void
;
entry:
br label %loop
loop:
%iv = phi i64 [0, %entry], [%iv.next, %latch]
%phi0 = phi double [%f0, %entry], [%x0, %latch]
%phi1 = phi double [%f1, %entry], [%x1, %latch]
call void @g()
call void @g()
call void @g()
br label %latch
latch:
%x0 = fadd double %phi0, 1.0
%x1 = fadd double %phi1, 1.0
%iv.next = add i64 %iv, 1
%done = icmp eq i64 %iv.next, %n
br i1 %done, label %exit, label %loop
exit:
%q.gep0 = getelementptr i64, ptr %q, i64 %iv
store double %x0, ptr %q.gep0
%q.gep1 = getelementptr i64, ptr %q.gep0, i64 1
store double %x1, ptr %q.gep1
ret void
}
; Should be vectorized
define void @f4(ptr %p, ptr %q, i1 %c0, i1 %c1) {
; CHECK-LABEL: define void @f4(
; CHECK-SAME: ptr [[P:%.*]], ptr [[Q:%.*]], i1 [[C0:%.*]], i1 [[C1:%.*]]) #[[ATTR0]] {
; CHECK-NEXT: [[ENTRY:.*:]]
; CHECK-NEXT: br label %[[FOO:.*]]
; CHECK: [[FOO]]:
; CHECK-NEXT: call void @g()
; CHECK-NEXT: call void @g()
; CHECK-NEXT: call void @g()
; CHECK-NEXT: br label %[[BAR:.*]]
; CHECK: [[BAR]]:
; CHECK-NEXT: [[TMP0:%.*]] = load <2 x i64>, ptr [[P]], align 8
; CHECK-NEXT: br i1 [[C0]], label %[[BAZ:.*]], label %[[QUX:.*]]
; CHECK: [[BAZ]]:
; CHECK-NEXT: [[TMP1:%.*]] = add <2 x i64> [[TMP0]], splat (i64 1)
; CHECK-NEXT: br label %[[QUX]]
; CHECK: [[QUX]]:
; CHECK-NEXT: [[TMP2:%.*]] = phi <2 x i64> [ [[TMP0]], %[[BAR]] ], [ [[TMP1]], %[[BAZ]] ]
; CHECK-NEXT: store <2 x i64> [[TMP2]], ptr [[Q]], align 8
; CHECK-NEXT: br i1 [[C1]], label %[[FOO]], label %[[BAR]]
;
entry:
br label %foo
foo:
call void @g()
call void @g()
call void @g()
br label %bar
bar:
%x0 = load i64, ptr %p
%p1 = getelementptr i64, ptr %p, i64 1
%x1 = load i64, ptr %p1
br i1 %c0, label %baz, label %qux
baz:
%y0 = add i64 %x0, 1
%y1 = add i64 %x1, 1
br label %qux
qux:
%z0 = phi i64 [%x0, %bar], [%y0, %baz]
%z1 = phi i64 [%x1, %bar], [%y1, %baz]
store i64 %z0, ptr %q
%q1 = getelementptr i64, ptr %q, i64 1
store i64 %z1, ptr %q1
br i1 %c1, label %foo, label %bar
}
; Should be vectorized
define void @f5(i1 %c0, ptr %p, ptr %q) {
; CHECK-LABEL: define void @f5(
; CHECK-SAME: i1 [[C0:%.*]], ptr [[P:%.*]], ptr [[Q:%.*]]) #[[ATTR0]] {
; CHECK-NEXT: [[ENTRY:.*:]]
; CHECK-NEXT: br label %[[FOO:.*]]
; CHECK: [[FOO]]:
; CHECK-NEXT: call void @g()
; CHECK-NEXT: call void @g()
; CHECK-NEXT: call void @g()
; CHECK-NEXT: [[TMP0:%.*]] = load <2 x i64>, ptr [[P]], align 8
; CHECK-NEXT: br i1 [[C0]], label %[[BAR:.*]], label %[[FOOBAR:.*]]
; CHECK: [[BAR]]:
; CHECK-NEXT: br label %[[BAZ:.*]]
; CHECK: [[BAZ]]:
; CHECK-NEXT: [[TMP1:%.*]] = add <2 x i64> [[TMP0]], splat (i64 1)
; CHECK-NEXT: br label %[[BARFOO:.*]]
; CHECK: [[FOOBAR]]:
; CHECK-NEXT: [[TMP2:%.*]] = add <2 x i64> [[TMP0]], splat (i64 2)
; CHECK-NEXT: br label %[[BARFOO]]
; CHECK: [[BARFOO]]:
; CHECK-NEXT: [[TMP3:%.*]] = phi <2 x i64> [ [[TMP2]], %[[FOOBAR]] ], [ [[TMP1]], %[[BAZ]] ]
; CHECK-NEXT: store <2 x i64> [[TMP3]], ptr [[Q]], align 8
; CHECK-NEXT: br label %[[FOO]]
;
entry:
br label %foo
foo:
call void @g()
call void @g()
call void @g()
%x0 = load i64, ptr %p
%p1 = getelementptr i64, ptr %p, i64 1
%x1 = load i64, ptr %p1
br i1 %c0, label %bar, label %foobar
bar:
br label %baz
baz:
%y0 = add i64 %x0, 1
%y1 = add i64 %x1, 1
br label %barfoo
foobar:
%z0 = add i64 %x0, 2
%z1 = add i64 %x1, 2
br label %barfoo
barfoo:
%phi0 = phi i64 [%z0, %foobar], [%y0, %baz]
%phi1 = phi i64 [%z1, %foobar], [%y1, %baz]
store i64 %phi0, ptr %q
%q1 = getelementptr i64, ptr %q, i64 1
store i64 %phi1, ptr %q1
br label %foo
}
; Shouldn't be vectorized
define void @f6(i1 %c, ptr %p, ptr %q, ptr %r) {
; CHECK-LABEL: define void @f6(
; CHECK-SAME: i1 [[C:%.*]], ptr [[P:%.*]], ptr [[Q:%.*]], ptr [[R:%.*]]) #[[ATTR0]] {
; CHECK-NEXT: [[ENTRY:.*]]:
; CHECK-NEXT: br i1 [[C]], label %[[FOO:.*]], label %[[BAR:.*]]
; CHECK: [[FOO]]:
; CHECK-NEXT: [[X0:%.*]] = load i64, ptr [[P]], align 8
; CHECK-NEXT: [[P1:%.*]] = getelementptr i64, ptr [[P]], i64 1
; CHECK-NEXT: [[X1:%.*]] = load i64, ptr [[P1]], align 8
; CHECK-NEXT: br label %[[BAR]]
; CHECK: [[BAR]]:
; CHECK-NEXT: [[PHI0:%.*]] = phi i64 [ 0, %[[ENTRY]] ], [ [[X0]], %[[FOO]] ]
; CHECK-NEXT: [[PHI1:%.*]] = phi i64 [ 0, %[[ENTRY]] ], [ [[X1]], %[[FOO]] ]
; CHECK-NEXT: call void @g()
; CHECK-NEXT: call void @g()
; CHECK-NEXT: call void @g()
; CHECK-NEXT: br label %[[BAZ:.*]]
; CHECK: [[BAZ]]:
; CHECK-NEXT: store i64 [[PHI0]], ptr [[Q]], align 8
; CHECK-NEXT: [[Q1:%.*]] = getelementptr i64, ptr [[Q]], i64 1
; CHECK-NEXT: store i64 [[PHI1]], ptr [[Q1]], align 8
; CHECK-NEXT: ret void
;
entry:
br i1 %c, label %foo, label %bar
foo:
%x0 = load i64, ptr %p
%p1 = getelementptr i64, ptr %p, i64 1
%x1 = load i64, ptr %p1
br label %bar
bar:
%phi0 = phi i64 [0, %entry], [%x0, %foo]
%phi1 = phi i64 [0, %entry], [%x1, %foo]
call void @g()
call void @g()
call void @g()
br label %baz
baz:
store i64 %phi0, ptr %q
%q1 = getelementptr i64, ptr %q, i64 1
store i64 %phi1, ptr %q1
ret void
}