Files
llvm-project/llvm/test/Transforms/LoopVectorize/noalias-scope-decl-outer-loop.ll
David Sherwood ba91dd14b9 [LV][NFC] Remove unneeded LLVM intrinsic declarations (#190993)
We no longer need to declare LLVM intrinsics in .ll files as the
intrinsics are populated automatically in the module. Remove the
declarations from tests to reduce test noise and size.

This came from a suggestion on PR #190786.
2026-04-09 11:41:18 +01:00

73 lines
3.1 KiB
LLVM

; NOTE: Assertions have been autogenerated by utils/update_test_checks.py UTC_ARGS: --check-globals none --version 6
; RUN: opt -S -passes='loop-vectorize,verify' -enable-vplan-native-path -force-vector-width=2 < %s | FileCheck %s
; The noalias.scope.decl intrinsic declares a noalias scope valid for a single
; iteration. During outer loop vectorization, emitting it as a single-scalar
; replicate would incorrectly extend the scope across multiple original
; iterations packed into one vector iteration. Bail out of vectorization for
; outer loops containing noalias.scope.decl.
; FIXME: We could still vectorize by dropping the noalias.scope.decl and
; stripping !alias.scope/!noalias metadata from the loop body.
define void @test_noalias_scope_decl(ptr %a, ptr %b, i64 %n) {
; CHECK-LABEL: define void @test_noalias_scope_decl(
; CHECK-SAME: ptr [[A:%.*]], ptr [[B:%.*]], i64 [[N:%.*]]) {
; CHECK-NEXT: [[SCALAR_PH:.*]]:
; CHECK-NEXT: br label %[[OUTER_HEADER:.*]]
; CHECK: [[OUTER_HEADER]]:
; CHECK-NEXT: [[J:%.*]] = phi i64 [ 0, %[[SCALAR_PH]] ], [ [[J_NEXT:%.*]], %[[OUTER_LATCH:.*]] ]
; CHECK-NEXT: call void @llvm.experimental.noalias.scope.decl(metadata [[META0:![0-9]+]])
; CHECK-NEXT: br label %[[INNER:.*]]
; CHECK: [[INNER]]:
; CHECK-NEXT: [[K:%.*]] = phi i64 [ 0, %[[OUTER_HEADER]] ], [ [[K_NEXT:%.*]], %[[INNER]] ]
; CHECK-NEXT: [[IDX:%.*]] = add i64 [[J]], [[K]]
; CHECK-NEXT: [[PTR_A:%.*]] = getelementptr inbounds i32, ptr [[A]], i64 [[IDX]]
; CHECK-NEXT: [[VAL:%.*]] = load i32, ptr [[PTR_A]], align 4, !alias.scope [[META0]]
; CHECK-NEXT: [[PTR_B:%.*]] = getelementptr inbounds i32, ptr [[B]], i64 [[IDX]]
; CHECK-NEXT: store i32 [[VAL]], ptr [[PTR_B]], align 4, !noalias [[META0]]
; CHECK-NEXT: [[K_NEXT]] = add i64 [[K]], 1
; CHECK-NEXT: [[INNER_COND:%.*]] = icmp eq i64 [[K_NEXT]], [[N]]
; CHECK-NEXT: br i1 [[INNER_COND]], label %[[OUTER_LATCH]], label %[[INNER]]
; CHECK: [[OUTER_LATCH]]:
; CHECK-NEXT: [[J_NEXT]] = add i64 [[J]], 1
; CHECK-NEXT: [[OUTER_COND:%.*]] = icmp eq i64 [[J_NEXT]], [[N]]
; CHECK-NEXT: br i1 [[OUTER_COND]], label %[[EXIT:.*]], label %[[OUTER_HEADER]], !llvm.loop [[LOOP3:![0-9]+]]
; CHECK: [[EXIT]]:
; CHECK-NEXT: ret void
;
entry:
br label %outer.header
outer.header:
%j = phi i64 [ 0, %entry ], [ %j.next, %outer.latch ]
call void @llvm.experimental.noalias.scope.decl(metadata !3)
br label %inner
inner:
%k = phi i64 [ 0, %outer.header ], [ %k.next, %inner ]
%idx = add i64 %j, %k
%ptr.a = getelementptr inbounds i32, ptr %a, i64 %idx
%val = load i32, ptr %ptr.a, align 4, !alias.scope !3
%ptr.b = getelementptr inbounds i32, ptr %b, i64 %idx
store i32 %val, ptr %ptr.b, align 4, !noalias !3
%k.next = add i64 %k, 1
%inner.cond = icmp eq i64 %k.next, %n
br i1 %inner.cond, label %outer.latch, label %inner
outer.latch:
%j.next = add i64 %j, 1
%outer.cond = icmp eq i64 %j.next, %n
br i1 %outer.cond, label %exit, label %outer.header, !llvm.loop !0
exit:
ret void
}
!0 = distinct !{!0, !1, !2}
!1 = !{!"llvm.loop.mustprogress"}
!2 = !{!"llvm.loop.vectorize.enable", i1 true}
!3 = !{!4}
!4 = distinct !{!4, !5}
!5 = distinct !{!5}