1; NOTE: Assertions have been autogenerated by utils/update_llc_test_checks.py 2; RUN: llc < %s -disable-wasm-fallthrough-return-opt -wasm-disable-explicit-locals -wasm-keep-registers | FileCheck %s 3 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: # %entry 15; CHECK-NEXT: i32.const $push0=, 1 16; CHECK-NEXT: call $push1=, _Znwm, $pop0 17; CHECK-NEXT: call $push2=, _ZN5AppleC1Ev, $pop1 18; CHECK-NEXT: return $pop2 19entry: 20 %call = tail call noalias ptr @_Znwm(i32 1) 21 %call1 = tail call ptr @_ZN5AppleC1Ev(ptr %call) 22 ret ptr %call 23} 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: # %entry 30; CHECK-NEXT: call $push0=, memcpy, $0, $1, $2 31; CHECK-NEXT: return $pop0 32entry: 33 %call = tail call ptr @memcpy(ptr %p, ptr %s, i32 %n) 34 ret ptr %p 35} 36 37; Test that the optimization isn't performed on constant arguments. 38 39@global = external global i32 40@addr = global ptr @global 41define 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=, global 46; CHECK-NEXT: call $drop=, returns_arg, $pop0 47; CHECK-NEXT: return 48 %call = call ptr @returns_arg(ptr @global) 49 ret void 50} 51declare ptr @returns_arg(ptr returned) 52 53; Test that the optimization isn't performed on arguments without the 54; "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, $2 63; CHECK-NEXT: call do_something_with_i32, $1 64; CHECK-NEXT: call do_something_with_double, $2 65; CHECK-NEXT: return 66 %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 void 70} 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, $1 79; CHECK-NEXT: return $pop0 80 %call = call i32 @do_something_else(i32 %a, i32 %b) 81 ret i32 %b 82} 83