@@ -977,6 +977,176 @@ define ccc void @t22_non_sret_to_sret(ptr %agg.result) nounwind {
977977 ret void
978978}
979979
980+ ; Not tailcallable, caller and callee have different return types.
981+ define void @t23_sret_to_non_sret (ptr noalias sret (%struct.foo ) align 4 %agg.result , ptr %arg ) {
982+ ; X86-LABEL: t23_sret_to_non_sret:
983+ ; X86: # %bb.0:
984+ ; X86-NEXT: pushl %esi
985+ ; X86-NEXT: .cfi_def_cfa_offset 8
986+ ; X86-NEXT: subl $8, %esp
987+ ; X86-NEXT: .cfi_def_cfa_offset 16
988+ ; X86-NEXT: .cfi_offset %esi, -8
989+ ; X86-NEXT: movl {{[0-9]+}}(%esp), %esi
990+ ; X86-NEXT: movl {{[0-9]+}}(%esp), %eax
991+ ; X86-NEXT: movl %eax, (%esp)
992+ ; X86-NEXT: calll callee_1@PLT
993+ ; X86-NEXT: movl %esi, %eax
994+ ; X86-NEXT: addl $8, %esp
995+ ; X86-NEXT: .cfi_def_cfa_offset 8
996+ ; X86-NEXT: popl %esi
997+ ; X86-NEXT: .cfi_def_cfa_offset 4
998+ ; X86-NEXT: retl $4
999+ ;
1000+ ; X64-LABEL: t23_sret_to_non_sret:
1001+ ; X64: # %bb.0:
1002+ ; X64-NEXT: pushq %rbx
1003+ ; X64-NEXT: .cfi_def_cfa_offset 16
1004+ ; X64-NEXT: .cfi_offset %rbx, -16
1005+ ; X64-NEXT: movq %rdi, %rbx
1006+ ; X64-NEXT: movq %rsi, %rdi
1007+ ; X64-NEXT: callq callee_1@PLT
1008+ ; X64-NEXT: movq %rbx, %rax
1009+ ; X64-NEXT: popq %rbx
1010+ ; X64-NEXT: .cfi_def_cfa_offset 8
1011+ ; X64-NEXT: retq
1012+ ;
1013+ ; X32-LABEL: t23_sret_to_non_sret:
1014+ ; X32: # %bb.0:
1015+ ; X32-NEXT: pushq %rbx
1016+ ; X32-NEXT: .cfi_def_cfa_offset 16
1017+ ; X32-NEXT: .cfi_offset %rbx, -16
1018+ ; X32-NEXT: movq %rdi, %rbx
1019+ ; X32-NEXT: movq %rsi, %rdi
1020+ ; X32-NEXT: callq callee_1@PLT
1021+ ; X32-NEXT: movl %ebx, %eax
1022+ ; X32-NEXT: popq %rbx
1023+ ; X32-NEXT: .cfi_def_cfa_offset 8
1024+ ; X32-NEXT: retq
1025+ tail call void @callee_1 (ptr %arg )
1026+ ret void
1027+ }
1028+
1029+ ; Not tailcallable, caller and callee have the same return type, but different return values.
1030+ define void @t24_sret_to_sret_different_val (ptr noalias sret (%struct.foo ) align 4 %agg.result , ptr %arg ) {
1031+ ; X86-LABEL: t24_sret_to_sret_different_val:
1032+ ; X86: # %bb.0:
1033+ ; X86-NEXT: pushl %esi
1034+ ; X86-NEXT: .cfi_def_cfa_offset 8
1035+ ; X86-NEXT: subl $24, %esp
1036+ ; X86-NEXT: .cfi_def_cfa_offset 32
1037+ ; X86-NEXT: .cfi_offset %esi, -8
1038+ ; X86-NEXT: movl {{[0-9]+}}(%esp), %esi
1039+ ; X86-NEXT: xorps %xmm0, %xmm0
1040+ ; X86-NEXT: movsd %xmm0, 8(%esi)
1041+ ; X86-NEXT: movsd %xmm0, (%esi)
1042+ ; X86-NEXT: leal {{[0-9]+}}(%esp), %eax
1043+ ; X86-NEXT: movl %eax, (%esp)
1044+ ; X86-NEXT: calll callee_2@PLT
1045+ ; X86-NEXT: subl $4, %esp
1046+ ; X86-NEXT: movl %esi, %eax
1047+ ; X86-NEXT: addl $24, %esp
1048+ ; X86-NEXT: .cfi_def_cfa_offset 8
1049+ ; X86-NEXT: popl %esi
1050+ ; X86-NEXT: .cfi_def_cfa_offset 4
1051+ ; X86-NEXT: retl $4
1052+ ;
1053+ ; X64-LABEL: t24_sret_to_sret_different_val:
1054+ ; X64: # %bb.0:
1055+ ; X64-NEXT: pushq %rbx
1056+ ; X64-NEXT: .cfi_def_cfa_offset 16
1057+ ; X64-NEXT: subq $16, %rsp
1058+ ; X64-NEXT: .cfi_def_cfa_offset 32
1059+ ; X64-NEXT: .cfi_offset %rbx, -16
1060+ ; X64-NEXT: movq %rdi, %rbx
1061+ ; X64-NEXT: movq $0, 8(%rdi)
1062+ ; X64-NEXT: movq $0, (%rdi)
1063+ ; X64-NEXT: movq %rsp, %rdi
1064+ ; X64-NEXT: callq callee_2@PLT
1065+ ; X64-NEXT: movq %rbx, %rax
1066+ ; X64-NEXT: addq $16, %rsp
1067+ ; X64-NEXT: .cfi_def_cfa_offset 16
1068+ ; X64-NEXT: popq %rbx
1069+ ; X64-NEXT: .cfi_def_cfa_offset 8
1070+ ; X64-NEXT: retq
1071+ ;
1072+ ; X32-LABEL: t24_sret_to_sret_different_val:
1073+ ; X32: # %bb.0:
1074+ ; X32-NEXT: pushq %rbx
1075+ ; X32-NEXT: .cfi_def_cfa_offset 16
1076+ ; X32-NEXT: subl $16, %esp
1077+ ; X32-NEXT: .cfi_def_cfa_offset 32
1078+ ; X32-NEXT: .cfi_offset %rbx, -16
1079+ ; X32-NEXT: movq %rdi, %rbx
1080+ ; X32-NEXT: movq $0, 8(%ebx)
1081+ ; X32-NEXT: movq $0, (%ebx)
1082+ ; X32-NEXT: movl %esp, %edi
1083+ ; X32-NEXT: callq callee_2@PLT
1084+ ; X32-NEXT: movl %ebx, %eax
1085+ ; X32-NEXT: addl $16, %esp
1086+ ; X32-NEXT: .cfi_def_cfa_offset 16
1087+ ; X32-NEXT: popq %rbx
1088+ ; X32-NEXT: .cfi_def_cfa_offset 8
1089+ ; X32-NEXT: retq
1090+ %callee.return = alloca %struct.foo , align 4
1091+ tail call void @llvm.memset.p0.i64 (ptr align 4 %agg.result , i8 0 , i64 16 , i1 false )
1092+ tail call void @callee_2 (ptr sret (%struct.foo ) align 4 %callee.return )
1093+ ret void
1094+ }
1095+
1096+ ; Not tailcallable, caller and callee have the same return type, but different return values.
1097+ define void @t25_sret_to_sret_different_val (ptr noalias sret (%struct.foo ) align 8 %agg.result , ptr %arg ) {
1098+ ; X86-LABEL: t25_sret_to_sret_different_val:
1099+ ; X86: # %bb.0:
1100+ ; X86-NEXT: pushl %esi
1101+ ; X86-NEXT: .cfi_def_cfa_offset 8
1102+ ; X86-NEXT: subl $8, %esp
1103+ ; X86-NEXT: .cfi_def_cfa_offset 16
1104+ ; X86-NEXT: .cfi_offset %esi, -8
1105+ ; X86-NEXT: movl {{[0-9]+}}(%esp), %esi
1106+ ; X86-NEXT: movl {{[0-9]+}}(%esp), %eax
1107+ ; X86-NEXT: movl %eax, (%esp)
1108+ ; X86-NEXT: calll callee_2@PLT
1109+ ; X86-NEXT: subl $4, %esp
1110+ ; X86-NEXT: movl %esi, %eax
1111+ ; X86-NEXT: addl $8, %esp
1112+ ; X86-NEXT: .cfi_def_cfa_offset 8
1113+ ; X86-NEXT: popl %esi
1114+ ; X86-NEXT: .cfi_def_cfa_offset 4
1115+ ; X86-NEXT: retl $4
1116+ ;
1117+ ; X64-LABEL: t25_sret_to_sret_different_val:
1118+ ; X64: # %bb.0:
1119+ ; X64-NEXT: pushq %rbx
1120+ ; X64-NEXT: .cfi_def_cfa_offset 16
1121+ ; X64-NEXT: .cfi_offset %rbx, -16
1122+ ; X64-NEXT: movq %rdi, %rbx
1123+ ; X64-NEXT: movq %rsi, %rdi
1124+ ; X64-NEXT: callq callee_2@PLT
1125+ ; X64-NEXT: movq %rbx, %rax
1126+ ; X64-NEXT: popq %rbx
1127+ ; X64-NEXT: .cfi_def_cfa_offset 8
1128+ ; X64-NEXT: retq
1129+ ;
1130+ ; X32-LABEL: t25_sret_to_sret_different_val:
1131+ ; X32: # %bb.0:
1132+ ; X32-NEXT: pushq %rbx
1133+ ; X32-NEXT: .cfi_def_cfa_offset 16
1134+ ; X32-NEXT: .cfi_offset %rbx, -16
1135+ ; X32-NEXT: movq %rdi, %rbx
1136+ ; X32-NEXT: movq %rsi, %rdi
1137+ ; X32-NEXT: callq callee_2@PLT
1138+ ; X32-NEXT: movl %ebx, %eax
1139+ ; X32-NEXT: popq %rbx
1140+ ; X32-NEXT: .cfi_def_cfa_offset 8
1141+ ; X32-NEXT: retq
1142+ tail call void @callee_2 (ptr sret (%struct.foo ) align 8 %arg )
1143+ ret void
1144+ }
1145+
1146+ declare void @llvm.memset.p0.i64 (ptr , i8 , i64 , i1 )
1147+ declare void @callee_1 (ptr )
1148+ declare void @callee_2 (ptr noalias sret (%struct.foo ))
1149+
9801150declare dso_local fastcc void @t21_f_sret (ptr noalias sret (%struct.foo )) nounwind
9811151declare dso_local fastcc void @t21_f_sret2 (ptr noalias sret (%struct.foo ), ptr noalias ) nounwind
9821152declare dso_local fastcc void @t21_f_non_sret (ptr ) nounwind
0 commit comments