blob: 830ec60229ec08dd50612c027dfc2c8b52120551 [file] [edit]
; NOTE: Assertions have been autogenerated by utils/update_analyze_test_checks.py UTC_ARGS: --filter-out-after "middle.block:" --version 6
; RUN: opt -passes=loop-vectorize -force-vector-width=2 -force-vector-interleave=1 -disable-output -vplan-print-before=makeCallWideningDecisions %s 2>&1 | FileCheck --strict-whitespace %s
declare i64 @bar(i64)
declare <2 x i64> @vec_bar(<2 x i64>)
declare i64 @"quoted name"(i64)
declare <2 x i64> @vec_quoted(<2 x i64>)
; Call with return, argument and function attributes at the call site.
define void @call_site_attrs(ptr noalias %in.ptr, ptr noalias %out.ptr) {
; CHECK-LABEL: VPlan for loop in 'call_site_attrs'
; CHECK: VPlan ' for UF>=1' {
; CHECK-NEXT: Live-in vp<[[VP0:%[0-9]+]]> = VF
; CHECK-NEXT: Live-in vp<[[VP1:%[0-9]+]]> = VF * UF
; CHECK-NEXT: Live-in vp<[[VP2:%[0-9]+]]> = vector-trip-count
; CHECK-NEXT: Live-in ir<1000> = original trip-count
; CHECK-EMPTY:
; CHECK-NEXT: ir-bb<entry>:
; CHECK-NEXT: Successor(s): scalar.ph, vector.ph
; CHECK-EMPTY:
; CHECK-NEXT: vector.ph:
; CHECK-NEXT: Successor(s): vector loop
; CHECK-EMPTY:
; CHECK-NEXT: <x1> vector loop: {
; CHECK-NEXT: vp<[[VP3:%[0-9]+]]> = CANONICAL-IV
; CHECK-EMPTY:
; CHECK-NEXT: vector.body:
; CHECK-NEXT: ir<%iv> = WIDEN-INDUCTION nuw nsw ir<0>, ir<1>, vp<[[VP0]]>
; CHECK-NEXT: CLONE ir<%in.gep> = getelementptr inbounds ir<%in.ptr>, ir<%iv>
; CHECK-NEXT: vp<[[VP4:%[0-9]+]]> = vector-pointer inbounds i64, ir<%in.gep>, ir<1>
; CHECK-NEXT: WIDEN ir<%in> = load vp<[[VP4]]>
; CHECK-NEXT: EMIT ir<%call> = call noundef range(i64 0, 100) i64 @bar(noundef range(i64 0, 80) ir<%in>) nounwind memory(none) "vector-function-abi-variant"="_ZGVnN2v_bar(vec_bar)"
; CHECK-NEXT: CLONE ir<%out.gep> = getelementptr inbounds ir<%out.ptr>, ir<%iv>
; CHECK-NEXT: vp<[[VP5:%[0-9]+]]> = vector-pointer inbounds i64, ir<%out.gep>, ir<1>
; CHECK-NEXT: WIDEN store vp<[[VP5]]>, ir<%call>
; CHECK-NEXT: CLONE ir<%iv.next> = add nuw nsw ir<%iv>, ir<1>
; CHECK-NEXT: CLONE ir<%exitcond> = icmp eq ir<%iv.next>, ir<1000>
; CHECK-NEXT: EMIT vp<%index.next> = add nuw vp<[[VP3]]>, vp<[[VP1]]>
; CHECK-NEXT: EMIT branch-on-count vp<%index.next>, vp<[[VP2]]>
; CHECK-NEXT: No successors
; CHECK-NEXT: }
; CHECK-NEXT: Successor(s): middle.block
; CHECK-EMPTY:
; CHECK-NEXT: middle.block:
;
entry:
br label %loop
loop:
%iv = phi i64 [ 0, %entry ], [ %iv.next, %loop ]
%in.gep = getelementptr inbounds i64, ptr %in.ptr, i64 %iv
%in = load i64, ptr %in.gep, align 8
%call = call range(i64 0, 100) noundef i64 @bar(i64 range(i64 0, 80) noundef %in) #0
%out.gep = getelementptr inbounds i64, ptr %out.ptr, i64 %iv
store i64 %call, ptr %out.gep, align 8
%iv.next = add nuw nsw i64 %iv, 1
%exitcond = icmp eq i64 %iv.next, 1000
br i1 %exitcond, label %exit, label %loop
exit:
ret void
}
; Conditional call, the call VPInstruction gets a mask operand.
define void @masked_call_site_attrs(ptr noalias %in.ptr, ptr noalias %out.ptr) {
; CHECK-LABEL: VPlan for loop in 'masked_call_site_attrs'
; CHECK: VPlan ' for UF>=1' {
; CHECK-NEXT: Live-in vp<[[VP0:%[0-9]+]]> = VF
; CHECK-NEXT: Live-in vp<[[VP1:%[0-9]+]]> = VF * UF
; CHECK-NEXT: Live-in vp<[[VP2:%[0-9]+]]> = vector-trip-count
; CHECK-NEXT: Live-in ir<1000> = original trip-count
; CHECK-EMPTY:
; CHECK-NEXT: ir-bb<entry>:
; CHECK-NEXT: Successor(s): scalar.ph, vector.ph
; CHECK-EMPTY:
; CHECK-NEXT: vector.ph:
; CHECK-NEXT: Successor(s): vector loop
; CHECK-EMPTY:
; CHECK-NEXT: <x1> vector loop: {
; CHECK-NEXT: vp<[[VP3:%[0-9]+]]> = CANONICAL-IV
; CHECK-EMPTY:
; CHECK-NEXT: vector.body:
; CHECK-NEXT: ir<%iv> = WIDEN-INDUCTION nuw nsw ir<0>, ir<1>, vp<[[VP0]]>
; CHECK-NEXT: CLONE ir<%in.gep> = getelementptr inbounds ir<%in.ptr>, ir<%iv>
; CHECK-NEXT: vp<[[VP4:%[0-9]+]]> = vector-pointer inbounds i64, ir<%in.gep>, ir<1>
; CHECK-NEXT: WIDEN ir<%in> = load vp<[[VP4]]>
; CHECK-NEXT: EMIT ir<%cmp> = icmp ugt ir<%in>, ir<50>
; CHECK-NEXT: Successor(s): then
; CHECK-EMPTY:
; CHECK-NEXT: then:
; CHECK-NEXT: EMIT ir<%call> = call noundef i64 @bar(noundef ir<%in>) nounwind memory(none) "vector-function-abi-variant"="_ZGVnN2v_bar(vec_bar)", ir<%cmp> (!vplan.execution.frequency 9223372036854775807 (50%, estimated))
; CHECK-NEXT: EMIT ir<%out.gep> = getelementptr inbounds ir<%out.ptr>, ir<%iv>
; CHECK-NEXT: REPLICATE store ir<%call>, ir<%out.gep>, ir<%cmp> (!vplan.execution.frequency 9223372036854775807 (50%, estimated))
; CHECK-NEXT: Successor(s): latch
; CHECK-EMPTY:
; CHECK-NEXT: latch:
; CHECK-NEXT: CLONE ir<%iv.next> = add nuw nsw ir<%iv>, ir<1>
; CHECK-NEXT: CLONE ir<%exitcond> = icmp eq ir<%iv.next>, ir<1000>
; CHECK-NEXT: EMIT vp<%index.next> = add nuw vp<[[VP3]]>, vp<[[VP1]]>
; CHECK-NEXT: EMIT branch-on-count vp<%index.next>, vp<[[VP2]]>
; CHECK-NEXT: No successors
; CHECK-NEXT: }
; CHECK-NEXT: Successor(s): middle.block
; CHECK-EMPTY:
; CHECK-NEXT: middle.block:
;
entry:
br label %loop
loop:
%iv = phi i64 [ 0, %entry ], [ %iv.next, %latch ]
%in.gep = getelementptr inbounds i64, ptr %in.ptr, i64 %iv
%in = load i64, ptr %in.gep, align 8
%cmp = icmp ugt i64 %in, 50
br i1 %cmp, label %then, label %latch
then:
%call = call noundef i64 @bar(i64 noundef %in) #0
%out.gep = getelementptr inbounds i64, ptr %out.ptr, i64 %iv
store i64 %call, ptr %out.gep, align 8
br label %latch
latch:
%iv.next = add nuw nsw i64 %iv, 1
%exitcond = icmp eq i64 %iv.next, 1000
br i1 %exitcond, label %exit, label %loop
exit:
ret void
}
; Call with memory attributes at the call site.
define void @call_site_memory_attrs(ptr noalias %in.ptr, ptr noalias %out.ptr) {
; CHECK-LABEL: VPlan for loop in 'call_site_memory_attrs'
; CHECK: VPlan ' for UF>=1' {
; CHECK-NEXT: Live-in vp<[[VP0:%[0-9]+]]> = VF
; CHECK-NEXT: Live-in vp<[[VP1:%[0-9]+]]> = VF * UF
; CHECK-NEXT: Live-in vp<[[VP2:%[0-9]+]]> = vector-trip-count
; CHECK-NEXT: Live-in ir<1000> = original trip-count
; CHECK-EMPTY:
; CHECK-NEXT: ir-bb<entry>:
; CHECK-NEXT: Successor(s): scalar.ph, vector.ph
; CHECK-EMPTY:
; CHECK-NEXT: vector.ph:
; CHECK-NEXT: Successor(s): vector loop
; CHECK-EMPTY:
; CHECK-NEXT: <x1> vector loop: {
; CHECK-NEXT: vp<[[VP3:%[0-9]+]]> = CANONICAL-IV
; CHECK-EMPTY:
; CHECK-NEXT: vector.body:
; CHECK-NEXT: ir<%iv> = WIDEN-INDUCTION nuw nsw ir<0>, ir<1>, vp<[[VP0]]>
; CHECK-NEXT: CLONE ir<%in.gep> = getelementptr inbounds ir<%in.ptr>, ir<%iv>
; CHECK-NEXT: vp<[[VP4:%[0-9]+]]> = vector-pointer inbounds i64, ir<%in.gep>, ir<1>
; CHECK-NEXT: WIDEN ir<%in> = load vp<[[VP4]]>
; CHECK-NEXT: EMIT ir<%call> = call i64 @bar(ir<%in>) nounwind memory(read) "vector-function-abi-variant"="_ZGVnN2v_bar(vec_bar)"
; CHECK-NEXT: CLONE ir<%out.gep> = getelementptr inbounds ir<%out.ptr>, ir<%iv>
; CHECK-NEXT: vp<[[VP5:%[0-9]+]]> = vector-pointer inbounds i64, ir<%out.gep>, ir<1>
; CHECK-NEXT: WIDEN store vp<[[VP5]]>, ir<%call>
; CHECK-NEXT: CLONE ir<%iv.next> = add nuw nsw ir<%iv>, ir<1>
; CHECK-NEXT: CLONE ir<%exitcond> = icmp eq ir<%iv.next>, ir<1000>
; CHECK-NEXT: EMIT vp<%index.next> = add nuw vp<[[VP3]]>, vp<[[VP1]]>
; CHECK-NEXT: EMIT branch-on-count vp<%index.next>, vp<[[VP2]]>
; CHECK-NEXT: No successors
; CHECK-NEXT: }
; CHECK-NEXT: Successor(s): middle.block
; CHECK-EMPTY:
; CHECK-NEXT: middle.block:
;
entry:
br label %loop
loop:
%iv = phi i64 [ 0, %entry ], [ %iv.next, %loop ]
%in.gep = getelementptr inbounds i64, ptr %in.ptr, i64 %iv
%in = load i64, ptr %in.gep, align 8
%call = call i64 @bar(i64 %in) #1
%out.gep = getelementptr inbounds i64, ptr %out.ptr, i64 %iv
store i64 %call, ptr %out.gep, align 8
%iv.next = add nuw nsw i64 %iv, 1
%exitcond = icmp eq i64 %iv.next, 1000
br i1 %exitcond, label %exit, label %loop
exit:
ret void
}
; Callee name that needs quoting.
define void @call_quoted_name(ptr noalias %in.ptr, ptr noalias %out.ptr) {
; CHECK-LABEL: VPlan for loop in 'call_quoted_name'
; CHECK: VPlan ' for UF>=1' {
; CHECK-NEXT: Live-in vp<[[VP0:%[0-9]+]]> = VF
; CHECK-NEXT: Live-in vp<[[VP1:%[0-9]+]]> = VF * UF
; CHECK-NEXT: Live-in vp<[[VP2:%[0-9]+]]> = vector-trip-count
; CHECK-NEXT: Live-in ir<1000> = original trip-count
; CHECK-EMPTY:
; CHECK-NEXT: ir-bb<entry>:
; CHECK-NEXT: Successor(s): scalar.ph, vector.ph
; CHECK-EMPTY:
; CHECK-NEXT: vector.ph:
; CHECK-NEXT: Successor(s): vector loop
; CHECK-EMPTY:
; CHECK-NEXT: <x1> vector loop: {
; CHECK-NEXT: vp<[[VP3:%[0-9]+]]> = CANONICAL-IV
; CHECK-EMPTY:
; CHECK-NEXT: vector.body:
; CHECK-NEXT: ir<%iv> = WIDEN-INDUCTION nuw nsw ir<0>, ir<1>, vp<[[VP0]]>
; CHECK-NEXT: CLONE ir<%in.gep> = getelementptr inbounds ir<%in.ptr>, ir<%iv>
; CHECK-NEXT: vp<[[VP4:%[0-9]+]]> = vector-pointer inbounds i64, ir<%in.gep>, ir<1>
; CHECK-NEXT: WIDEN ir<%in> = load vp<[[VP4]]>
; CHECK-NEXT: EMIT ir<%call> = call i64 @"quoted name"(ir<%in>) nounwind memory(none) "vector-function-abi-variant"="_ZGVnN2v_quoted name(vec_quoted)"
; CHECK-NEXT: CLONE ir<%out.gep> = getelementptr inbounds ir<%out.ptr>, ir<%iv>
; CHECK-NEXT: vp<[[VP5:%[0-9]+]]> = vector-pointer inbounds i64, ir<%out.gep>, ir<1>
; CHECK-NEXT: WIDEN store vp<[[VP5]]>, ir<%call>
; CHECK-NEXT: CLONE ir<%iv.next> = add nuw nsw ir<%iv>, ir<1>
; CHECK-NEXT: CLONE ir<%exitcond> = icmp eq ir<%iv.next>, ir<1000>
; CHECK-NEXT: EMIT vp<%index.next> = add nuw vp<[[VP3]]>, vp<[[VP1]]>
; CHECK-NEXT: EMIT branch-on-count vp<%index.next>, vp<[[VP2]]>
; CHECK-NEXT: No successors
; CHECK-NEXT: }
; CHECK-NEXT: Successor(s): middle.block
; CHECK-EMPTY:
; CHECK-NEXT: middle.block:
;
entry:
br label %loop
loop:
%iv = phi i64 [ 0, %entry ], [ %iv.next, %loop ]
%in.gep = getelementptr inbounds i64, ptr %in.ptr, i64 %iv
%in = load i64, ptr %in.gep, align 8
%call = call i64 @"quoted name"(i64 %in) #2
%out.gep = getelementptr inbounds i64, ptr %out.ptr, i64 %iv
store i64 %call, ptr %out.gep, align 8
%iv.next = add nuw nsw i64 %iv, 1
%exitcond = icmp eq i64 %iv.next, 1000
br i1 %exitcond, label %exit, label %loop
exit:
ret void
}
attributes #0 = { nounwind memory(none) "vector-function-abi-variant"="_ZGVnN2v_bar(vec_bar)" }
attributes #1 = { nounwind memory(read) "vector-function-abi-variant"="_ZGVnN2v_bar(vec_bar)" }
attributes #2 = { nounwind memory(none) "vector-function-abi-variant"="_ZGVnN2v_quoted name(vec_quoted)" }