diff options
| author | Dimitry Andric <dim@FreeBSD.org> | 2015-12-30 11:46:15 +0000 |
|---|---|---|
| committer | Dimitry Andric <dim@FreeBSD.org> | 2015-12-30 11:46:15 +0000 |
| commit | dd58ef019b700900793a1eb48b52123db01b654e (patch) | |
| tree | fcfbb4df56a744f4ddc6122c50521dd3f1c5e196 /test/Transforms/DeadStoreElimination | |
| parent | 2fe5752e3a7c345cdb59e869278d36af33c13fa4 (diff) | |
Notes
Diffstat (limited to 'test/Transforms/DeadStoreElimination')
| -rw-r--r-- | test/Transforms/DeadStoreElimination/calloc-store.ll | 65 | ||||
| -rw-r--r-- | test/Transforms/DeadStoreElimination/inst-limits.ll | 8 | ||||
| -rw-r--r-- | test/Transforms/DeadStoreElimination/simple.ll | 147 |
3 files changed, 216 insertions, 4 deletions
diff --git a/test/Transforms/DeadStoreElimination/calloc-store.ll b/test/Transforms/DeadStoreElimination/calloc-store.ll new file mode 100644 index 000000000000..daba61332065 --- /dev/null +++ b/test/Transforms/DeadStoreElimination/calloc-store.ll @@ -0,0 +1,65 @@ +; RUN: opt < %s -basicaa -dse -S | FileCheck %s + +declare noalias i8* @calloc(i64, i64) + +define i32* @test1() { +; CHECK-LABEL: test1 + %1 = tail call noalias i8* @calloc(i64 1, i64 4) + %2 = bitcast i8* %1 to i32* + ; This store is dead and should be removed + store i32 0, i32* %2, align 4 +; CHECK-NOT: store i32 0, i32* %2, align 4 + ret i32* %2 +} + +define i32* @test2() { +; CHECK-LABEL: test2 + %1 = tail call noalias i8* @calloc(i64 1, i64 4) + %2 = bitcast i8* %1 to i32* + %3 = getelementptr i32, i32* %2, i32 5 + store i32 0, i32* %3, align 4 +; CHECK-NOT: store i32 0, i32* %2, align 4 + ret i32* %2 +} + +define i32* @test3(i32 *%arg) { +; CHECK-LABEL: test3 + store i32 0, i32* %arg, align 4 +; CHECK: store i32 0, i32* %arg, align 4 + ret i32* %arg +} + +declare void @clobber_memory(i8*) +define i8* @test4() { +; CHECK-LABEL: test4 + %1 = tail call noalias i8* @calloc(i64 1, i64 4) + call void @clobber_memory(i8* %1) + store i8 0, i8* %1, align 4 +; CHECK: store i8 0, i8* %1, align 4 + ret i8* %1 +} + +define i32* @test5() { +; CHECK-LABEL: test5 + %1 = tail call noalias i8* @calloc(i64 1, i64 4) + %2 = bitcast i8* %1 to i32* + store volatile i32 0, i32* %2, align 4 +; CHECK: store volatile i32 0, i32* %2, align 4 + ret i32* %2 +} + +define i8* @test6() { +; CHECK-LABEL: test6 + %1 = tail call noalias i8* @calloc(i64 1, i64 4) + store i8 5, i8* %1, align 4 +; CHECK: store i8 5, i8* %1, align 4 + ret i8* %1 +} + +define i8* @test7(i8 %arg) { +; CHECK-LABEL: test7 + %1 = tail call noalias i8* @calloc(i64 1, i64 4) + store i8 %arg, i8* %1, align 4 +; CHECK: store i8 %arg, i8* %1, align 4 + ret i8* %1 +} diff --git a/test/Transforms/DeadStoreElimination/inst-limits.ll b/test/Transforms/DeadStoreElimination/inst-limits.ll index 54e41c8b413b..5848ab89bc88 100644 --- a/test/Transforms/DeadStoreElimination/inst-limits.ll +++ b/test/Transforms/DeadStoreElimination/inst-limits.ll @@ -9,7 +9,7 @@ target datalayout = "e-m:e-i64:64-f80:128-n8:16:32:64-S128" @x = global i32 0, align 4 ; Function Attrs: nounwind -define i32 @test_within_limit() { +define i32 @test_within_limit() !dbg !4 { entry: ; The first store; later there is a second store to the same location, ; so this store should be optimized away by DSE. @@ -245,17 +245,17 @@ declare void @llvm.dbg.value(metadata, i64, metadata, metadata) !llvm.dbg.cu = !{!0} !llvm.module.flags = !{!11, !13} -!0 = !DICompileUnit(language: DW_LANG_C_plus_plus, producer: "clang version 3.4", isOptimized: true, emissionKind: 0, file: !1, enums: !2, retainedTypes: !2, subprograms: !3, globals: !2, imports: !2) +!0 = distinct !DICompileUnit(language: DW_LANG_C_plus_plus, producer: "clang version 3.4", isOptimized: true, emissionKind: 0, file: !1, enums: !2, retainedTypes: !2, subprograms: !3, globals: !2, imports: !2) !1 = !DIFile(filename: "test.c", directory: "/home/tmp") !2 = !{} !3 = !{!4} -!4 = !DISubprogram(name: "test_within_limit", line: 3, isLocal: false, isDefinition: true, virtualIndex: 6, flags: DIFlagPrototyped, isOptimized: false, scopeLine: 4, file: !1, scope: !5, type: !6, function: i32 ()* @test_within_limit, variables: !2) +!4 = distinct !DISubprogram(name: "test_within_limit", line: 3, isLocal: false, isDefinition: true, virtualIndex: 6, flags: DIFlagPrototyped, isOptimized: false, scopeLine: 4, file: !1, scope: !5, type: !6, variables: !2) !5 = !DIFile(filename: "test.c", directory: "/home/tmp") !6 = !DISubroutineType(types: !7) !7 = !{!8} !8 = !DIBasicType(tag: DW_TAG_base_type, name: "int", size: 32, align: 32, encoding: DW_ATE_signed) !9 = !{!10} -!10 = !DILocalVariable(tag: DW_TAG_auto_variable, name: "x", scope: !4, type: !8) +!10 = !DILocalVariable(name: "x", scope: !4, type: !8) !11 = !{i32 2, !"Dwarf Version", i32 4} !12 = !{i32* undef} diff --git a/test/Transforms/DeadStoreElimination/simple.ll b/test/Transforms/DeadStoreElimination/simple.ll index 2ffe0539098e..4f6221db2454 100644 --- a/test/Transforms/DeadStoreElimination/simple.ll +++ b/test/Transforms/DeadStoreElimination/simple.ll @@ -350,3 +350,150 @@ define i8* @test25(i8* %p) nounwind { store i8 %tmp, i8* %p.4, align 1 ret i8* %q } + +; Remove redundant store if loaded value is in another block. +; CHECK-LABEL: @test26( +; CHECK-NOT: store +; CHECK: ret +define i32 @test26(i1 %c, i32* %p) { +entry: + %v = load i32, i32* %p, align 4 + br i1 %c, label %bb1, label %bb2 +bb1: + br label %bb3 +bb2: + store i32 %v, i32* %p, align 4 + br label %bb3 +bb3: + ret i32 0 +} + +; Remove redundant store if loaded value is in another block. +; CHECK-LABEL: @test27( +; CHECK-NOT: store +; CHECK: ret +define i32 @test27(i1 %c, i32* %p) { +entry: + %v = load i32, i32* %p, align 4 + br i1 %c, label %bb1, label %bb2 +bb1: + br label %bb3 +bb2: + br label %bb3 +bb3: + store i32 %v, i32* %p, align 4 + ret i32 0 +} + +; Don't remove redundant store because of may-aliased store. +; CHECK-LABEL: @test28( +; CHECK: bb3: +; CHECK-NEXT: store i32 %v +define i32 @test28(i1 %c, i32* %p, i32* %p2, i32 %i) { +entry: + %v = load i32, i32* %p, align 4 + + ; Might overwrite value at %p + store i32 %i, i32* %p2, align 4 + br i1 %c, label %bb1, label %bb2 +bb1: + br label %bb3 +bb2: + br label %bb3 +bb3: + store i32 %v, i32* %p, align 4 + ret i32 0 +} + +; Don't remove redundant store because of may-aliased store. +; CHECK-LABEL: @test29( +; CHECK: bb3: +; CHECK-NEXT: store i32 %v +define i32 @test29(i1 %c, i32* %p, i32* %p2, i32 %i) { +entry: + %v = load i32, i32* %p, align 4 + br i1 %c, label %bb1, label %bb2 +bb1: + br label %bb3 +bb2: + ; Might overwrite value at %p + store i32 %i, i32* %p2, align 4 + br label %bb3 +bb3: + store i32 %v, i32* %p, align 4 + ret i32 0 +} + +declare void @unknown_func() + +; Don't remove redundant store because of unknown call. +; CHECK-LABEL: @test30( +; CHECK: bb3: +; CHECK-NEXT: store i32 %v +define i32 @test30(i1 %c, i32* %p, i32 %i) { +entry: + %v = load i32, i32* %p, align 4 + br i1 %c, label %bb1, label %bb2 +bb1: + br label %bb3 +bb2: + ; Might overwrite value at %p + call void @unknown_func() + br label %bb3 +bb3: + store i32 %v, i32* %p, align 4 + ret i32 0 +} + +; Remove redundant store if loaded value is in another block inside a loop. +; CHECK-LABEL: @test31( +; CHECK-NOT: store +; CHECK: ret +define i32 @test31(i1 %c, i32* %p, i32 %i) { +entry: + %v = load i32, i32* %p, align 4 + br label %bb1 +bb1: + store i32 %v, i32* %p, align 4 + br i1 undef, label %bb1, label %bb2 +bb2: + ret i32 0 +} + +; Don't remove redundant store in a loop with a may-alias store. +; CHECK-LABEL: @test32( +; CHECK: bb1: +; CHECK-NEXT: store i32 %v +; CHECK-NEXT: call void @unknown_func +define i32 @test32(i1 %c, i32* %p, i32 %i) { +entry: + %v = load i32, i32* %p, align 4 + br label %bb1 +bb1: + store i32 %v, i32* %p, align 4 + ; Might read and overwrite value at %p + call void @unknown_func() + br i1 undef, label %bb1, label %bb2 +bb2: + ret i32 0 +} + +; Remove redundant store, which is in the lame loop as the load. +; CHECK-LABEL: @test33( +; CHECK-NOT: store +; CHECK: ret +define i32 @test33(i1 %c, i32* %p, i32 %i) { +entry: + br label %bb1 +bb1: + %v = load i32, i32* %p, align 4 + br label %bb2 +bb2: + store i32 %v, i32* %p, align 4 + ; Might read and overwrite value at %p, but doesn't matter. + call void @unknown_func() + br i1 undef, label %bb1, label %bb3 +bb3: + ret i32 0 +} + |
