Skip to content

Commit e665925

Browse files
authored
llvm-reduce: Add values to return reduction (#132686)
In void functions, try to replace instruction uses with a new non-void return. If the return type matches the instruction, also try to directly return it. This handles most of the cases, but doesn't try to handle all of the weird exception related terminators. Also doesn't try to replace argument uses, although it could. We could also handle cases where we can insert a simple cast to an original return value. I didn't think too hard about where to put this in the default pass order. In many cases it obviates the need for most of the CFG folds, but I've left it near the end initially. I also think this is too aggressive about removing dead code, and should leave existing dead code alone. I'm also not sure why we have both "removeUnreachableBlocks" and EliminateUnreachableBlocks" in Utils. Fixes #66039, fixes #107327
1 parent 0b2ab11 commit e665925

12 files changed

+1341
-3
lines changed

llvm/include/llvm/IR/Function.h

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1048,6 +1048,14 @@ class LLVM_ABI Function : public GlobalObject, public ilist_node<Function> {
10481048
void setValueSubclassDataBit(unsigned Bit, bool On);
10491049
};
10501050

1051+
namespace CallingConv {
1052+
1053+
// TODO: Need similar function for support of argument in position. General
1054+
// version on FunctionType + Attributes + CallingConv::ID?
1055+
LLVM_READNONE
1056+
bool supportsNonVoidReturnType(CallingConv::ID CC);
1057+
} // namespace CallingConv
1058+
10511059
/// Check whether null pointer dereferencing is considered undefined behavior
10521060
/// for a given function or an address space.
10531061
/// Null pointer access in non-zero address space is not considered undefined.

llvm/lib/IR/Function.cpp

Lines changed: 82 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1176,3 +1176,85 @@ bool llvm::NullPointerIsDefined(const Function *F, unsigned AS) {
11761176

11771177
return false;
11781178
}
1179+
1180+
bool llvm::CallingConv::supportsNonVoidReturnType(CallingConv::ID CC) {
1181+
switch (CC) {
1182+
case CallingConv::C:
1183+
case CallingConv::Fast:
1184+
case CallingConv::Cold:
1185+
case CallingConv::GHC:
1186+
case CallingConv::HiPE:
1187+
case CallingConv::AnyReg:
1188+
case CallingConv::PreserveMost:
1189+
case CallingConv::PreserveAll:
1190+
case CallingConv::Swift:
1191+
case CallingConv::CXX_FAST_TLS:
1192+
case CallingConv::Tail:
1193+
case CallingConv::CFGuard_Check:
1194+
case CallingConv::SwiftTail:
1195+
case CallingConv::PreserveNone:
1196+
case CallingConv::X86_StdCall:
1197+
case CallingConv::X86_FastCall:
1198+
case CallingConv::ARM_APCS:
1199+
case CallingConv::ARM_AAPCS:
1200+
case CallingConv::ARM_AAPCS_VFP:
1201+
case CallingConv::MSP430_INTR:
1202+
case CallingConv::X86_ThisCall:
1203+
case CallingConv::PTX_Device:
1204+
case CallingConv::SPIR_FUNC:
1205+
case CallingConv::Intel_OCL_BI:
1206+
case CallingConv::X86_64_SysV:
1207+
case CallingConv::Win64:
1208+
case CallingConv::X86_VectorCall:
1209+
case CallingConv::DUMMY_HHVM:
1210+
case CallingConv::DUMMY_HHVM_C:
1211+
case CallingConv::X86_INTR:
1212+
case CallingConv::AVR_INTR:
1213+
case CallingConv::AVR_SIGNAL:
1214+
case CallingConv::AVR_BUILTIN:
1215+
return true;
1216+
case CallingConv::AMDGPU_KERNEL:
1217+
case CallingConv::SPIR_KERNEL:
1218+
case CallingConv::AMDGPU_CS_Chain:
1219+
case CallingConv::AMDGPU_CS_ChainPreserve:
1220+
return false;
1221+
case CallingConv::AMDGPU_VS:
1222+
case CallingConv::AMDGPU_HS:
1223+
case CallingConv::AMDGPU_GS:
1224+
case CallingConv::AMDGPU_PS:
1225+
case CallingConv::AMDGPU_CS:
1226+
case CallingConv::AMDGPU_LS:
1227+
case CallingConv::AMDGPU_ES:
1228+
case CallingConv::MSP430_BUILTIN:
1229+
case CallingConv::AArch64_VectorCall:
1230+
case CallingConv::AArch64_SVE_VectorCall:
1231+
case CallingConv::WASM_EmscriptenInvoke:
1232+
case CallingConv::AMDGPU_Gfx:
1233+
case CallingConv::M68k_INTR:
1234+
case CallingConv::AArch64_SME_ABI_Support_Routines_PreserveMost_From_X0:
1235+
case CallingConv::AArch64_SME_ABI_Support_Routines_PreserveMost_From_X2:
1236+
case CallingConv::M68k_RTD:
1237+
case CallingConv::GRAAL:
1238+
case CallingConv::ARM64EC_Thunk_X64:
1239+
case CallingConv::ARM64EC_Thunk_Native:
1240+
case CallingConv::RISCV_VectorCall:
1241+
case CallingConv::AArch64_SME_ABI_Support_Routines_PreserveMost_From_X1:
1242+
case CallingConv::RISCV_VLSCall_32:
1243+
case CallingConv::RISCV_VLSCall_64:
1244+
case CallingConv::RISCV_VLSCall_128:
1245+
case CallingConv::RISCV_VLSCall_256:
1246+
case CallingConv::RISCV_VLSCall_512:
1247+
case CallingConv::RISCV_VLSCall_1024:
1248+
case CallingConv::RISCV_VLSCall_2048:
1249+
case CallingConv::RISCV_VLSCall_4096:
1250+
case CallingConv::RISCV_VLSCall_8192:
1251+
case CallingConv::RISCV_VLSCall_16384:
1252+
case CallingConv::RISCV_VLSCall_32768:
1253+
case CallingConv::RISCV_VLSCall_65536:
1254+
return true;
1255+
default:
1256+
return false;
1257+
}
1258+
1259+
llvm_unreachable("covered callingconv switch");
1260+
}
Lines changed: 27 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,27 @@
1+
; Make sure we don't break on non-callee uses of funtions with a
2+
; non-void return type.
3+
4+
; RUN: llvm-reduce --abort-on-invalid-reduction --delta-passes=instructions-to-return --test FileCheck --test-arg --check-prefix=INTERESTING --test-arg %s --test-arg --input-file %s -o %t
5+
; RUN: FileCheck --check-prefix=RESULT %s < %t
6+
7+
; INTERESTING-LABEL: @interesting(
8+
; INTERESTING: %inttoptr = inttoptr i64
9+
10+
; RESULT-LABEL: define ptr @interesting(i64 %arg) {
11+
; RESULT-NEXT: %inttoptr = inttoptr i64 %arg to ptr
12+
; RESULT-NEXT: ret ptr %inttoptr
13+
define void @interesting(i64 %arg) {
14+
%inttoptr = inttoptr i64 %arg to ptr
15+
%load = load i32, ptr %inttoptr
16+
ret void
17+
}
18+
19+
declare i32 @func(ptr)
20+
21+
; RESULT-LABEL: define i32 @caller() {
22+
; RESULT-NEXT: %call = call i32 @func(ptr @interesting)
23+
; RESULT-NEXT: ret i32 %call
24+
define void @caller() {
25+
%call = call i32 @func(ptr @interesting)
26+
ret void
27+
}

0 commit comments

Comments
 (0)