1; NOTE: Assertions have been autogenerated by utils/update_llc_test_checks.py 2; RUN: llc -mtriple=riscv32 -verify-machineinstrs < %s \ 3; RUN: | FileCheck -check-prefix=RV32I %s 4; RUN: llc -mtriple=riscv64 -verify-machineinstrs < %s \ 5; RUN: | FileCheck -check-prefix=RV64I %s 6 7; When passing a function argument with a size that isn't a multiple of XLEN, 8; and the argument is split and passed indirectly, we must ensure that the stack 9; slot size appropriately reflects the total size of the parts the argument is 10; split into. Otherwise, stack writes can clobber neighboring values. 11 12declare void @callee129(i129) 13declare void @callee160(i160) 14declare void @callee161(i161) 15 16; FIXME: Stack write clobbers the spilled value (on RV64). 17define i32 @caller129() nounwind { 18; RV32I-LABEL: caller129: 19; RV32I: # %bb.0: 20; RV32I-NEXT: addi sp, sp, -32 21; RV32I-NEXT: sw ra, 28(sp) # 4-byte Folded Spill 22; RV32I-NEXT: addi a0, zero, 42 23; RV32I-NEXT: sw a0, 24(sp) 24; RV32I-NEXT: sw zero, 16(sp) 25; RV32I-NEXT: sw zero, 12(sp) 26; RV32I-NEXT: sw zero, 8(sp) 27; RV32I-NEXT: sw zero, 4(sp) 28; RV32I-NEXT: mv a0, sp 29; RV32I-NEXT: sw zero, 0(sp) 30; RV32I-NEXT: call callee129@plt 31; RV32I-NEXT: lw a0, 24(sp) 32; RV32I-NEXT: lw ra, 28(sp) # 4-byte Folded Reload 33; RV32I-NEXT: addi sp, sp, 32 34; RV32I-NEXT: ret 35; 36; RV64I-LABEL: caller129: 37; RV64I: # %bb.0: 38; RV64I-NEXT: addi sp, sp, -32 39; RV64I-NEXT: sd ra, 24(sp) # 8-byte Folded Spill 40; RV64I-NEXT: addi a0, zero, 42 41; RV64I-NEXT: sw a0, 20(sp) 42; RV64I-NEXT: sd zero, 16(sp) 43; RV64I-NEXT: sd zero, 8(sp) 44; RV64I-NEXT: mv a0, sp 45; RV64I-NEXT: sd zero, 0(sp) 46; RV64I-NEXT: call callee129@plt 47; RV64I-NEXT: lw a0, 20(sp) 48; RV64I-NEXT: ld ra, 24(sp) # 8-byte Folded Reload 49; RV64I-NEXT: addi sp, sp, 32 50; RV64I-NEXT: ret 51 %1 = alloca i32 52 store i32 42, i32* %1 53 call void @callee129(i129 0) 54 %2 = load i32, i32* %1 55 ret i32 %2 56} 57 58; FIXME: Stack write clobbers the spilled value (on RV64). 59define i32 @caller160() nounwind { 60; RV32I-LABEL: caller160: 61; RV32I: # %bb.0: 62; RV32I-NEXT: addi sp, sp, -32 63; RV32I-NEXT: sw ra, 28(sp) # 4-byte Folded Spill 64; RV32I-NEXT: addi a0, zero, 42 65; RV32I-NEXT: sw a0, 24(sp) 66; RV32I-NEXT: sw zero, 16(sp) 67; RV32I-NEXT: sw zero, 12(sp) 68; RV32I-NEXT: sw zero, 8(sp) 69; RV32I-NEXT: sw zero, 4(sp) 70; RV32I-NEXT: mv a0, sp 71; RV32I-NEXT: sw zero, 0(sp) 72; RV32I-NEXT: call callee160@plt 73; RV32I-NEXT: lw a0, 24(sp) 74; RV32I-NEXT: lw ra, 28(sp) # 4-byte Folded Reload 75; RV32I-NEXT: addi sp, sp, 32 76; RV32I-NEXT: ret 77; 78; RV64I-LABEL: caller160: 79; RV64I: # %bb.0: 80; RV64I-NEXT: addi sp, sp, -32 81; RV64I-NEXT: sd ra, 24(sp) # 8-byte Folded Spill 82; RV64I-NEXT: addi a0, zero, 42 83; RV64I-NEXT: sw a0, 20(sp) 84; RV64I-NEXT: sd zero, 16(sp) 85; RV64I-NEXT: sd zero, 8(sp) 86; RV64I-NEXT: mv a0, sp 87; RV64I-NEXT: sd zero, 0(sp) 88; RV64I-NEXT: call callee160@plt 89; RV64I-NEXT: lw a0, 20(sp) 90; RV64I-NEXT: ld ra, 24(sp) # 8-byte Folded Reload 91; RV64I-NEXT: addi sp, sp, 32 92; RV64I-NEXT: ret 93 %1 = alloca i32 94 store i32 42, i32* %1 95 call void @callee160(i160 0) 96 %2 = load i32, i32* %1 97 ret i32 %2 98} 99 100define i32 @caller161() nounwind { 101; RV32I-LABEL: caller161: 102; RV32I: # %bb.0: 103; RV32I-NEXT: addi sp, sp, -32 104; RV32I-NEXT: sw ra, 28(sp) # 4-byte Folded Spill 105; RV32I-NEXT: addi a0, zero, 42 106; RV32I-NEXT: sw a0, 24(sp) 107; RV32I-NEXT: sw zero, 20(sp) 108; RV32I-NEXT: sw zero, 16(sp) 109; RV32I-NEXT: sw zero, 12(sp) 110; RV32I-NEXT: sw zero, 8(sp) 111; RV32I-NEXT: sw zero, 4(sp) 112; RV32I-NEXT: mv a0, sp 113; RV32I-NEXT: sw zero, 0(sp) 114; RV32I-NEXT: call callee161@plt 115; RV32I-NEXT: lw a0, 24(sp) 116; RV32I-NEXT: lw ra, 28(sp) # 4-byte Folded Reload 117; RV32I-NEXT: addi sp, sp, 32 118; RV32I-NEXT: ret 119; 120; RV64I-LABEL: caller161: 121; RV64I: # %bb.0: 122; RV64I-NEXT: addi sp, sp, -48 123; RV64I-NEXT: sd ra, 40(sp) # 8-byte Folded Spill 124; RV64I-NEXT: addi a0, zero, 42 125; RV64I-NEXT: sw a0, 36(sp) 126; RV64I-NEXT: sd zero, 16(sp) 127; RV64I-NEXT: sd zero, 8(sp) 128; RV64I-NEXT: mv a0, sp 129; RV64I-NEXT: sd zero, 0(sp) 130; RV64I-NEXT: call callee161@plt 131; RV64I-NEXT: lw a0, 36(sp) 132; RV64I-NEXT: ld ra, 40(sp) # 8-byte Folded Reload 133; RV64I-NEXT: addi sp, sp, 48 134; RV64I-NEXT: ret 135 %1 = alloca i32 136 store i32 42, i32* %1 137 call void @callee161(i161 0) 138 %2 = load i32, i32* %1 139 ret i32 %2 140} 141