From 59bec0e3c0c39cf704c6eb7fb2a44e787dbab4a0 Mon Sep 17 00:00:00 2001 From: Reid Kleckner Date: Tue, 28 Jan 2014 02:38:36 +0000 Subject: Update optimization passes to handle inalloca arguments Summary: I searched Transforms/ and Analysis/ for 'ByVal' and updated those call sites to check for inalloca if appropriate. I added tests for any change that would allow an optimization to fire on inalloca. Reviewers: nlewycky Differential Revision: http://llvm-reviews.chandlerc.com/D2449 git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@200281 91177308-0d34-0410-b5e6-96231b3b80d8 --- test/Transforms/ArgumentPromotion/inalloca.ll | 49 ++++++++++++++++++++++ test/Transforms/DeadStoreElimination/simple.ll | 9 ++++ test/Transforms/FunctionAttrs/readattrs.ll | 6 +++ .../InstCombine/call-cast-target-inalloca.ll | 22 ++++++++++ 4 files changed, 86 insertions(+) create mode 100644 test/Transforms/ArgumentPromotion/inalloca.ll create mode 100644 test/Transforms/InstCombine/call-cast-target-inalloca.ll (limited to 'test') diff --git a/test/Transforms/ArgumentPromotion/inalloca.ll b/test/Transforms/ArgumentPromotion/inalloca.ll new file mode 100644 index 0000000000..513a968255 --- /dev/null +++ b/test/Transforms/ArgumentPromotion/inalloca.ll @@ -0,0 +1,49 @@ +; RUN: opt %s -argpromotion -scalarrepl -S | FileCheck %s + +target datalayout = "E-p:64:64:64-a0:0:8-f32:32:32-f64:64:64-i1:8:8-i8:8:8-i16:16:16-i32:32:32-i64:32:64-v64:64:64-v128:128:128" + +%struct.ss = type { i32, i32 } + +; Argpromote + scalarrepl should change this to passing the two integers by value. +define internal i32 @f(%struct.ss* inalloca %s) { +entry: + %f0 = getelementptr %struct.ss* %s, i32 0, i32 0 + %f1 = getelementptr %struct.ss* %s, i32 0, i32 1 + %a = load i32* %f0, align 4 + %b = load i32* %f1, align 4 + %r = add i32 %a, %b + ret i32 %r +} +; CHECK-LABEL: define internal i32 @f +; CHECK-NOT: load +; CHECK: ret + +define i32 @main() { +entry: + %S = alloca %struct.ss + %f0 = getelementptr %struct.ss* %S, i32 0, i32 0 + %f1 = getelementptr %struct.ss* %S, i32 0, i32 1 + store i32 1, i32* %f0, align 4 + store i32 2, i32* %f1, align 4 + %r = call i32 @f(%struct.ss* inalloca %S) + ret i32 %r +} +; CHECK-LABEL: define i32 @main +; CHECK-NOT: load +; CHECK: ret + +; Argpromote can't promote %a because of the icmp use. +define internal i1 @g(%struct.ss* %a, %struct.ss* inalloca %b) nounwind { +; CHECK: define internal i1 @g(%struct.ss* %a, %struct.ss* inalloca %b) +entry: + %c = icmp eq %struct.ss* %a, %b + ret i1 %c +} + +define i32 @test() { +entry: + %S = alloca %struct.ss + %c = call i1 @g(%struct.ss* %S, %struct.ss* inalloca %S) +; CHECK: call i1 @g(%struct.ss* %S, %struct.ss* inalloca %S) + ret i32 0 +} diff --git a/test/Transforms/DeadStoreElimination/simple.ll b/test/Transforms/DeadStoreElimination/simple.ll index ec98466d33..cdfe2268ef 100644 --- a/test/Transforms/DeadStoreElimination/simple.ll +++ b/test/Transforms/DeadStoreElimination/simple.ll @@ -105,6 +105,15 @@ define void @test9(%struct.x* byval %a) nounwind { ; CHECK-NEXT: ret void } +; Test for inalloca handling. +define void @test9_2(%struct.x* inalloca %a) nounwind { + %tmp2 = getelementptr %struct.x* %a, i32 0, i32 0 + store i32 1, i32* %tmp2, align 4 + ret void +; CHECK-LABEL: @test9_2( +; CHECK-NEXT: ret void +} + ; va_arg has fuzzy dependence, the store shouldn't be zapped. define double @test10(i8* %X) { %X_addr = alloca i8* diff --git a/test/Transforms/FunctionAttrs/readattrs.ll b/test/Transforms/FunctionAttrs/readattrs.ll index 0842f566d1..7ae38bbb10 100644 --- a/test/Transforms/FunctionAttrs/readattrs.ll +++ b/test/Transforms/FunctionAttrs/readattrs.ll @@ -45,3 +45,9 @@ define void @test6_2(i8** %p, i8* %q) { call void @test6_1() ret void } + +; CHECK: define void @test7_1(i32* inalloca nocapture %a) +; inalloca parameters are always considered written +define void @test7_1(i32* inalloca %a) { + ret void +} diff --git a/test/Transforms/InstCombine/call-cast-target-inalloca.ll b/test/Transforms/InstCombine/call-cast-target-inalloca.ll new file mode 100644 index 0000000000..baf97e0ce9 --- /dev/null +++ b/test/Transforms/InstCombine/call-cast-target-inalloca.ll @@ -0,0 +1,22 @@ +; RUN: opt < %s -instcombine -S | FileCheck %s + +target datalayout = "e-p:32:32" +target triple = "i686-pc-linux-gnu" + +declare void @takes_i32(i32) +declare void @takes_i32_inalloca(i32* inalloca) + +define void @f() { +; CHECK-LABEL: define void @f() + %args = alloca i32 + call void bitcast (void (i32)* @takes_i32 to void (i32*)*)(i32* inalloca %args) +; CHECK: call void bitcast + ret void +} + +define void @g() { +; CHECK-LABEL: define void @g() + call void bitcast (void (i32*)* @takes_i32_inalloca to void (i32)*)(i32 0) +; CHECK: call void bitcast + ret void +} -- cgit v1.2.3