Files
clang-p2996/llvm/test/Transforms/LoopFusion/diagnostics_missed.ll
Kit Barton de0b633999 [LoopFusion] Extend use of OptimizationRemarkEmitter
Summary:
This patch extends the use of the OptimizationRemarkEmitter to provide
information about loops that are not fused, and loops that are not eligible for
fusion. In particular, it uses the OptimizationRemarkAnalysis to identify loops
that are not eligible for fusion and the OptimizationRemarkMissed to identify
loops that cannot be fused.

It also reuses the statistics to provide the messages used in the
OptimizationRemarks. This provides common message strings between the
optimization remarks and the statistics.

I would like feedback on this approach, in general. If people are OK with this,
I will flesh out additional remarks in subsequent commits.

Subscribers: hiraditya, jsji, llvm-commits

Tags: #llvm

Differential Revision: https://reviews.llvm.org/D63844

llvm-svn: 367327
2019-07-30 15:58:43 +00:00

302 lines
14 KiB
LLVM

; RUN: opt -S -loop-fusion -pass-remarks-missed=loop-fusion -disable-output < %s 2>&1 | FileCheck %s
;
target datalayout = "e-m:o-i64:64-f80:128-n8:16:32:64-S128"
@B = common global [1024 x i32] zeroinitializer, align 16, !dbg !0
; CHECK: remark: diagnostics_missed.c:18:3: [non_adjacent]: entry and for.end: Loops are not adjacent
define void @non_adjacent(i32* noalias %A) !dbg !67 {
entry:
br label %for.cond
for.cond: ; preds = %for.inc, %entry
%i.0 = phi i64 [ 0, %entry ], [ %inc, %for.inc ]
%exitcond1 = icmp ne i64 %i.0, 100
br i1 %exitcond1, label %for.body, label %for.cond.cleanup
for.cond.cleanup: ; preds = %for.cond
br label %for.end
for.body: ; preds = %for.cond
%sub = add nsw i64 %i.0, -3
%add = add nuw nsw i64 %i.0, 3
%mul = mul nsw i64 %sub, %add
%rem = srem i64 %mul, %i.0
%conv = trunc i64 %rem to i32
%arrayidx = getelementptr inbounds i32, i32* %A, i64 %i.0
store i32 %conv, i32* %arrayidx, align 4
br label %for.inc
for.inc: ; preds = %for.body
%inc = add nuw nsw i64 %i.0, 1, !dbg !86
br label %for.cond, !dbg !87, !llvm.loop !88
for.end: ; preds = %for.cond.cleanup
br label %for.cond2
for.cond2: ; preds = %for.inc13, %for.end
%i1.0 = phi i64 [ 0, %for.end ], [ %inc14, %for.inc13 ]
%exitcond = icmp ne i64 %i1.0, 100
br i1 %exitcond, label %for.body6, label %for.cond.cleanup5
for.cond.cleanup5: ; preds = %for.cond2
br label %for.end15
for.body6: ; preds = %for.cond2
%sub7 = add nsw i64 %i1.0, -3
%add8 = add nuw nsw i64 %i1.0, 3
%mul9 = mul nsw i64 %sub7, %add8
%rem10 = srem i64 %mul9, %i1.0
%conv11 = trunc i64 %rem10 to i32
%arrayidx12 = getelementptr inbounds [1024 x i32], [1024 x i32]* @B, i64 0, i64 %i1.0
store i32 %conv11, i32* %arrayidx12, align 4
br label %for.inc13
for.inc13: ; preds = %for.body6
%inc14 = add nuw nsw i64 %i1.0, 1, !dbg !100
br label %for.cond2, !dbg !101, !llvm.loop !102
for.end15: ; preds = %for.cond.cleanup5
ret void
}
; CHECK: remark: diagnostics_missed.c:28:3: [different_bounds]: entry and for.end: Loop trip counts are not the same
define void @different_bounds(i32* noalias %A) !dbg !105 {
entry:
br label %for.cond
for.cond: ; preds = %for.inc, %entry
%i.0 = phi i64 [ 0, %entry ], [ %inc, %for.inc ]
%exitcond1 = icmp ne i64 %i.0, 100
br i1 %exitcond1, label %for.body, label %for.cond.cleanup
for.cond.cleanup: ; preds = %for.cond
br label %for.end
for.body: ; preds = %for.cond
%sub = add nsw i64 %i.0, -3
%add = add nuw nsw i64 %i.0, 3
%mul = mul nsw i64 %sub, %add
%rem = srem i64 %mul, %i.0
%conv = trunc i64 %rem to i32
%arrayidx = getelementptr inbounds i32, i32* %A, i64 %i.0
store i32 %conv, i32* %arrayidx, align 4
br label %for.inc
for.inc: ; preds = %for.body
%inc = add nuw nsw i64 %i.0, 1, !dbg !123
br label %for.cond, !dbg !124, !llvm.loop !125
for.end: ; preds = %for.cond.cleanup
br label %for.cond2
for.cond2: ; preds = %for.inc13, %for.end
%i1.0 = phi i64 [ 0, %for.end ], [ %inc14, %for.inc13 ]
%exitcond = icmp ne i64 %i1.0, 200
br i1 %exitcond, label %for.body6, label %for.cond.cleanup5
for.cond.cleanup5: ; preds = %for.cond2
br label %for.end15
for.body6: ; preds = %for.cond2
%sub7 = add nsw i64 %i1.0, -3
%add8 = add nuw nsw i64 %i1.0, 3
%mul9 = mul nsw i64 %sub7, %add8
%rem10 = srem i64 %mul9, %i1.0
%conv11 = trunc i64 %rem10 to i32
%arrayidx12 = getelementptr inbounds [1024 x i32], [1024 x i32]* @B, i64 0, i64 %i1.0
store i32 %conv11, i32* %arrayidx12, align 4
br label %for.inc13
for.inc13: ; preds = %for.body6
%inc14 = add nuw nsw i64 %i1.0, 1
br label %for.cond2, !dbg !138, !llvm.loop !139
for.end15: ; preds = %for.cond.cleanup5
ret void
}
; CHECK: remark: diagnostics_missed.c:38:3: [negative_dependence]: entry and for.end: Loop has a non-empty preheader
define void @negative_dependence(i32* noalias %A) !dbg !142 {
entry:
br label %for.cond
for.cond: ; preds = %for.inc, %entry
%indvars.iv1 = phi i64 [ %indvars.iv.next2, %for.inc ], [ 0, %entry ]
%exitcond3 = icmp ne i64 %indvars.iv1, 100
br i1 %exitcond3, label %for.body, label %for.end
for.body: ; preds = %for.cond
%arrayidx = getelementptr inbounds i32, i32* %A, i64 %indvars.iv1
%tmp = trunc i64 %indvars.iv1 to i32
store i32 %tmp, i32* %arrayidx, align 4
br label %for.inc
for.inc: ; preds = %for.body
%indvars.iv.next2 = add nuw nsw i64 %indvars.iv1, 1
br label %for.cond, !dbg !160, !llvm.loop !161
for.end: ; preds = %for.cond
call void @llvm.dbg.value(metadata i32 0, metadata !147, metadata !DIExpression()), !dbg !163
br label %for.cond2, !dbg !164
for.cond2: ; preds = %for.inc10, %for.end
%indvars.iv = phi i64 [ %indvars.iv.next, %for.inc10 ], [ 0, %for.end ]
%exitcond = icmp ne i64 %indvars.iv, 100
br i1 %exitcond, label %for.body5, label %for.end12
for.body5: ; preds = %for.cond2
%indvars.iv.next = add nuw nsw i64 %indvars.iv, 1
%arrayidx7 = getelementptr inbounds i32, i32* %A, i64 %indvars.iv.next
%tmp4 = load i32, i32* %arrayidx7, align 4
%mul = shl nsw i32 %tmp4, 1
%arrayidx9 = getelementptr inbounds [1024 x i32], [1024 x i32]* @B, i64 0, i64 %indvars.iv
store i32 %mul, i32* %arrayidx9, align 4
br label %for.inc10
for.inc10: ; preds = %for.body5
br label %for.cond2
for.end12: ; preds = %for.cond.
ret void, !dbg !178
}
; CHECK: remark: diagnostics_missed.c:51:3: [sumTest]: entry and for.cond2.preheader: Dependencies prevent fusion
define i32 @sumTest(i32* noalias %A) !dbg !179 {
entry:
br label %for.cond
for.cond: ; preds = %for.inc, %entry
%indvars.iv1 = phi i64 [ %indvars.iv.next2, %for.inc ], [ 0, %entry ]
%sum.0 = phi i32 [ 0, %entry ], [ %add, %for.inc ]
%exitcond3 = icmp ne i64 %indvars.iv1, 100
br i1 %exitcond3, label %for.body, label %for.cond2
for.body: ; preds = %for.cond
br label %for.inc
for.inc: ; preds = %for.body
%arrayidx = getelementptr inbounds i32, i32* %A, i64 %indvars.iv1
%tmp = load i32, i32* %arrayidx, align 4
%add = add nsw i32 %sum.0, %tmp
%indvars.iv.next2 = add nuw nsw i64 %indvars.iv1, 1
br label %for.cond, !dbg !199, !llvm.loop !200
for.cond2: ; preds = %for.inc10, %for.cond
%sum.0.lcssa = phi i32 [ %sum.0, %for.cond ], [ %sum.0.lcssa, %for.inc10 ]
%indvars.iv = phi i64 [ %indvars.iv.next, %for.inc10 ], [ 0, %for.cond ]
%exitcond = icmp ne i64 %indvars.iv, 100
br i1 %exitcond, label %for.body5, label %for.end12
for.body5: ; preds = %for.cond2
%arrayidx7 = getelementptr inbounds i32, i32* %A, i64 %indvars.iv
%tmp4 = load i32, i32* %arrayidx7, align 4
%div = sdiv i32 %tmp4, %sum.0.lcssa
%arrayidx9 = getelementptr inbounds [1024 x i32], [1024 x i32]* @B, i64 0, i64 %indvars.iv
store i32 %div, i32* %arrayidx9, align 4
br label %for.inc10
for.inc10: ; preds = %for.body5
%indvars.iv.next = add nuw nsw i64 %indvars.iv, 1
br label %for.cond2
for.end12: ; preds = %for.cond2
ret i32 %sum.0.lcssa, !dbg !215
}
declare void @llvm.dbg.value(metadata, metadata, metadata)
!llvm.dbg.cu = !{!2}
!llvm.module.flags = !{!11, !12, !13, !14}
!0 = !DIGlobalVariableExpression(var: !1, expr: !DIExpression())
!1 = distinct !DIGlobalVariable(name: "B", scope: !2, file: !6, line: 46, type: !7, isLocal: false, isDefinition: true)
!2 = distinct !DICompileUnit(language: DW_LANG_C99, file: !3, producer: "clang version 9.0.0 (git@github.ibm.com:compiler/llvm-project.git 23c4baaa9f5b33d2d52eda981d376c6b0a7a3180)", isOptimized: true, runtimeVersion: 0, emissionKind: FullDebug, enums: !4, globals: !5, nameTableKind: GNU)
!3 = !DIFile(filename: "diagnostics_missed.c", directory: "/tmp")
!4 = !{}
!5 = !{!0}
!6 = !DIFile(filename: "diagnostics_missed.c", directory: "/tmp")
!7 = !DICompositeType(tag: DW_TAG_array_type, baseType: !8, size: 32768, elements: !9)
!8 = !DIBasicType(name: "int", size: 32, encoding: DW_ATE_signed)
!9 = !{!10}
!10 = !DISubrange(count: 1024)
!11 = !{i32 2, !"Dwarf Version", i32 4}
!12 = !{i32 2, !"Debug Info Version", i32 3}
!13 = !{i32 1, !"wchar_size", i32 4}
!14 = !{i32 7, !"PIC Level", i32 2}
!17 = !DISubroutineType(types: !18)
!18 = !{null, !19}
!19 = !DIDerivedType(tag: DW_TAG_restrict_type, baseType: !20)
!20 = !DIDerivedType(tag: DW_TAG_pointer_type, baseType: !8, size: 64)
!67 = distinct !DISubprogram(name: "non_adjacent", scope: !6, file: !6, line: 17, type: !17, scopeLine: 17, flags: DIFlagPrototyped | DIFlagAllCallsDescribed, spFlags: DISPFlagDefinition | DISPFlagOptimized, unit: !2, retainedNodes: !68)
!68 = !{!69, !70, !73}
!69 = !DILocalVariable(name: "A", arg: 1, scope: !67, file: !6, line: 17, type: !19)
!70 = !DILocalVariable(name: "i", scope: !71, file: !6, line: 18, type: !72)
!71 = distinct !DILexicalBlock(scope: !67, file: !6, line: 18, column: 3)
!72 = !DIBasicType(name: "long int", size: 64, encoding: DW_ATE_signed)
!73 = !DILocalVariable(name: "i", scope: !74, file: !6, line: 22, type: !72)
!74 = distinct !DILexicalBlock(scope: !67, file: !6, line: 22, column: 3)
!79 = distinct !DILexicalBlock(scope: !71, file: !6, line: 18, column: 3)
!80 = !DILocation(line: 18, column: 3, scope: !71)
!86 = !DILocation(line: 18, column: 30, scope: !79)
!87 = !DILocation(line: 18, column: 3, scope: !79)
!88 = distinct !{!88, !80, !89}
!89 = !DILocation(line: 20, column: 3, scope: !71)
!93 = distinct !DILexicalBlock(scope: !74, file: !6, line: 22, column: 3)
!94 = !DILocation(line: 22, column: 3, scope: !74)
!100 = !DILocation(line: 22, column: 30, scope: !93)
!101 = !DILocation(line: 22, column: 3, scope: !93)
!102 = distinct !{!102, !94, !103}
!103 = !DILocation(line: 24, column: 3, scope: !74)
!105 = distinct !DISubprogram(name: "different_bounds", scope: !6, file: !6, line: 27, type: !17, scopeLine: 27, flags: DIFlagPrototyped | DIFlagAllCallsDescribed, spFlags: DISPFlagDefinition | DISPFlagOptimized, unit: !2, retainedNodes: !106)
!106 = !{!107, !108, !110}
!107 = !DILocalVariable(name: "A", arg: 1, scope: !105, file: !6, line: 27, type: !19)
!108 = !DILocalVariable(name: "i", scope: !109, file: !6, line: 28, type: !72)
!109 = distinct !DILexicalBlock(scope: !105, file: !6, line: 28, column: 3)
!110 = !DILocalVariable(name: "i", scope: !111, file: !6, line: 32, type: !72)
!111 = distinct !DILexicalBlock(scope: !105, file: !6, line: 32, column: 3)
!116 = distinct !DILexicalBlock(scope: !109, file: !6, line: 28, column: 3)
!117 = !DILocation(line: 28, column: 3, scope: !109)
!123 = !DILocation(line: 28, column: 30, scope: !116)
!124 = !DILocation(line: 28, column: 3, scope: !116)
!125 = distinct !{!125, !117, !126}
!126 = !DILocation(line: 30, column: 3, scope: !109)
!130 = distinct !DILexicalBlock(scope: !111, file: !6, line: 32, column: 3)
!131 = !DILocation(line: 32, column: 3, scope: !111)
!138 = !DILocation(line: 32, column: 3, scope: !130)
!139 = distinct !{!139, !131, !140}
!140 = !DILocation(line: 34, column: 3, scope: !111)
!142 = distinct !DISubprogram(name: "negative_dependence", scope: !6, file: !6, line: 37, type: !17, scopeLine: 37, flags: DIFlagPrototyped | DIFlagAllCallsDescribed, spFlags: DISPFlagDefinition | DISPFlagOptimized, unit: !2, retainedNodes: !143)
!143 = !{!144, !145, !147}
!144 = !DILocalVariable(name: "A", arg: 1, scope: !142, file: !6, line: 37, type: !19)
!145 = !DILocalVariable(name: "i", scope: !146, file: !6, line: 38, type: !8)
!146 = distinct !DILexicalBlock(scope: !142, file: !6, line: 38, column: 3)
!147 = !DILocalVariable(name: "i", scope: !148, file: !6, line: 42, type: !8)
!148 = distinct !DILexicalBlock(scope: !142, file: !6, line: 42, column: 3)
!153 = distinct !DILexicalBlock(scope: !146, file: !6, line: 38, column: 3)
!154 = !DILocation(line: 38, column: 3, scope: !146)
!160 = !DILocation(line: 38, column: 3, scope: !153)
!161 = distinct !{!161, !154, !162}
!162 = !DILocation(line: 40, column: 3, scope: !146)
!163 = !DILocation(line: 0, scope: !148)
!164 = !DILocation(line: 42, column: 8, scope: !148)
!178 = !DILocation(line: 45, column: 1, scope: !142)
!179 = distinct !DISubprogram(name: "sumTest", scope: !6, file: !6, line: 48, type: !180, scopeLine: 48, flags: DIFlagPrototyped | DIFlagAllCallsDescribed, spFlags: DISPFlagDefinition | DISPFlagOptimized, unit: !2, retainedNodes: !182)
!180 = !DISubroutineType(types: !181)
!181 = !{!8, !19}
!182 = !{!183, !184, !185, !187}
!183 = !DILocalVariable(name: "A", arg: 1, scope: !179, file: !6, line: 48, type: !19)
!184 = !DILocalVariable(name: "sum", scope: !179, file: !6, line: 49, type: !8)
!185 = !DILocalVariable(name: "i", scope: !186, file: !6, line: 51, type: !8)
!186 = distinct !DILexicalBlock(scope: !179, file: !6, line: 51, column: 3)
!187 = !DILocalVariable(name: "i", scope: !188, file: !6, line: 54, type: !8)
!188 = distinct !DILexicalBlock(scope: !179, file: !6, line: 54, column: 3)
!193 = distinct !DILexicalBlock(scope: !186, file: !6, line: 51, column: 3)
!194 = !DILocation(line: 51, column: 3, scope: !186)
!199 = !DILocation(line: 51, column: 3, scope: !193)
!200 = distinct !{!200, !194, !201}
!201 = !DILocation(line: 52, column: 15, scope: !186)
!215 = !DILocation(line: 57, column: 3, scope: !179)