File: unsafe-and-rt-checks-convergent.ll

package info (click to toggle)
llvm-toolchain-21 1%3A21.1.6-3
  • links: PTS, VCS
  • area: main
  • in suites: forky, sid
  • size: 2,245,028 kB
  • sloc: cpp: 7,619,726; ansic: 1,434,018; asm: 1,058,748; python: 252,740; f90: 94,671; objc: 70,685; lisp: 42,813; pascal: 18,401; sh: 8,601; ml: 5,111; perl: 4,720; makefile: 3,675; awk: 3,523; javascript: 2,409; xml: 892; fortran: 770
file content (138 lines) | stat: -rw-r--r-- 5,391 bytes parent folder | download | duplicates (2)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
; NOTE: Assertions have been autogenerated by utils/update_analyze_test_checks.py UTC_ARGS: --version 5
; RUN: opt -passes='print<access-info>' -disable-output %s 2>&1 | FileCheck %s

; Analyze this loop:
;   for (i = 0; i < n; i++)
;    A[i + 1] = A[i] * B[i] * C[i];

; In this case, runtime checks are needed, and there is a convergent operation.
define void @rtchecks_needed(ptr %a, ptr %b, ptr %c) {
; CHECK-LABEL: 'rtchecks_needed'
; CHECK-NEXT:    for.body:
; CHECK-NEXT:      Has convergent operation in loop
; CHECK-NEXT:      Report: cannot add control dependency to convergent operation
; CHECK-NEXT:      Dependences:
; CHECK-NEXT:        Backward:
; CHECK-NEXT:            %loadA = load i16, ptr %arrayidxA, align 2 ->
; CHECK-NEXT:            store i16 %mul1, ptr %arrayidxA_plus_2, align 2
; CHECK-EMPTY:
; CHECK-NEXT:      Run-time memory checks:
; CHECK-NEXT:      Check 0:
; CHECK-NEXT:        Comparing group GRP0:
; CHECK-NEXT:          %arrayidxA = getelementptr inbounds i16, ptr %a, i64 %storemerge3
; CHECK-NEXT:          %arrayidxA_plus_2 = getelementptr inbounds i16, ptr %a, i64 %add
; CHECK-NEXT:        Against group GRP1:
; CHECK-NEXT:          %arrayidxB = getelementptr inbounds i16, ptr %b, i64 %storemerge3
; CHECK-NEXT:      Check 1:
; CHECK-NEXT:        Comparing group GRP0:
; CHECK-NEXT:          %arrayidxA = getelementptr inbounds i16, ptr %a, i64 %storemerge3
; CHECK-NEXT:          %arrayidxA_plus_2 = getelementptr inbounds i16, ptr %a, i64 %add
; CHECK-NEXT:        Against group GRP2:
; CHECK-NEXT:          %arrayidxC = getelementptr inbounds i16, ptr %c, i64 %storemerge3
; CHECK-NEXT:      Grouped accesses:
; CHECK-NEXT:        Group GRP0:
; CHECK-NEXT:          (Low: %a High: (42 + %a))
; CHECK-NEXT:            Member: {%a,+,2}<nuw><%for.body>
; CHECK-NEXT:            Member: {(2 + %a),+,2}<nw><%for.body>
; CHECK-NEXT:        Group GRP1:
; CHECK-NEXT:          (Low: %b High: (40 + %b))
; CHECK-NEXT:            Member: {%b,+,2}<nuw><%for.body>
; CHECK-NEXT:        Group GRP2:
; CHECK-NEXT:          (Low: %c High: (40 + %c))
; CHECK-NEXT:            Member: {%c,+,2}<nuw><%for.body>
; CHECK-EMPTY:
; CHECK-NEXT:      Non vectorizable stores to invariant address were not found in loop.
; CHECK-NEXT:      SCEV assumptions:
; CHECK-EMPTY:
; CHECK-NEXT:      Expressions re-written:
;
entry:
  br label %for.body

for.body:                                         ; preds = %for.body, %entry
  %storemerge3 = phi i64 [ 0, %entry ], [ %add, %for.body ]

  %arrayidxA = getelementptr inbounds i16, ptr %a, i64 %storemerge3
  %loadA = load i16, ptr %arrayidxA, align 2

  %arrayidxB = getelementptr inbounds i16, ptr %b, i64 %storemerge3
  %loadB = load i16, ptr %arrayidxB, align 2

  %arrayidxC = getelementptr inbounds i16, ptr %c, i64 %storemerge3
  %loadC = load i16, ptr %arrayidxC, align 2

  call i16 @llvm.convergent(i16 %loadC)

  %mul = mul i16 %loadB, %loadA
  %mul1 = mul i16 %mul, %loadC

  %add = add nuw nsw i64 %storemerge3, 1
  %arrayidxA_plus_2 = getelementptr inbounds i16, ptr %a, i64 %add
  store i16 %mul1, ptr %arrayidxA_plus_2, align 2

  %exitcond = icmp eq i64 %add, 20
  br i1 %exitcond, label %for.end, label %for.body

for.end:                                          ; preds = %for.body
  ret void
}

