1; NOTE: Assertions have been autogenerated by utils/update_llc_test_checks.py 2; RUN: llc < %s -asm-verbose=false -wasm-disable-explicit-locals -wasm-keep-registers | FileCheck %s 3 4target datalayout = "e-m:e-p:32:32-i64:64-n32:64-S128" 5target triple = "wasm32-unknown-unknown" 6 7; Return multiple values, some of which will be legalized into multiple values. 8declare { i64, i128, i192, i128, i64 } @return_multi_multi() 9 10; Test returning a single value from @return_multi_multi. 11 12define i64 @test0() { 13; CHECK-LABEL: test0 14; CHECK: call return_multi_multi 15; CHECK: i64.load $0=, 8($1) 16; CHECK: local.copy $push8=, $0 17 %t0 = call { i64, i128, i192, i128, i64 } @return_multi_multi() 18 %t1 = extractvalue { i64, i128, i192, i128, i64 } %t0, 0 19 ret i64 %t1 20} 21 22define i128 @test1() { 23; CHECK-LABEL: test1 24; CHECK: call return_multi_multi 25; CHECK: i64.load $1=, 16($2) 26; CHECK: i32.const $push0=, 24 27; CHECK: i32.add $push1=, $2, $pop0 28; CHECK: i64.load $push2=, 0($pop1) 29; CHECK: i64.store 8($0), $pop2 30; CHECK: i64.store 0($0), $1 31 %t0 = call { i64, i128, i192, i128, i64 } @return_multi_multi() 32 %t1 = extractvalue { i64, i128, i192, i128, i64 } %t0, 1 33 ret i128 %t1 34} 35 36define i192 @test2() { 37; CHECK-LABEL: test2 38; CHECK: call return_multi_multi 39; CHECK: i32.const $push0=, 40 40; CHECK: i32.add $push1=, $3, $pop0 41; CHECK: i64.load $1=, 0($pop1) 42; CHECK: i64.load $2=, 32($3) 43; CHECK: i32.const $push2=, 48 44; CHECK: i32.add $push3=, $3, $pop2 45; CHECK: i64.load $push4=, 0($pop3) 46; CHECK: i64.store 16($0), $pop4 47; CHECK: i64.store 0($0), $2 48; CHECK: i64.store 8($0), $1 49 %t0 = call { i64, i128, i192, i128, i64 } @return_multi_multi() 50 %t1 = extractvalue { i64, i128, i192, i128, i64 } %t0, 2 51 ret i192 %t1 52} 53 54define i128 @test3() { 55; CHECK-LABEL: test3 56; CHECK: call return_multi_multi 57; CHECK: i64.load $1=, 56($2) 58; CHECK: i32.const $push0=, 64 59; CHECK: i32.add $push1=, $2, $pop0 60; CHECK: i64.load $push2=, 0($pop1) 61; CHECK: i64.store 8($0), $pop2 62; CHECK: i64.store 0($0), $1 63 %t0 = call { i64, i128, i192, i128, i64 } @return_multi_multi() 64 %t1 = extractvalue { i64, i128, i192, i128, i64 } %t0, 3 65 ret i128 %t1 66} 67 68define i64 @test4() { 69; CHECK-LABEL: test4 70; CHECK: call return_multi_multi 71; CHECK: i64.load $0=, 72($1) 72; CHECK: local.copy $push8=, $0 73 %t0 = call { i64, i128, i192, i128, i64 } @return_multi_multi() 74 %t1 = extractvalue { i64, i128, i192, i128, i64 } %t0, 4 75 ret i64 %t1 76} 77 78; Test returning multiple values from @return_multi_multi. 79 80define { i64, i128 } @test5() { 81; CHECK-LABEL: test5 82; CHECK: call return_multi_multi 83; CHECK: i32.const $push10=, 8 84; CHECK: i32.add $push11=, $3, $pop10 85; CHECK: i32.const $push0=, 16 86; CHECK: i32.add $push1=, $pop11, $pop0 87; CHECK: i64.load $1=, 0($pop1) 88; CHECK: i64.load $2=, 8($3) 89; CHECK: i64.load $push2=, 16($3) 90; CHECK: i64.store 8($0), $pop2 91; CHECK: i32.const $push12=, 16 92; CHECK: i32.add $push3=, $0, $pop12 93; CHECK: i64.store 0($pop3), $1 94; CHECK: i64.store 0($0), $2 95 %t0 = call { i64, i128, i192, i128, i64 } @return_multi_multi() 96 %r0 = extractvalue { i64, i128, i192, i128, i64 } %t0, 0 97 %r1 = extractvalue { i64, i128, i192, i128, i64 } %t0, 1 98 %s0 = insertvalue { i64, i128 } undef, i64 %r0, 0 99 %s1 = insertvalue { i64, i128 } %s0, i128 %r1, 1 100 ret { i64, i128 } %s1 101} 102 103define { i128, i128 } @test6() { 104; CHECK-LABEL: test6 105; CHECK: call return_multi_multi 106; CHECK: i32.const $push0=, 24 107; CHECK: i32.add $push1=, $4, $pop0 108; CHECK: i64.load $1=, 0($pop1) 109; CHECK: i32.const $push2=, 64 110; CHECK: i32.add $push3=, $4, $pop2 111; CHECK: i64.load $2=, 0($pop3) 112; CHECK: i64.load $3=, 16($4) 113; CHECK: i64.load $push4=, 56($4) 114; CHECK: i64.store 16($0), $pop4 115; CHECK: i32.const $push5=, 24 116; CHECK: i32.add $push6=, $0, $pop5 117; CHECK: i64.store 0($pop6), $2 118; CHECK: i64.store 0($0), $3 119; CHECK: i64.store 8($0), $1 120 %t0 = call { i64, i128, i192, i128, i64 } @return_multi_multi() 121 %r1 = extractvalue { i64, i128, i192, i128, i64 } %t0, 1 122 %r3 = extractvalue { i64, i128, i192, i128, i64 } %t0, 3 123 %s0 = insertvalue { i128, i128 } undef, i128 %r1, 0 124 %s1 = insertvalue { i128, i128 } %s0, i128 %r3, 1 125 ret { i128, i128 } %s1 126} 127 128define { i64, i192 } @test7() { 129; CHECK-LABEL: test7 130; CHECK: call return_multi_multi 131; CHECK: i32.const $push2=, 40 132; CHECK: i32.add $push3=, $4, $pop2 133; CHECK: i64.load $1=, 0($pop3) 134; CHECK: i64.load $2=, 8($4) 135; CHECK: i64.load $3=, 32($4) 136; CHECK: i32.const $push0=, 24 137; CHECK: i32.add $push1=, $0, $pop0 138; CHECK: i32.const $push4=, 48 139; CHECK: i32.add $push5=, $4, $pop4 140; CHECK: i64.load $push6=, 0($pop5) 141; CHECK: i64.store 0($pop1), $pop6 142; CHECK: i64.store 8($0), $3 143; CHECK: i32.const $push7=, 16 144; CHECK: i32.add $push8=, $0, $pop7 145; CHECK: i64.store 0($pop8), $1 146; CHECK: i64.store 0($0), $2 147 %t0 = call { i64, i128, i192, i128, i64 } @return_multi_multi() 148 %r0 = extractvalue { i64, i128, i192, i128, i64 } %t0, 0 149 %r2 = extractvalue { i64, i128, i192, i128, i64 } %t0, 2 150 %s0 = insertvalue { i64, i192 } undef, i64 %r0, 0 151 %s1 = insertvalue { i64, i192 } %s0, i192 %r2, 1 152 ret { i64, i192 } %s1 153} 154 155define { i128, i192, i128, i64 } @test8() { 156; CHECK-LABEL: test8 157; CHECK: call return_multi_multi 158; CHECK: i32.const $push0=, 64 159; CHECK: i32.add $push1=, $8, $pop0 160; CHECK: i64.load $1=, 0($pop1) 161; CHECK: i32.const $push20=, 8 162; CHECK: i32.add $push21=, $8, $pop20 163; CHECK: i32.const $push2=, 32 164; CHECK: i32.add $push3=, $pop21, $pop2 165; CHECK: i64.load $2=, 0($pop3) 166; CHECK: i32.const $push4=, 48 167; CHECK: i32.add $push5=, $8, $pop4 168; CHECK: i64.load $3=, 0($pop5) 169; CHECK: i32.const $push6=, 24 170; CHECK: i32.add $push7=, $8, $pop6 171; CHECK: i64.load $4=, 0($pop7) 172; CHECK: i64.load $5=, 8($8) 173; CHECK: i64.load $6=, 56($8) 174; CHECK: i64.load $7=, 32($8) 175; CHECK: i64.load $push8=, 16($8) 176; CHECK: i64.store 40($0), $pop8 177; CHECK: i32.const $push9=, 48 178; CHECK: i32.add $push10=, $0, $pop9 179; CHECK: i64.store 0($pop10), $4 180; CHECK: i32.const $push22=, 32 181; CHECK: i32.add $push11=, $0, $pop22 182; CHECK: i64.store 0($pop11), $3 183; CHECK: i64.store 16($0), $7 184; CHECK: i32.const $push12=, 24 185; CHECK: i32.add $push13=, $0, $pop12 186; CHECK: i64.store 0($pop13), $2 187; CHECK: i64.store 0($0), $6 188; CHECK: i64.store 8($0), $1 189; CHECK: i64.store 56($0), $5 190 %t0 = call { i64, i128, i192, i128, i64 } @return_multi_multi() 191 %r0 = extractvalue { i64, i128, i192, i128, i64 } %t0, 0 192 %r1 = extractvalue { i64, i128, i192, i128, i64 } %t0, 1 193 %r2 = extractvalue { i64, i128, i192, i128, i64 } %t0, 2 194 %r3 = extractvalue { i64, i128, i192, i128, i64 } %t0, 3 195 %s0 = insertvalue { i128, i192, i128, i64 } undef, i128 %r3, 0 196 %s1 = insertvalue { i128, i192, i128, i64 } %s0, i192 %r2, 1 197 %s2 = insertvalue { i128, i192, i128, i64 } %s1, i128 %r1, 2 198 %s3 = insertvalue { i128, i192, i128, i64 } %s2, i64 %r0, 3 199 ret { i128, i192, i128, i64 } %s3 200} 201