aboutsummaryrefslogtreecommitdiff
path: root/test/Transforms/Inline
diff options
context:
space:
mode:
Diffstat (limited to 'test/Transforms/Inline')
-rw-r--r--test/Transforms/Inline/AArch64/binop.ll291
-rw-r--r--test/Transforms/Inline/ARM/inline-fp.ll113
-rw-r--r--test/Transforms/Inline/inline-fp.ll137
-rw-r--r--test/Transforms/Inline/redundant-loads.ll18
4 files changed, 422 insertions, 137 deletions
diff --git a/test/Transforms/Inline/AArch64/binop.ll b/test/Transforms/Inline/AArch64/binop.ll
new file mode 100644
index 000000000000..051528991e46
--- /dev/null
+++ b/test/Transforms/Inline/AArch64/binop.ll
@@ -0,0 +1,291 @@
+; RUN: opt -inline -mtriple=aarch64--linux-gnu -S -o - < %s -inline-threshold=0 | FileCheck %s
+
+target datalayout = "e-m:e-i8:8:32-i16:16:32-i64:64-i128:128-n32:64-S128"
+target triple = "aarch64--linux-gnu"
+
+declare void @pad()
+@glbl = external global i32
+
+define i32 @outer_add1(i32 %a) {
+; CHECK-LABEL: @outer_add1(
+; CHECK-NOT: call i32 @add
+ %C = call i32 @add(i32 %a, i32 0)
+ ret i32 %C
+}
+
+define i32 @outer_add2(i32 %a) {
+; CHECK-LABEL: @outer_add2(
+; CHECK-NOT: call i32 @add
+ %C = call i32 @add(i32 0, i32 %a)
+ ret i32 %C
+}
+
+define i32 @add(i32 %a, i32 %b) {
+ %add = add i32 %a, %b
+ call void @pad()
+ store i32 0, i32* @glbl
+ ret i32 %add
+}
+
+
+
+define i32 @outer_sub1(i32 %a) {
+; CHECK-LABEL: @outer_sub1(
+; CHECK-NOT: call i32 @sub1
+ %C = call i32 @sub1(i32 %a, i32 0)
+ ret i32 %C
+}
+
+define i32 @sub1(i32 %a, i32 %b) {
+ %sub = sub i32 %a, %b
+ call void @pad()
+ store i32 0, i32* @glbl
+ ret i32 %sub
+}
+
+
+define i32 @outer_sub2(i32 %a) {
+; CHECK-LABEL: @outer_sub2(
+; CHECK-NOT: call i32 @sub2
+ %C = call i32 @sub2(i32 %a)
+ ret i32 %C
+}
+
+define i32 @sub2(i32 %a) {
+ %sub = sub i32 %a, %a
+ call void @pad()
+ ret i32 %sub
+}
+
+
+
+define i32 @outer_mul1(i32 %a) {
+; CHECK-LABEL: @outer_mul1(
+; CHECK-NOT: call i32 @mul
+ %C = call i32 @mul(i32 %a, i32 0)
+ ret i32 %C
+}
+
+define i32 @outer_mul2(i32 %a) {
+; CHECK-LABEL: @outer_mul2(
+; CHECK-NOT: call i32 @mul
+ %C = call i32 @mul(i32 %a, i32 1)
+ ret i32 %C
+}
+
+define i32 @mul(i32 %a, i32 %b) {
+ %mul = mul i32 %a, %b
+ call void @pad()
+ store i32 0, i32* @glbl
+ ret i32 %mul
+}
+
+
+
+define i32 @outer_div1(i32 %a) {
+; CHECK-LABEL: @outer_div1(
+; CHECK-NOT: call i32 @div1
+ %C = call i32 @div1(i32 0, i32 %a)
+ ret i32 %C
+}
+
+define i32 @outer_div2(i32 %a) {
+; CHECK-LABEL: @outer_div2(
+; CHECK-NOT: call i32 @div1
+ %C = call i32 @div1(i32 %a, i32 1)
+ ret i32 %C
+}
+
+define i32 @div1(i32 %a, i32 %b) {
+ %div = sdiv i32 %a, %b
+ call void @pad()
+ store i32 0, i32* @glbl
+ ret i32 %div
+}
+
+
+define i32 @outer_div3(i32 %a) {
+; CHECK-LABEL: @outer_div3(
+; CHECK-NOT: call i32 @div
+ %C = call i32 @div2(i32 %a)
+ ret i32 %C
+}
+
+define i32 @div2(i32 %a) {
+ %div = sdiv i32 %a, %a
+ call void @pad()
+ ret i32 %div
+}
+
+
+
+define i32 @outer_rem1(i32 %a) {
+; CHECK-LABEL: @outer_rem1(
+; CHECK-NOT: call i32 @rem
+ %C = call i32 @rem1(i32 0, i32 %a)
+ ret i32 %C
+}
+
+define i32 @outer_rem2(i32 %a) {
+; CHECK-LABEL: @outer_rem2(
+; CHECK-NOT: call i32 @rem
+ %C = call i32 @rem1(i32 %a, i32 1)
+ ret i32 %C
+}
+
+define i32 @rem1(i32 %a, i32 %b) {
+ %rem = urem i32 %a, %b
+ call void @pad()
+ store i32 0, i32* @glbl
+ ret i32 %rem
+}
+
+
+define i32 @outer_rem3(i32 %a) {
+; CHECK-LABEL: @outer_rem3(
+; CHECK-NOT: call i32 @rem
+ %C = call i32 @rem2(i32 %a)
+ ret i32 %C
+}
+
+define i32 @rem2(i32 %a) {
+ %rem = urem i32 %a, %a
+ call void @pad()
+ ret i32 %rem
+}
+
+
+
+define i32 @outer_shl1(i32 %a) {
+; CHECK-LABEL: @outer_shl1(
+; CHECK-NOT: call i32 @shl
+ %C = call i32 @shl(i32 %a, i32 0)
+ ret i32 %C
+}
+
+define i32 @shl(i32 %a, i32 %b) {
+ %shl = shl i32 %a, %b
+ call void @pad()
+ store i32 0, i32* @glbl
+ ret i32 %shl
+}
+
+
+
+define i32 @outer_shr1(i32 %a) {
+; CHECK-LABEL: @outer_shr1(
+; CHECK-NOT: call i32 @shr
+ %C = call i32 @shr(i32 %a, i32 0)
+ ret i32 %C
+}
+
+define i32 @shr(i32 %a, i32 %b) {
+ %shr = ashr i32 %a, %b
+ call void @pad()
+ store i32 0, i32* @glbl
+ ret i32 %shr
+}
+
+
+
+define i1 @outer_and1(i1 %a) {
+; check-label: @outer_and1(
+; check-not: call i1 @and1
+ %c = call i1 @and1(i1 %a, i1 false)
+ ret i1 %c
+}
+
+define i1 @outer_and2(i1 %a) {
+; check-label: @outer_and2(
+; check-not: call i1 @and1
+ %c = call i1 @and1(i1 %a, i1 true)
+ ret i1 %c
+}
+
+define i1 @and1(i1 %a, i1 %b) {
+ %and = and i1 %a, %b
+ call void @pad()
+ store i32 0, i32* @glbl
+ ret i1 %and
+}
+
+
+define i1 @outer_and3(i1 %a) {
+; check-label: @outer_and3(
+; check-not: call i1 @and2
+ %c = call i1 @and2(i1 %a)
+ ret i1 %c
+}
+
+define i1 @and2(i1 %a) {
+ %and = and i1 %a, %a
+ call void @pad()
+ ret i1 %and
+}
+
+
+
+define i1 @outer_or1(i1 %a) {
+; check-label: @outer_or1(
+; check-not: call i1 @or1
+ %c = call i1 @or1(i1 %a, i1 false)
+ ret i1 %c
+}
+
+define i1 @outer_or2(i1 %a) {
+; check-label: @outer_or2(
+; check-not: call i1 @or1
+ %c = call i1 @or1(i1 %a, i1 true)
+ ret i1 %c
+}
+
+define i1 @or1(i1 %a, i1 %b) {
+ %or = or i1 %a, %b
+ call void @pad()
+ store i32 0, i32* @glbl
+ ret i1 %or
+}
+
+
+define i1 @outer_or3(i1 %a) {
+; check-label: @outer_or3(
+; check-not: call i1 @or2
+ %c = call i1 @or2(i1 %a)
+ ret i1 %c
+}
+
+define i1 @or2(i1 %a) {
+ %or = or i1 %a, %a
+ call void @pad()
+ ret i1 %or
+}
+
+
+
+define i1 @outer_xor1(i1 %a) {
+; check-label: @outer_xor1(
+; check-not: call i1 @xor
+ %c = call i1 @xor1(i1 %a, i1 false)
+ ret i1 %c
+}
+
+define i1 @xor1(i1 %a, i1 %b) {
+ %xor = xor i1 %a, %b
+ call void @pad()
+ store i32 0, i32* @glbl
+ ret i1 %xor
+}
+
+
+define i1 @outer_xor3(i1 %a) {
+; check-label: @outer_xor3(
+; check-not: call i1 @xor
+ %c = call i1 @xor2(i1 %a)
+ ret i1 %c
+}
+
+define i1 @xor2(i1 %a) {
+ %xor = xor i1 %a, %a
+ call void @pad()
+ ret i1 %xor
+}
diff --git a/test/Transforms/Inline/ARM/inline-fp.ll b/test/Transforms/Inline/ARM/inline-fp.ll
new file mode 100644
index 000000000000..b4e76dfc7d2d
--- /dev/null
+++ b/test/Transforms/Inline/ARM/inline-fp.ll
@@ -0,0 +1,113 @@
+; RUN: opt -S -inline -mtriple=arm-eabi -pass-remarks=.* -pass-remarks-missed=.* < %s 2>&1 | FileCheck %s -check-prefix=NOFP
+; RUN: opt -S -inline -mtriple=arm-eabi -mattr=+vfp2 -pass-remarks=.* -pass-remarks-missed=.* < %s 2>&1 | FileCheck %s -check-prefix=FULLFP
+; RUN: opt -S -inline -mtriple=arm-eabi -mattr=+vfp2,+fp-only-sp -pass-remarks=.* -pass-remarks-missed=.* < %s 2>&1 | FileCheck %s -check-prefix=SINGLEFP
+; Make sure that soft float implementations are calculated as being more expensive
+; to the inliner.
+
+; NOFP-DAG: single not inlined into test_single because too costly to inline (cost=125, threshold=75)
+; NOFP-DAG: single not inlined into test_single because too costly to inline (cost=125, threshold=75)
+; NOFP-DAG: single_cheap inlined into test_single_cheap with cost=-15 (threshold=75)
+; NOFP-DAG: single_cheap inlined into test_single_cheap with cost=-15015 (threshold=75)
+; NOFP-DAG: double not inlined into test_double because too costly to inline (cost=125, threshold=75)
+; NOFP-DAG: double not inlined into test_double because too costly to inline (cost=125, threshold=75)
+; NOFP-DAG: single_force_soft not inlined into test_single_force_soft because too costly to inline (cost=125, threshold=75)
+; NOFP-DAG: single_force_soft not inlined into test_single_force_soft because too costly to inline (cost=125, threshold=75)
+
+; FULLFP-DAG: single inlined into test_single with cost=0 (threshold=75)
+; FULLFP-DAG: single inlined into test_single with cost=-15000 (threshold=75)
+; FULLFP-DAG: single_cheap inlined into test_single_cheap with cost=-15 (threshold=75)
+; FULLFP-DAG: single_cheap inlined into test_single_cheap with cost=-15015 (threshold=75)
+; FULLFP-DAG: double inlined into test_double with cost=0 (threshold=75)
+; FULLFP-DAG: double inlined into test_double with cost=-15000 (threshold=75)
+; FULLFP-DAG: single_force_soft not inlined into test_single_force_soft because too costly to inline (cost=125, threshold=75)
+; FULLFP-DAG: single_force_soft not inlined into test_single_force_soft because too costly to inline (cost=125, threshold=75)
+
+; SINGLEFP-DAG: single inlined into test_single with cost=0 (threshold=75)
+; SINGLEFP-DAG: single inlined into test_single with cost=-15000 (threshold=75)
+; SINGLEFP-DAG: single_cheap inlined into test_single_cheap with cost=-15 (threshold=75)
+; SINGLEFP-DAG: single_cheap inlined into test_single_cheap with cost=-15015 (threshold=75)
+; SINGLEFP-DAG: double not inlined into test_double because too costly to inline (cost=125, threshold=75)
+; SINGLEFP-DAG: double not inlined into test_double because too costly to inline (cost=125, threshold=75)
+; SINGLEFP-DAG: single_force_soft not inlined into test_single_force_soft because too costly to inline (cost=125, threshold=75)
+; SINGLEFP-DAG: single_force_soft not inlined into test_single_force_soft because too costly to inline (cost=125, threshold=75)
+
+define i32 @test_single(i32 %a, i8 %b, i32 %c, i8 %d) #0 {
+ %call = call float @single(i32 %a, i8 zeroext %b)
+ %call2 = call float @single(i32 %c, i8 zeroext %d)
+ ret i32 0
+}
+
+define i32 @test_single_cheap(i32 %a, i8 %b, i32 %c, i8 %d) #0 {
+ %call = call float @single_cheap(i32 %a, i8 zeroext %b)
+ %call2 = call float @single_cheap(i32 %c, i8 zeroext %d)
+ ret i32 0
+}
+
+define i32 @test_double(i32 %a, i8 %b, i32 %c, i8 %d) #0 {
+ %call = call double @double(i32 %a, i8 zeroext %b)
+ %call2 = call double @double(i32 %c, i8 zeroext %d)
+ ret i32 0
+}
+
+define i32 @test_single_force_soft(i32 %a, i8 %b, i32 %c, i8 %d) #1 {
+ %call = call float @single_force_soft(i32 %a, i8 zeroext %b) #1
+ %call2 = call float @single_force_soft(i32 %c, i8 zeroext %d) #1
+ ret i32 0
+}
+
+define internal float @single(i32 %response, i8 zeroext %value1) #0 {
+entry:
+ %conv = zext i8 %value1 to i32
+ %sub = add nsw i32 %conv, -1
+ %conv1 = sitofp i32 %sub to float
+ %0 = tail call float @llvm.pow.f32(float 0x3FF028F5C0000000, float %conv1)
+ %mul = fmul float %0, 2.620000e+03
+ %conv2 = sitofp i32 %response to float
+ %sub3 = fsub float %conv2, %mul
+ %div = fdiv float %sub3, %mul
+ ret float %div
+}
+
+define internal float @single_cheap(i32 %response, i8 zeroext %value1) #0 {
+entry:
+ %conv = zext i8 %value1 to i32
+ %sub = add nsw i32 %conv, -1
+ %conv1 = bitcast i32 %sub to float
+ %conv2 = bitcast i32 %response to float
+ %0 = tail call float @llvm.pow.f32(float %conv2, float %conv1)
+ %1 = tail call float @llvm.pow.f32(float %0, float %0)
+ %2 = tail call float @llvm.pow.f32(float %1, float %1)
+ ret float %2
+}
+
+define internal double @double(i32 %response, i8 zeroext %value1) #0 {
+entry:
+ %conv = zext i8 %value1 to i32
+ %sub = add nsw i32 %conv, -1
+ %conv1 = sitofp i32 %sub to double
+ %0 = tail call double @llvm.pow.f64(double 0x3FF028F5C0000000, double %conv1)
+ %mul = fmul double %0, 2.620000e+03
+ %conv2 = sitofp i32 %response to double
+ %sub3 = fsub double %conv2, %mul
+ %div = fdiv double %sub3, %mul
+ ret double %div
+}
+
+define internal float @single_force_soft(i32 %response, i8 zeroext %value1) #1 {
+entry:
+ %conv = zext i8 %value1 to i32
+ %sub = add nsw i32 %conv, -1
+ %conv1 = sitofp i32 %sub to float
+ %0 = tail call float @llvm.pow.f32(float 0x3FF028F5C0000000, float %conv1)
+ %mul = fmul float %0, 2.620000e+03
+ %conv2 = sitofp i32 %response to float
+ %sub3 = fsub float %conv2, %mul
+ %div = fdiv float %sub3, %mul
+ ret float %div
+}
+
+declare float @llvm.pow.f32(float, float) optsize minsize
+declare double @llvm.pow.f64(double, double) optsize minsize
+
+attributes #0 = { optsize }
+attributes #1 = { optsize "use-soft-float"="true" "target-features"="+soft-float" }
diff --git a/test/Transforms/Inline/inline-fp.ll b/test/Transforms/Inline/inline-fp.ll
deleted file mode 100644
index dd5972fe1b8a..000000000000
--- a/test/Transforms/Inline/inline-fp.ll
+++ /dev/null
@@ -1,137 +0,0 @@
-; RUN: opt -S -inline < %s | FileCheck %s
-; RUN: opt -S -passes='cgscc(inline)' < %s | FileCheck %s
-; Make sure that soft float implementations are calculated as being more expensive
-; to the inliner.
-
-define i32 @test_nofp() #0 {
-; f_nofp() has the "use-soft-float" attribute, so it should never get inlined.
-; CHECK-LABEL: test_nofp
-; CHECK: call float @f_nofp
-entry:
- %responseX = alloca i32, align 4
- %responseY = alloca i32, align 4
- %responseZ = alloca i32, align 4
- %valueX = alloca i8, align 1
- %valueY = alloca i8, align 1
- %valueZ = alloca i8, align 1
-
- call void @getX(i32* %responseX, i8* %valueX)
- call void @getY(i32* %responseY, i8* %valueY)
- call void @getZ(i32* %responseZ, i8* %valueZ)
-
- %0 = load i32, i32* %responseX
- %1 = load i8, i8* %valueX
- %call = call float @f_nofp(i32 %0, i8 zeroext %1)
- %2 = load i32, i32* %responseZ
- %3 = load i8, i8* %valueZ
- %call2 = call float @f_nofp(i32 %2, i8 zeroext %3)
- %call3 = call float @fabsf(float %call)
- %cmp = fcmp ogt float %call3, 0x3FC1EB8520000000
- br i1 %cmp, label %if.end12, label %if.else
-
-if.else: ; preds = %entry
- %4 = load i32, i32* %responseY
- %5 = load i8, i8* %valueY
- %call1 = call float @f_nofp(i32 %4, i8 zeroext %5)
- %call4 = call float @fabsf(float %call1)
- %cmp5 = fcmp ogt float %call4, 0x3FC1EB8520000000
- br i1 %cmp5, label %if.end12, label %if.else7
-
-if.else7: ; preds = %if.else
- %call8 = call float @fabsf(float %call2)
- %cmp9 = fcmp ogt float %call8, 0x3FC1EB8520000000
- br i1 %cmp9, label %if.then10, label %if.end12
-
-if.then10: ; preds = %if.else7
- br label %if.end12
-
-if.end12: ; preds = %if.else, %entry, %if.then10, %if.else7
- %success.0 = phi i32 [ 0, %if.then10 ], [ 1, %if.else7 ], [ 0, %entry ], [ 0, %if.else ]
- ret i32 %success.0
-}
-
-define i32 @test_hasfp() #0 {
-; f_hasfp() does not have the "use-soft-float" attribute, so it should get inlined.
-; CHECK-LABEL: test_hasfp
-; CHECK-NOT: call float @f_hasfp
-entry:
- %responseX = alloca i32, align 4
- %responseY = alloca i32, align 4
- %responseZ = alloca i32, align 4
- %valueX = alloca i8, align 1
- %valueY = alloca i8, align 1
- %valueZ = alloca i8, align 1
-
- call void @getX(i32* %responseX, i8* %valueX)
- call void @getY(i32* %responseY, i8* %valueY)
- call void @getZ(i32* %responseZ, i8* %valueZ)
-
- %0 = load i32, i32* %responseX
- %1 = load i8, i8* %valueX
- %call = call float @f_hasfp(i32 %0, i8 zeroext %1)
- %2 = load i32, i32* %responseZ
- %3 = load i8, i8* %valueZ
- %call2 = call float @f_hasfp(i32 %2, i8 zeroext %3)
- %call3 = call float @fabsf(float %call)
- %cmp = fcmp ogt float %call3, 0x3FC1EB8520000000
- br i1 %cmp, label %if.end12, label %if.else
-
-if.else: ; preds = %entry
- %4 = load i32, i32* %responseY
- %5 = load i8, i8* %valueY
- %call1 = call float @f_hasfp(i32 %4, i8 zeroext %5)
- %call4 = call float @fabsf(float %call1)
- %cmp5 = fcmp ogt float %call4, 0x3FC1EB8520000000
- br i1 %cmp5, label %if.end12, label %if.else7
-
-if.else7: ; preds = %if.else
- %call8 = call float @fabsf(float %call2)
- %cmp9 = fcmp ogt float %call8, 0x3FC1EB8520000000
- br i1 %cmp9, label %if.then10, label %if.end12
-
-if.then10: ; preds = %if.else7
- br label %if.end12
-
-if.end12: ; preds = %if.else, %entry, %if.then10, %if.else7
- %success.0 = phi i32 [ 0, %if.then10 ], [ 1, %if.else7 ], [ 0, %entry ], [ 0, %if.else ]
- ret i32 %success.0
-}
-
-declare void @getX(i32*, i8*) #0
-
-declare void @getY(i32*, i8*) #0
-
-declare void @getZ(i32*, i8*) #0
-
-define internal float @f_hasfp(i32 %response, i8 zeroext %value1) #0 {
-entry:
- %conv = zext i8 %value1 to i32
- %sub = add nsw i32 %conv, -1
- %conv1 = sitofp i32 %sub to float
- %0 = tail call float @llvm.pow.f32(float 0x3FF028F5C0000000, float %conv1)
- %mul = fmul float %0, 2.620000e+03
- %conv2 = sitofp i32 %response to float
- %sub3 = fsub float %conv2, %mul
- %div = fdiv float %sub3, %mul
- ret float %div
-}
-
-define internal float @f_nofp(i32 %response, i8 zeroext %value1) #1 {
-entry:
- %conv = zext i8 %value1 to i32
- %sub = add nsw i32 %conv, -1
- %conv1 = sitofp i32 %sub to float
- %0 = tail call float @llvm.pow.f32(float 0x3FF028F5C0000000, float %conv1)
- %mul = fmul float %0, 2.620000e+03
- %conv2 = sitofp i32 %response to float
- %sub3 = fsub float %conv2, %mul
- %div = fdiv float %sub3, %mul
- ret float %div
-}
-
-declare float @fabsf(float) optsize minsize
-
-declare float @llvm.pow.f32(float, float) optsize minsize
-
-attributes #0 = { optsize }
-attributes #1 = { optsize "use-soft-float"="true" }
diff --git a/test/Transforms/Inline/redundant-loads.ll b/test/Transforms/Inline/redundant-loads.ll
index 6b89f1db484b..176f605fc73b 100644
--- a/test/Transforms/Inline/redundant-loads.ll
+++ b/test/Transforms/Inline/redundant-loads.ll
@@ -184,3 +184,21 @@ define void @inner9(i32* %a, void ()* %f) {
call void @pad()
ret void
}
+
+
+define void @outer10(i32* %a) {
+; CHECK-LABEL: @outer10(
+; CHECK: call void @inner10
+ %b = alloca i32
+ call void @inner10(i32* %a, i32* %b)
+ ret void
+}
+
+define void @inner10(i32* %a, i32* %b) {
+ %1 = load i32, i32* %a
+ store i32 %1, i32 * %b
+ %2 = load volatile i32, i32* %a ; volatile load should be kept.
+ call void @pad()
+ %3 = load volatile i32, i32* %a ; Same as the above.
+ ret void
+}