llvm-project/llvm/test/Transforms/LoopFusion/diagnostics_missed.ll
Kit Barton ff07fc66d9 [LoopFusion] Restrict loop fusion to rotated loops.
Summary:
This patch restricts loop fusion to only consider rotated loops as valid candidates.
This simplifies the analysis and transformation and aligns with other loop optimizations.

Reviewers: jdoerfert, Meinersbur, dmgreen, etiotto, Whitney, fhahn, hfinkel

Reviewed By: Meinersbur

Subscribers: ormris, hiraditya, llvm-commits

Tags: #llvm

Differential Revision: https://reviews.llvm.org/D71025
2019-12-16 15:17:29 -05:00

270 lines
13 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 !14 {
entry:
br label %for.body
for.cond.cleanup: ; preds = %for.inc
br label %for.end
for.body: ; preds = %entry, %for.inc
%i.02 = phi i64 [ 0, %entry ], [ %inc, %for.inc ]
%sub = add nsw i64 %i.02, -3
%add = add nuw nsw i64 %i.02, 3
%mul = mul nsw i64 %sub, %add
%rem = srem i64 %mul, %i.02
%conv = trunc i64 %rem to i32
%arrayidx = getelementptr inbounds i32, i32* %A, i64 %i.02
store i32 %conv, i32* %arrayidx, align 4
br label %for.inc
for.inc: ; preds = %for.body
%inc = add nuw nsw i64 %i.02, 1, !dbg !26
%exitcond1 = icmp ne i64 %inc, 100
br i1 %exitcond1, label %for.body, label %for.cond.cleanup, !llvm.loop !28
for.end: ; preds = %for.cond.cleanup
br label %for.body6
for.cond.cleanup5: ; preds = %for.inc13
br label %for.end15
for.body6: ; preds = %for.end, %for.inc13
%i1.01 = phi i64 [ 0, %for.end ], [ %inc14, %for.inc13 ]
%sub7 = add nsw i64 %i1.01, -3
%add8 = add nuw nsw i64 %i1.01, 3
%mul9 = mul nsw i64 %sub7, %add8
%rem10 = srem i64 %mul9, %i1.01
%conv11 = trunc i64 %rem10 to i32
%arrayidx12 = getelementptr inbounds [1024 x i32], [1024 x i32]* @B, i64 0, i64 %i1.01
store i32 %conv11, i32* %arrayidx12, align 4
br label %for.inc13
for.inc13: ; preds = %for.body6
%inc14 = add nuw nsw i64 %i1.01, 1, !dbg !31
%exitcond = icmp ne i64 %inc14, 100
br i1 %exitcond, label %for.body6, label %for.cond.cleanup5, !llvm.loop !33
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 !36 {
entry:
br label %for.body
for.cond.cleanup: ; preds = %for.inc
br label %for.end
for.body: ; preds = %entry, %for.inc
%i.02 = phi i64 [ 0, %entry ], [ %inc, %for.inc ]
%sub = add nsw i64 %i.02, -3
%add = add nuw nsw i64 %i.02, 3
%mul = mul nsw i64 %sub, %add
%rem = srem i64 %mul, %i.02
%conv = trunc i64 %rem to i32
%arrayidx = getelementptr inbounds i32, i32* %A, i64 %i.02
store i32 %conv, i32* %arrayidx, align 4
br label %for.inc
for.inc: ; preds = %for.body
%inc = add nuw nsw i64 %i.02, 1, !dbg !43
%exitcond1 = icmp ne i64 %inc, 100
br i1 %exitcond1, label %for.body, label %for.cond.cleanup, !llvm.loop !45
for.end: ; preds = %for.cond.cleanup
br label %for.body6
for.cond.cleanup5: ; preds = %for.inc13
br label %for.end15
for.body6: ; preds = %for.end, %for.inc13
%i1.01 = phi i64 [ 0, %for.end ], [ %inc14, %for.inc13 ]
%sub7 = add nsw i64 %i1.01, -3
%add8 = add nuw nsw i64 %i1.01, 3
%mul9 = mul nsw i64 %sub7, %add8
%rem10 = srem i64 %mul9, %i1.01
%conv11 = trunc i64 %rem10 to i32
%arrayidx12 = getelementptr inbounds [1024 x i32], [1024 x i32]* @B, i64 0, i64 %i1.01
store i32 %conv11, i32* %arrayidx12, align 4
br label %for.inc13
for.inc13: ; preds = %for.body6
%inc14 = add nuw nsw i64 %i1.01, 1
%exitcond = icmp ne i64 %inc14, 200
br i1 %exitcond, label %for.body6, label %for.cond.cleanup5, !llvm.loop !48
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 !51 {
entry:
br label %for.body
for.body: ; preds = %entry, %for.inc
%indvars.iv13 = phi i64 [ 0, %entry ], [ %indvars.iv.next2, %for.inc ]
%arrayidx = getelementptr inbounds i32, i32* %A, i64 %indvars.iv13
%tmp = trunc i64 %indvars.iv13 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.iv13, 1
%exitcond3 = icmp ne i64 %indvars.iv.next2, 100
br i1 %exitcond3, label %for.body, label %for.end, !llvm.loop !58
for.end: ; preds = %for.inc
call void @llvm.dbg.value(metadata i32 0, metadata !56, metadata !DIExpression()), !dbg !61
br label %for.body5
for.body5: ; preds = %for.end, %for.inc10
%indvars.iv2 = phi i64 [ 0, %for.end ], [ %indvars.iv.next, %for.inc10 ]
%indvars.iv.next = add nuw nsw i64 %indvars.iv2, 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.iv2
store i32 %mul, i32* %arrayidx9, align 4
br label %for.inc10
for.inc10: ; preds = %for.body5
%exitcond = icmp ne i64 %indvars.iv.next, 100
br i1 %exitcond, label %for.body5, label %for.end12
for.end12: ; preds = %for.inc10
ret void, !dbg !62
}
; CHECK: remark: diagnostics_missed.c:51:3: [sumTest]: entry and for.cond2.preheader: Dependencies prevent fusion
define i32 @sumTest(i32* noalias %A) !dbg !63 {
entry:
br label %for.body
for.cond2.preheader: ; preds = %for.inc
br label %for.body5
for.body: ; preds = %entry, %for.inc
%sum.04 = phi i32 [ 0, %entry ], [ %add, %for.inc ]
%indvars.iv13 = phi i64 [ 0, %entry ], [ %indvars.iv.next2, %for.inc ]
br label %for.inc
for.inc: ; preds = %for.body
%arrayidx = getelementptr inbounds i32, i32* %A, i64 %indvars.iv13
%tmp = load i32, i32* %arrayidx, align 4
%add = add nsw i32 %sum.04, %tmp
%indvars.iv.next2 = add nuw nsw i64 %indvars.iv13, 1
%exitcond3 = icmp ne i64 %indvars.iv.next2, 100
br i1 %exitcond3, label %for.body, label %for.cond2.preheader, !llvm.loop !73
for.body5: ; preds = %for.cond2.preheader, %for.inc10
%indvars.iv2 = phi i64 [ 0, %for.cond2.preheader ], [ %indvars.iv.next, %for.inc10 ]
%arrayidx7 = getelementptr inbounds i32, i32* %A, i64 %indvars.iv2
%tmp4 = load i32, i32* %arrayidx7, align 4
%div = sdiv i32 %tmp4, %add
%arrayidx9 = getelementptr inbounds [1024 x i32], [1024 x i32]* @B, i64 0, i64 %indvars.iv2
store i32 %div, i32* %arrayidx9, align 4
br label %for.inc10
for.inc10: ; preds = %for.body5
%indvars.iv.next = add nuw nsw i64 %indvars.iv2, 1
%exitcond = icmp ne i64 %indvars.iv.next, 100
br i1 %exitcond, label %for.body5, label %for.end12
for.end12: ; preds = %for.inc10
ret i32 %add, !dbg !76
}
; Function Attrs: nounwind readnone speculatable willreturn
declare void @llvm.dbg.value(metadata, metadata, metadata) #0
attributes #0 = { nounwind readnone speculatable willreturn }
!llvm.dbg.cu = !{!2}
!llvm.module.flags = !{!10, !11, !12, !13}
!0 = !DIGlobalVariableExpression(var: !1, expr: !DIExpression())
!1 = distinct !DIGlobalVariable(name: "B", scope: !2, file: !3, line: 46, type: !6, 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 = !DICompositeType(tag: DW_TAG_array_type, baseType: !7, size: 32768, elements: !8)
!7 = !DIBasicType(name: "int", size: 32, encoding: DW_ATE_signed)
!8 = !{!9}
!9 = !DISubrange(count: 1024)
!10 = !{i32 2, !"Dwarf Version", i32 4}
!11 = !{i32 2, !"Debug Info Version", i32 3}
!12 = !{i32 1, !"wchar_size", i32 4}
!13 = !{i32 7, !"PIC Level", i32 2}
!14 = distinct !DISubprogram(name: "non_adjacent", scope: !3, file: !3, line: 17, type: !15, scopeLine: 17, flags: DIFlagPrototyped | DIFlagAllCallsDescribed, spFlags: DISPFlagDefinition | DISPFlagOptimized, unit: !2, retainedNodes: !19)
!15 = !DISubroutineType(types: !16)
!16 = !{null, !17}
!17 = !DIDerivedType(tag: DW_TAG_restrict_type, baseType: !18)
!18 = !DIDerivedType(tag: DW_TAG_pointer_type, baseType: !7, size: 64)
!19 = !{!20, !21, !24}
!20 = !DILocalVariable(name: "A", arg: 1, scope: !14, file: !3, line: 17, type: !17)
!21 = !DILocalVariable(name: "i", scope: !22, file: !3, line: 18, type: !23)
!22 = distinct !DILexicalBlock(scope: !14, file: !3, line: 18, column: 3)
!23 = !DIBasicType(name: "long int", size: 64, encoding: DW_ATE_signed)
!24 = !DILocalVariable(name: "i", scope: !25, file: !3, line: 22, type: !23)
!25 = distinct !DILexicalBlock(scope: !14, file: !3, line: 22, column: 3)
!26 = !DILocation(line: 18, column: 30, scope: !27)
!27 = distinct !DILexicalBlock(scope: !22, file: !3, line: 18, column: 3)
!28 = distinct !{!28, !29, !30}
!29 = !DILocation(line: 18, column: 3, scope: !22)
!30 = !DILocation(line: 20, column: 3, scope: !22)
!31 = !DILocation(line: 22, column: 30, scope: !32)
!32 = distinct !DILexicalBlock(scope: !25, file: !3, line: 22, column: 3)
!33 = distinct !{!33, !34, !35}
!34 = !DILocation(line: 22, column: 3, scope: !25)
!35 = !DILocation(line: 24, column: 3, scope: !25)
!36 = distinct !DISubprogram(name: "different_bounds", scope: !3, file: !3, line: 27, type: !15, scopeLine: 27, flags: DIFlagPrototyped | DIFlagAllCallsDescribed, spFlags: DISPFlagDefinition | DISPFlagOptimized, unit: !2, retainedNodes: !37)
!37 = !{!38, !39, !41}
!38 = !DILocalVariable(name: "A", arg: 1, scope: !36, file: !3, line: 27, type: !17)
!39 = !DILocalVariable(name: "i", scope: !40, file: !3, line: 28, type: !23)
!40 = distinct !DILexicalBlock(scope: !36, file: !3, line: 28, column: 3)
!41 = !DILocalVariable(name: "i", scope: !42, file: !3, line: 32, type: !23)
!42 = distinct !DILexicalBlock(scope: !36, file: !3, line: 32, column: 3)
!43 = !DILocation(line: 28, column: 30, scope: !44)
!44 = distinct !DILexicalBlock(scope: !40, file: !3, line: 28, column: 3)
!45 = distinct !{!45, !46, !47}
!46 = !DILocation(line: 28, column: 3, scope: !40)
!47 = !DILocation(line: 30, column: 3, scope: !40)
!48 = distinct !{!48, !49, !50}
!49 = !DILocation(line: 32, column: 3, scope: !42)
!50 = !DILocation(line: 34, column: 3, scope: !42)
!51 = distinct !DISubprogram(name: "negative_dependence", scope: !3, file: !3, line: 37, type: !15, scopeLine: 37, flags: DIFlagPrototyped | DIFlagAllCallsDescribed, spFlags: DISPFlagDefinition | DISPFlagOptimized, unit: !2, retainedNodes: !52)
!52 = !{!53, !54, !56}
!53 = !DILocalVariable(name: "A", arg: 1, scope: !51, file: !3, line: 37, type: !17)
!54 = !DILocalVariable(name: "i", scope: !55, file: !3, line: 38, type: !7)
!55 = distinct !DILexicalBlock(scope: !51, file: !3, line: 38, column: 3)
!56 = !DILocalVariable(name: "i", scope: !57, file: !3, line: 42, type: !7)
!57 = distinct !DILexicalBlock(scope: !51, file: !3, line: 42, column: 3)
!58 = distinct !{!58, !59, !60}
!59 = !DILocation(line: 38, column: 3, scope: !55)
!60 = !DILocation(line: 40, column: 3, scope: !55)
!61 = !DILocation(line: 0, scope: !57)
!62 = !DILocation(line: 45, column: 1, scope: !51)
!63 = distinct !DISubprogram(name: "sumTest", scope: !3, file: !3, line: 48, type: !64, scopeLine: 48, flags: DIFlagPrototyped | DIFlagAllCallsDescribed, spFlags: DISPFlagDefinition | DISPFlagOptimized, unit: !2, retainedNodes: !66)
!64 = !DISubroutineType(types: !65)
!65 = !{!7, !17}
!66 = !{!67, !68, !69, !71}
!67 = !DILocalVariable(name: "A", arg: 1, scope: !63, file: !3, line: 48, type: !17)
!68 = !DILocalVariable(name: "sum", scope: !63, file: !3, line: 49, type: !7)
!69 = !DILocalVariable(name: "i", scope: !70, file: !3, line: 51, type: !7)
!70 = distinct !DILexicalBlock(scope: !63, file: !3, line: 51, column: 3)
!71 = !DILocalVariable(name: "i", scope: !72, file: !3, line: 54, type: !7)
!72 = distinct !DILexicalBlock(scope: !63, file: !3, line: 54, column: 3)
!73 = distinct !{!73, !74, !75}
!74 = !DILocation(line: 51, column: 3, scope: !70)
!75 = !DILocation(line: 52, column: 15, scope: !70)
!76 = !DILocation(line: 57, column: 3, scope: !63)