; In this case, no runtime checks are needed, and there is a convergent operation.
define void @no_rtchecks(ptr noalias %a, ptr noalias %b, ptr noalias %c, ptr noalias %d, ptr noalias %e) {
; CHECK-LABEL: 'no_rtchecks'
; CHECK-NEXT:    for.body:
; CHECK-NEXT:      Has convergent operation in loop
; CHECK-NEXT:      Report: cannot add control dependency to convergent operation
; CHECK-NEXT:      Dependences:
; CHECK-NEXT:        Backward:
; CHECK-NEXT:            %loadA = load i16, ptr %arrayidxA, align 4 ->
; CHECK-NEXT:            store i16 %mulA, ptr %arrayidxA_plus_4, align 4
; CHECK-EMPTY:
; CHECK-NEXT:      Run-time memory checks:
; CHECK-NEXT:      Grouped accesses:
; CHECK-EMPTY:
; CHECK-NEXT:      Non vectorizable stores to invariant address were not found in loop.
; CHECK-NEXT:      SCEV assumptions:
; CHECK-EMPTY:
; CHECK-NEXT:      Expressions re-written:
;
entry:
  br label %for.body

for.body:                                         ; preds = %for.body, %entry
  %ind = phi i64 [ 0, %entry ], [ %add, %for.body ]

  %arrayidxA = getelementptr inbounds i16, ptr %a, i64 %ind
  %loadA = load i16, ptr %arrayidxA, align 4

  %arrayidxB = getelementptr inbounds i16, ptr %b, i64 %ind
  %loadB = load i16, ptr %arrayidxB, align 4

  %mulA = mul i16 %loadB, %loadA

  %add = add nuw nsw i64 %ind, 1
  %arrayidxA_plus_4 = getelementptr inbounds i16, ptr %a, i64 %add
  store i16 %mulA, ptr %arrayidxA_plus_4, align 4

  %arrayidxD = getelementptr inbounds i16, ptr %d, i64 %ind
  %loadD = load i16, ptr %arrayidxD, align 4

  %arrayidxE = getelementptr inbounds i16, ptr %e, i64 %ind
  %loadE = load i16, ptr %arrayidxE, align 4

  %convergentD = call i16 @llvm.convergent(i16 %loadD)
  %mulC = mul i16 %convergentD, %loadE

  %arrayidxC = getelementptr inbounds i16, ptr %c, i64 %ind
  store i16 %mulC, ptr %arrayidxC, align 4

  %exitcond = icmp eq i64 %add, 20
  br i1 %exitcond, label %for.end, label %for.body

for.end:                                          ; preds = %for.body
  ret void
}

declare i16 @llvm.convergent(i16) #0

attributes #0 = { nounwind readnone convergent }