aboutsummaryrefslogtreecommitdiffstats
path: root/test/Transforms/InstCombine
diff options
context:
space:
mode:
Diffstat (limited to 'test/Transforms/InstCombine')
-rw-r--r--test/Transforms/InstCombine/2013-03-05-Combine-BitcastTy-Into-Alloca.ll45
-rw-r--r--test/Transforms/InstCombine/debuginfo.ll32
-rw-r--r--test/Transforms/InstCombine/fast-math.ll116
-rw-r--r--test/Transforms/InstCombine/objsize.ll128
4 files changed, 307 insertions, 14 deletions
diff --git a/test/Transforms/InstCombine/2013-03-05-Combine-BitcastTy-Into-Alloca.ll b/test/Transforms/InstCombine/2013-03-05-Combine-BitcastTy-Into-Alloca.ll
new file mode 100644
index 0000000..b20c3a0
--- /dev/null
+++ b/test/Transforms/InstCombine/2013-03-05-Combine-BitcastTy-Into-Alloca.ll
@@ -0,0 +1,45 @@
+; RUN: opt < %s -instcombine -S | FileCheck %s
+target datalayout = "e-p:64:64:64-i1:8:8-i8:8:8-i16:16:16-i32:32:32-i64:64:64-f32:32:32-f64:64:64-v64:64:64-v128:128:128-a0:0:64-s0:64:64-f80:128:128-n8:16:32:64-S128"
+target triple = "x86_64-apple-macosx10.9.0"
+
+%struct._my_struct = type <{ [12 x i8], [4 x i8] }>
+
+@initval = common global %struct._my_struct zeroinitializer, align 1
+
+; InstCombine will try to change the %struct._my_struct alloca into an
+; allocation of an i96 because of the bitcast to create %2. That's not valid,
+; as the other 32 bits of the structure still feed into the return value
+define { i64, i64 } @function(i32 %x, i32 %y, i32 %z) nounwind {
+; CHECK: @function
+; CHECK-NEXT: entry:
+; CHECK-NEXT: %retval = alloca %struct._my_struct, align 8
+; CHECK-NOT: bitcast i96* %retval to %struct._my_struct*
+entry:
+ %retval = alloca %struct._my_struct, align 8
+ %k.sroa.0.0.copyload = load i96* bitcast (%struct._my_struct* @initval to i96*), align 1
+ %k.sroa.1.12.copyload = load i32* bitcast ([4 x i8]* getelementptr inbounds (%struct._my_struct* @initval, i64 0, i32 1) to i32*), align 1
+ %0 = zext i32 %x to i96
+ %bf.value = shl nuw nsw i96 %0, 6
+ %bf.clear = and i96 %k.sroa.0.0.copyload, -288230376151711744
+ %1 = zext i32 %y to i96
+ %bf.value2 = shl nuw nsw i96 %1, 32
+ %bf.shl3 = and i96 %bf.value2, 288230371856744448
+ %bf.value.masked = and i96 %bf.value, 4294967232
+ %2 = zext i32 %z to i96
+ %bf.value8 = and i96 %2, 63
+ %bf.clear4 = or i96 %bf.shl3, %bf.value.masked
+ %bf.set5 = or i96 %bf.clear4, %bf.value8
+ %bf.set10 = or i96 %bf.set5, %bf.clear
+ %retval.0.cast7 = bitcast %struct._my_struct* %retval to i96*
+ store i96 %bf.set10, i96* %retval.0.cast7, align 8
+ %retval.12.idx8 = getelementptr inbounds %struct._my_struct* %retval, i64 0, i32 1
+ %retval.12.cast9 = bitcast [4 x i8]* %retval.12.idx8 to i32*
+ store i32 %k.sroa.1.12.copyload, i32* %retval.12.cast9, align 4
+ %trunc = trunc i96 %bf.set10 to i64
+ %.fca.0.insert = insertvalue { i64, i64 } undef, i64 %trunc, 0
+ %retval.8.idx12 = getelementptr inbounds %struct._my_struct* %retval, i64 0, i32 0, i64 8
+ %retval.8.cast13 = bitcast i8* %retval.8.idx12 to i64*
+ %retval.8.load14 = load i64* %retval.8.cast13, align 8
+ %.fca.1.insert = insertvalue { i64, i64 } %.fca.0.insert, i64 %retval.8.load14, 1
+ ret { i64, i64 } %.fca.1.insert
+}
diff --git a/test/Transforms/InstCombine/debuginfo.ll b/test/Transforms/InstCombine/debuginfo.ll
index f6892fc..e7fe71d 100644
--- a/test/Transforms/InstCombine/debuginfo.ll
+++ b/test/Transforms/InstCombine/debuginfo.ll
@@ -28,22 +28,21 @@ entry:
ret i8* %call, !dbg !21
}
-!llvm.dbg.lv.foobar = !{!0, !7, !9}
-!llvm.dbg.sp = !{!1}
+!llvm.dbg.cu = !{!3}
-!0 = metadata !{i32 590081, metadata !1, metadata !"__dest", metadata !2, i32 16777294, metadata !6, i32 0} ; [ DW_TAG_arg_variable ]
-!1 = metadata !{i32 589870, i32 0, metadata !2, metadata !"foobar", metadata !"foobar", metadata !"", metadata !2, i32 79, metadata !4, i1 true, i1 true, i32 0, i32 0, i32 0, i32 256, i1 true, i8* (i8*, i32, i64)* @foobar} ; [ DW_TAG_subprogram ]
-!2 = metadata !{i32 589865, metadata !"string.h", metadata !"Game", metadata !3} ; [ DW_TAG_file_type ]
-!3 = metadata !{i32 589841, i32 0, i32 12, metadata !"bits.c", metadata !"Game", metadata !"clang version 3.0 (trunk 127710)", i1 true, i1 true, metadata !"", i32 0} ; [ DW_TAG_compile_unit ]
-!4 = metadata !{i32 589845, metadata !2, metadata !"", metadata !2, i32 0, i64 0, i64 0, i32 0, i32 0, i32 0, metadata !5, i32 0, i32 0} ; [ DW_TAG_subroutine_type ]
+!0 = metadata !{i32 786689, metadata !1, metadata !"__dest", metadata !2, i32 16777294, metadata !6, i32 0, null} ; [ DW_TAG_arg_variable ]
+!1 = metadata !{i32 786478, i32 0, metadata !2, metadata !"foobar", metadata !"foobar", metadata !"", metadata !2, i32 79, metadata !4, i1 true, i1 true, i32 0, i32 0, i32 0, i32 256, i1 true, i8* (i8*, i32, i64)* @foobar, null, null, metadata !25, i32 79} ; [ DW_TAG_subprogram ]
+!2 = metadata !{i32 786473, metadata !27} ; [ DW_TAG_file_type ]
+!3 = metadata !{i32 786449, i32 0, i32 12, metadata !26, metadata !"clang version 3.0 (trunk 127710)", i1 true, metadata !"", i32 0, null, null, metadata !24, null, null} ; [ DW_TAG_compile_unit ]
+!4 = metadata !{i32 786453, metadata !2, metadata !"", metadata !2, i32 0, i64 0, i64 0, i32 0, i32 0, i32 0, metadata !5, i32 0, i32 0} ; [ DW_TAG_subroutine_type ]
!5 = metadata !{metadata !6}
-!6 = metadata !{i32 589839, metadata !3, metadata !"", null, i32 0, i64 64, i64 64, i64 0, i32 0, null} ; [ DW_TAG_pointer_type ]
-!7 = metadata !{i32 590081, metadata !1, metadata !"__val", metadata !2, i32 33554510, metadata !8, i32 0} ; [ DW_TAG_arg_variable ]
-!8 = metadata !{i32 589860, metadata !3, metadata !"int", null, i32 0, i64 32, i64 32, i64 0, i32 0, i32 5} ; [ DW_TAG_base_type ]
-!9 = metadata !{i32 590081, metadata !1, metadata !"__len", metadata !2, i32 50331726, metadata !10, i32 0} ; [ DW_TAG_arg_variable ]
+!6 = metadata !{i32 786447, metadata !3, metadata !"", null, i32 0, i64 64, i64 64, i64 0, i32 0, null} ; [ DW_TAG_pointer_type ]
+!7 = metadata !{i32 786689, metadata !1, metadata !"__val", metadata !2, i32 33554510, metadata !8, i32 0, null} ; [ DW_TAG_arg_variable ]
+!8 = metadata !{i32 786468, metadata !3, metadata !"int", null, i32 0, i64 32, i64 32, i64 0, i32 0, i32 5} ; [ DW_TAG_base_type ]
+!9 = metadata !{i32 786689, metadata !1, metadata !"__len", metadata !2, i32 50331726, metadata !10, i32 0, null} ; [ DW_TAG_arg_variable ]
!10 = metadata !{i32 589846, metadata !3, metadata !"size_t", metadata !2, i32 80, i64 0, i64 0, i64 0, i32 0, metadata !11} ; [ DW_TAG_typedef ]
!11 = metadata !{i32 589846, metadata !3, metadata !"__darwin_size_t", metadata !2, i32 90, i64 0, i64 0, i64 0, i32 0, metadata !12} ; [ DW_TAG_typedef ]
-!12 = metadata !{i32 589860, metadata !3, metadata !"long unsigned int", null, i32 0, i64 64, i64 64, i64 0, i32 0, i32 7} ; [ DW_TAG_base_type ]
+!12 = metadata !{i32 786468, metadata !3, metadata !"long unsigned int", null, i32 0, i64 64, i64 64, i64 0, i32 0, i32 7} ; [ DW_TAG_base_type ]
!13 = metadata !{metadata !"any pointer", metadata !14}
!14 = metadata !{metadata !"omnipotent char", metadata !15}
!15 = metadata !{metadata !"Simple C/C++ TBAA", null}
@@ -53,5 +52,10 @@ entry:
!19 = metadata !{metadata !"long", metadata !14}
!20 = metadata !{i32 78, i32 54, metadata !1, null}
!21 = metadata !{i32 80, i32 3, metadata !22, null}
-!22 = metadata !{i32 589835, metadata !23, i32 80, i32 3, metadata !2, i32 7} ; [ DW_TAG_lexical_block ]
-!23 = metadata !{i32 589835, metadata !1, i32 79, i32 1, metadata !2, i32 6} ; [ DW_TAG_lexical_block ]
+!22 = metadata !{i32 786443, metadata !23, i32 80, i32 3, metadata !2, i32 7} ; [ DW_TAG_lexical_block ]
+!23 = metadata !{i32 786443, metadata !1, i32 79, i32 1, metadata !2, i32 6} ; [ DW_TAG_lexical_block ]
+!24 = metadata !{metadata !1}
+!25 = metadata !{metadata !0, metadata !7, metadata !9}
+!26 = metadata !{i32 786473, metadata !28} ; [ DW_TAG_file_type ]
+!27 = metadata !{metadata !"string.h", metadata !"Game"}
+!28 = metadata !{metadata !"bits.c", metadata !"Game"}
diff --git a/test/Transforms/InstCombine/fast-math.ll b/test/Transforms/InstCombine/fast-math.ll
index c97bd28..47f1ec4 100644
--- a/test/Transforms/InstCombine/fast-math.ll
+++ b/test/Transforms/InstCombine/fast-math.ll
@@ -172,6 +172,17 @@ define double @fmul_distribute3(double %f1) {
; CHECK: fmul fast double %t2, 0x10000000000000
}
+; ((X*C1) + C2) * C3 => (X * (C1*C3)) + (C2*C3) (i.e. distribution)
+define float @fmul_distribute4(float %f1) {
+ %t1 = fmul float %f1, 6.0e+3
+ %t2 = fsub float 2.0e+3, %t1
+ %t3 = fmul fast float %t2, 5.0e+3
+ ret float %t3
+; CHECK: @fmul_distribute4
+; CHECK: %1 = fmul fast float %f1, 3.000000e+07
+; CHECK: %t3 = fsub fast float 1.000000e+07, %1
+}
+
; C1/X * C2 => (C1*C2) / X
define float @fmul2(float %f1) {
%t1 = fdiv float 2.0e+3, %f1
@@ -339,3 +350,108 @@ define float @fdiv9(float %x) {
; CHECK: @fdiv9
; CHECK: fmul fast float %x, 5.000000e+00
}
+
+; =========================================================================
+;
+; Testing-cases about factorization
+;
+; =========================================================================
+; x*z + y*z => (x+y) * z
+define float @fact_mul1(float %x, float %y, float %z) {
+ %t1 = fmul fast float %x, %z
+ %t2 = fmul fast float %y, %z
+ %t3 = fadd fast float %t1, %t2
+ ret float %t3
+; CHECK: @fact_mul1
+; CHECK: fmul fast float %1, %z
+}
+
+; z*x + y*z => (x+y) * z
+define float @fact_mul2(float %x, float %y, float %z) {
+ %t1 = fmul fast float %z, %x
+ %t2 = fmul fast float %y, %z
+ %t3 = fsub fast float %t1, %t2
+ ret float %t3
+; CHECK: @fact_mul2
+; CHECK: fmul fast float %1, %z
+}
+
+; z*x - z*y => (x-y) * z
+define float @fact_mul3(float %x, float %y, float %z) {
+ %t2 = fmul fast float %z, %y
+ %t1 = fmul fast float %z, %x
+ %t3 = fsub fast float %t1, %t2
+ ret float %t3
+; CHECK: @fact_mul3
+; CHECK: fmul fast float %1, %z
+}
+
+; x*z - z*y => (x-y) * z
+define float @fact_mul4(float %x, float %y, float %z) {
+ %t1 = fmul fast float %x, %z
+ %t2 = fmul fast float %z, %y
+ %t3 = fsub fast float %t1, %t2
+ ret float %t3
+; CHECK: @fact_mul4
+; CHECK: fmul fast float %1, %z
+}
+
+; x/y + x/z, no xform
+define float @fact_div1(float %x, float %y, float %z) {
+ %t1 = fdiv fast float %x, %y
+ %t2 = fdiv fast float %x, %z
+ %t3 = fadd fast float %t1, %t2
+ ret float %t3
+; CHECK: fact_div1
+; CHECK: fadd fast float %t1, %t2
+}
+
+; x/y + z/x; no xform
+define float @fact_div2(float %x, float %y, float %z) {
+ %t1 = fdiv fast float %x, %y
+ %t2 = fdiv fast float %z, %x
+ %t3 = fadd fast float %t1, %t2
+ ret float %t3
+; CHECK: fact_div2
+; CHECK: fadd fast float %t1, %t2
+}
+
+; y/x + z/x => (y+z)/x
+define float @fact_div3(float %x, float %y, float %z) {
+ %t1 = fdiv fast float %y, %x
+ %t2 = fdiv fast float %z, %x
+ %t3 = fadd fast float %t1, %t2
+ ret float %t3
+; CHECK: fact_div3
+; CHECK: fdiv fast float %1, %x
+}
+
+; y/x - z/x => (y-z)/x
+define float @fact_div4(float %x, float %y, float %z) {
+ %t1 = fdiv fast float %y, %x
+ %t2 = fdiv fast float %z, %x
+ %t3 = fsub fast float %t1, %t2
+ ret float %t3
+; CHECK: fact_div4
+; CHECK: fdiv fast float %1, %x
+}
+
+; y/x - z/x => (y-z)/x is disabled if y-z is denormal.
+define float @fact_div5(float %x) {
+ %t1 = fdiv fast float 0x3810000000000000, %x
+ %t2 = fdiv fast float 0x3800000000000000, %x
+ %t3 = fadd fast float %t1, %t2
+ ret float %t3
+; CHECK: fact_div5
+; CHECK: fdiv fast float 0x3818000000000000, %x
+}
+
+; y/x - z/x => (y-z)/x is disabled if y-z is denormal.
+define float @fact_div6(float %x) {
+ %t1 = fdiv fast float 0x3810000000000000, %x
+ %t2 = fdiv fast float 0x3800000000000000, %x
+ %t3 = fsub fast float %t1, %t2
+ ret float %t3
+; CHECK: fact_div6
+; CHECK: %t3 = fsub fast float %t1, %t2
+}
diff --git a/test/Transforms/InstCombine/objsize.ll b/test/Transforms/InstCombine/objsize.ll
index 31a3cb4..0ead9d1 100644
--- a/test/Transforms/InstCombine/objsize.ll
+++ b/test/Transforms/InstCombine/objsize.ll
@@ -256,3 +256,131 @@ xpto:
return:
ret i32 7
}
+
+declare noalias i8* @valloc(i32) nounwind
+
+; CHECK: @test14
+; CHECK: ret i32 6
+define i32 @test14(i32 %a) nounwind {
+ switch i32 %a, label %sw.default [
+ i32 1, label %sw.bb
+ i32 2, label %sw.bb1
+ ]
+
+sw.bb:
+ %call = tail call noalias i8* @malloc(i32 6) nounwind
+ br label %sw.epilog
+
+sw.bb1:
+ %call2 = tail call noalias i8* @calloc(i32 3, i32 2) nounwind
+ br label %sw.epilog
+
+sw.default:
+ %call3 = tail call noalias i8* @valloc(i32 6) nounwind
+ br label %sw.epilog
+
+sw.epilog:
+ %b.0 = phi i8* [ %call3, %sw.default ], [ %call2, %sw.bb1 ], [ %call, %sw.bb ]
+ %1 = tail call i32 @llvm.objectsize.i32(i8* %b.0, i1 false)
+ ret i32 %1
+}
+
+; CHECK: @test15
+; CHECK: llvm.objectsize
+define i32 @test15(i32 %a) nounwind {
+ switch i32 %a, label %sw.default [
+ i32 1, label %sw.bb
+ i32 2, label %sw.bb1
+ ]
+
+sw.bb:
+ %call = tail call noalias i8* @malloc(i32 3) nounwind
+ br label %sw.epilog
+
+sw.bb1:
+ %call2 = tail call noalias i8* @calloc(i32 2, i32 1) nounwind
+ br label %sw.epilog
+
+sw.default:
+ %call3 = tail call noalias i8* @valloc(i32 3) nounwind
+ br label %sw.epilog
+
+sw.epilog:
+ %b.0 = phi i8* [ %call3, %sw.default ], [ %call2, %sw.bb1 ], [ %call, %sw.bb ]
+ %1 = tail call i32 @llvm.objectsize.i32(i8* %b.0, i1 false)
+ ret i32 %1
+}
+
+; CHECK: @test16
+; CHECK: llvm.objectsize
+define i32 @test16(i8* %a, i32 %n) nounwind {
+ %b = alloca [5 x i8], align 1
+ %c = alloca [5 x i8], align 1
+ switch i32 %n, label %sw.default [
+ i32 1, label %sw.bb
+ i32 2, label %sw.bb1
+ ]
+
+sw.bb:
+ %bp = bitcast [5 x i8]* %b to i8*
+ br label %sw.epilog
+
+sw.bb1:
+ %cp = bitcast [5 x i8]* %c to i8*
+ br label %sw.epilog
+
+sw.default:
+ br label %sw.epilog
+
+sw.epilog:
+ %phi = phi i8* [ %a, %sw.default ], [ %cp, %sw.bb1 ], [ %bp, %sw.bb ]
+ %sz = call i32 @llvm.objectsize.i32(i8* %phi, i1 false)
+ ret i32 %sz
+}
+
+; CHECK: @test17
+; CHECK: ret i32 5
+define i32 @test17(i32 %n) nounwind {
+ %b = alloca [5 x i8], align 1
+ %c = alloca [5 x i8], align 1
+ %bp = bitcast [5 x i8]* %b to i8*
+ switch i32 %n, label %sw.default [
+ i32 1, label %sw.bb
+ i32 2, label %sw.bb1
+ ]
+
+sw.bb:
+ br label %sw.epilog
+
+sw.bb1:
+ %cp = bitcast [5 x i8]* %c to i8*
+ br label %sw.epilog
+
+sw.default:
+ br label %sw.epilog
+
+sw.epilog:
+ %phi = phi i8* [ %bp, %sw.default ], [ %cp, %sw.bb1 ], [ %bp, %sw.bb ]
+ %sz = call i32 @llvm.objectsize.i32(i8* %phi, i1 false)
+ ret i32 %sz
+}
+
+@globalalias = alias internal [60 x i8]* @a
+
+; CHECK: @test18
+; CHECK-NEXT: ret i32 60
+define i32 @test18() {
+ %bc = bitcast [60 x i8]* @globalalias to i8*
+ %1 = call i32 @llvm.objectsize.i32(i8* %bc, i1 false)
+ ret i32 %1
+}
+
+@globalalias2 = alias weak [60 x i8]* @a
+
+; CHECK: @test19
+; CHECK: llvm.objectsize
+define i32 @test19() {
+ %bc = bitcast [60 x i8]* @globalalias2 to i8*
+ %1 = call i32 @llvm.objectsize.i32(i8* %bc, i1 false)
+ ret i32 %1
+}