llvm-project/llvm/test/Transforms/InstCombine/intersect-accessgroup.ll
Florian Hahn 076513646c
[Local] Only intersect llvm.access.group metadata if instr moves. (#115868)
Preserve llvm.access.group metadata on the replacement instruction, if
it does not move. In that case, the program would be UB, if the parallel
property encoded in the metadata does not hold.

This matches the LangRef recently updated in #116220

PR https://github.com/llvm/llvm-project/pull/115868
2024-11-19 22:01:16 +00:00

113 lines
3.0 KiB
LLVM

; RUN: opt -passes=instcombine -S < %s | FileCheck %s
;
; void func(long n, double A[static const restrict n]) {
; for (int i = 0; i < n; i+=1)
; for (int j = 0; j < n;j+=1)
; for (int k = 0; k < n; k += 1)
; for (int l = 0; l < n; l += 1) {
; ptr p = &A[i + j + k + l];
; double x = *p;
; double y = *p;
; arg(x + y);
; }
; }
;
; Check that the original access group on %0 is preserved when replacing uses
; of %1 with it, as %0 is not moved and if %0 would not be parallel in the
; original loop it would be UB.
;
target datalayout = "e-m:e-i64:64-f80:128-n8:16:32:64-S128"
declare void @arg(double)
define void @func(i64 %n, ptr noalias nonnull %A) {
entry:
br label %for.cond
for.cond:
%i.0 = phi i32 [ 0, %entry ], [ %add31, %for.inc30 ]
%conv = sext i32 %i.0 to i64
%cmp = icmp slt i64 %conv, %n
br i1 %cmp, label %for.cond2, label %for.end32
for.cond2:
%j.0 = phi i32 [ %add28, %for.inc27 ], [ 0, %for.cond ]
%conv3 = sext i32 %j.0 to i64
%cmp4 = icmp slt i64 %conv3, %n
br i1 %cmp4, label %for.cond8, label %for.inc30
for.cond8:
%k.0 = phi i32 [ %add25, %for.inc24 ], [ 0, %for.cond2 ]
%conv9 = sext i32 %k.0 to i64
%cmp10 = icmp slt i64 %conv9, %n
br i1 %cmp10, label %for.cond14, label %for.inc27
for.cond14:
%l.0 = phi i32 [ %add23, %for.body19 ], [ 0, %for.cond8 ]
%conv15 = sext i32 %l.0 to i64
%cmp16 = icmp slt i64 %conv15, %n
br i1 %cmp16, label %for.body19, label %for.inc24
for.body19:
%add = add nsw i32 %i.0, %j.0
%add20 = add nsw i32 %add, %k.0
%add21 = add nsw i32 %add20, %l.0
%idxprom = sext i32 %add21 to i64
%arrayidx = getelementptr inbounds double, ptr %A, i64 %idxprom
%0 = load double, ptr %arrayidx, align 8, !llvm.access.group !1
%1 = load double, ptr %arrayidx, align 8, !llvm.access.group !2
%add22 = fadd double %0, %1
call void @arg(double %add22), !llvm.access.group !3
%add23 = add nsw i32 %l.0, 1
br label %for.cond14, !llvm.loop !11
for.inc24:
%add25 = add nsw i32 %k.0, 1
br label %for.cond8, !llvm.loop !14
for.inc27:
%add28 = add nsw i32 %j.0, 1
br label %for.cond2, !llvm.loop !16
for.inc30:
%add31 = add nsw i32 %i.0, 1
br label %for.cond, !llvm.loop !18
for.end32:
ret void
}
; access groups
!7 = distinct !{}
!8 = distinct !{}
!9 = distinct !{}
; access group lists
!1 = !{!7, !9}
!2 = !{!7, !8}
!3 = !{!7, !8, !9}
!11 = distinct !{!11, !13}
!13 = !{!"llvm.loop.parallel_accesses", !7}
!14 = distinct !{!14, !15}
!15 = !{!"llvm.loop.parallel_accesses", !8}
!16 = distinct !{!16, !17}
!17 = !{!"llvm.loop.parallel_accesses", !8, !9}
!18 = distinct !{!18, !19}
!19 = !{!"llvm.loop.parallel_accesses", !9}
; CHECK: load double, {{.*}} !llvm.access.group ![[ACCESSGROUP_0:[0-9]+]]
; CHECK: br label %for.cond14, !llvm.loop ![[LOOP_4:[0-9]+]]
; CHECK: ![[ACCESSGROUP_0]] = !{![[G1:[0-9]+]], ![[G2:[0-9]+]]}
; CHECK: ![[G1]] = distinct !{}
; CHECK: ![[G2]] = distinct !{}
; CHECK: ![[LOOP_4]] = distinct !{![[LOOP_4]], ![[PARALLEL_ACCESSES_5:[0-9]+]]}
; CHECK: ![[PARALLEL_ACCESSES_5]] = !{!"llvm.loop.parallel_accesses", ![[G1]]}