107 lines · plain
1; NOTE: Assertions have been autogenerated by utils/update_llc_test_checks.py2; RUN: llc < %s -disable-wasm-fallthrough-return-opt -wasm-disable-explicit-locals -wasm-keep-registers | FileCheck %s3 4; Test that the "returned" attribute is optimized effectively.5 6target triple = "wasm32-unknown-unknown"7 8%class.Apple = type { i8 }9declare noalias ptr @_Znwm(i32)10declare ptr @_ZN5AppleC1Ev(ptr returned)11define ptr @_Z3foov() {12; CHECK-LABEL: _Z3foov:13; CHECK: .functype _Z3foov () -> (i32)14; CHECK-NEXT: # %bb.0: # %entry15; CHECK-NEXT: i32.const $push0=, 116; CHECK-NEXT: call $push1=, _Znwm, $pop017; CHECK-NEXT: call $push2=, _ZN5AppleC1Ev, $pop118; CHECK-NEXT: return $pop219entry:20 %call = tail call noalias ptr @_Znwm(i32 1)21 %call1 = tail call ptr @_ZN5AppleC1Ev(ptr %call)22 ret ptr %call23}24 25declare ptr @memcpy(ptr returned, ptr, i32)26define ptr @_Z3barPvS_l(ptr %p, ptr %s, i32 %n) {27; CHECK-LABEL: _Z3barPvS_l:28; CHECK: .functype _Z3barPvS_l (i32, i32, i32) -> (i32)29; CHECK-NEXT: # %bb.0: # %entry30; CHECK-NEXT: call $push0=, memcpy, $0, $1, $231; CHECK-NEXT: return $pop032entry:33 %call = tail call ptr @memcpy(ptr %p, ptr %s, i32 %n)34 ret ptr %p35}36 37; Test that the optimization isn't performed on constant arguments.38 39@global = external global i3240@addr = global ptr @global41define void @test_constant_arg() {42; CHECK-LABEL: test_constant_arg:43; CHECK: .functype test_constant_arg () -> ()44; CHECK-NEXT: # %bb.0:45; CHECK-NEXT: i32.const $push0=, global46; CHECK-NEXT: call $drop=, returns_arg, $pop047; CHECK-NEXT: return48 %call = call ptr @returns_arg(ptr @global)49 ret void50}51declare ptr @returns_arg(ptr returned)52 53; Test that the optimization isn't performed on arguments without the54; "returned" attribute.55declare i32 @do_something(i32 returned, i32, double)56declare void @do_something_with_i32(i32)57declare void @do_something_with_double(double)58define void @test_other_skipped(i32 %a, i32 %b, double %c) {59; CHECK-LABEL: test_other_skipped:60; CHECK: .functype test_other_skipped (i32, i32, f64) -> ()61; CHECK-NEXT: # %bb.0:62; CHECK-NEXT: call $drop=, do_something, $0, $1, $263; CHECK-NEXT: call do_something_with_i32, $164; CHECK-NEXT: call do_something_with_double, $265; CHECK-NEXT: return66 %call = call i32 @do_something(i32 %a, i32 %b, double %c)67 call void @do_something_with_i32(i32 %b)68 call void @do_something_with_double(double %c)69 ret void70}71 72; Test that the optimization is performed on arguments other than the first.73declare i32 @do_something_else(i32, i32 returned)74define i32 @test_second_arg(i32 %a, i32 %b) {75; CHECK-LABEL: test_second_arg:76; CHECK: .functype test_second_arg (i32, i32) -> (i32)77; CHECK-NEXT: # %bb.0:78; CHECK-NEXT: call $push0=, do_something_else, $0, $179; CHECK-NEXT: return $pop080 %call = call i32 @do_something_else(i32 %a, i32 %b)81 ret i32 %b82}83 84define void @test() {85; CHECK-LABEL: test:86; CHECK: .functype test () -> ()87; CHECK-NEXT: # %bb.0: # %entry88; CHECK-NEXT: global.get $push0=, __stack_pointer89; CHECK-NEXT: i32.const $push1=, 1690; CHECK-NEXT: i32.sub $push7=, $pop0, $pop191; CHECK-NEXT: local.tee $push6=, $0=, $pop792; CHECK-NEXT: global.set __stack_pointer, $pop693; CHECK-NEXT: i32.const $push4=, 1294; CHECK-NEXT: i32.add $push5=, $0, $pop495; CHECK-NEXT: call $drop=, returns_arg, $pop596; CHECK-NEXT: i32.const $push2=, 1697; CHECK-NEXT: i32.add $push3=, $0, $pop298; CHECK-NEXT: global.set __stack_pointer, $pop399; CHECK-NEXT: return100entry:101 %a = alloca i32102 call void @llvm.lifetime.start.p0(ptr %a)103 %ret = call ptr @returns_arg(ptr %a)104 call void @llvm.lifetime.end.p0(ptr %a)105 ret void106}107