diff --git a/llvm/test/tools/llvm-reduce/issue100880-mismatched-call-type.ll b/llvm/test/tools/llvm-reduce/issue100880-mismatched-call-type.ll new file mode 100644 index 0000000000000..7854ed255ebe8 --- /dev/null +++ b/llvm/test/tools/llvm-reduce/issue100880-mismatched-call-type.ll @@ -0,0 +1,24 @@ +; RUN: llvm-reduce %s -o %t --abort-on-invalid-reduction --delta-passes=operands-to-args --test FileCheck --test-arg %s --test-arg --check-prefix=INTERESTING --test-arg --input-file +; RUN: FileCheck %s --input-file %t --check-prefix=REDUCED + +@a = dso_local global i8 0, align 1 +@b = dso_local global i16 0, align 2 + +; INTERESTING-LABEL: define void @c( +; INTERESTING: sext +; INTERESTING: icmp + +; REDUCED: define void @c(ptr %a, i8 %ld0, ptr %b, i16 %ld1, i32 %conv, i32 %conv1, i1 %cmp, i32 %conv2) +; REDUCED: call void @c(i32 noundef signext %conv2) +define void @c() { +entry: + %ld0 = load i8, ptr @a, align 1 + %conv = zext i8 %ld0 to i32 + %ld1 = load i16, ptr @b, align 2 + %conv1 = sext i16 %ld1 to i32 + %cmp = icmp sge i32 %conv, %conv1 + %conv2 = zext i1 %cmp to i32 + call void @c(i32 noundef signext %conv2) + ret void +} + diff --git a/llvm/test/tools/llvm-reduce/operands-to-args-wrong-call-type-issue69312.ll b/llvm/test/tools/llvm-reduce/operands-to-args-wrong-call-type-issue69312.ll new file mode 100644 index 0000000000000..542737b08ce2b --- /dev/null +++ b/llvm/test/tools/llvm-reduce/operands-to-args-wrong-call-type-issue69312.ll @@ -0,0 +1,44 @@ +; RUN: llvm-reduce %s -o %t --abort-on-invalid-reduction --delta-passes=operands-to-args --test FileCheck --test-arg %s --test-arg --match-full-lines --test-arg --check-prefix=INTERESTING --test-arg --input-file +; RUN: FileCheck %s --input-file %t --check-prefixes=REDUCED,INTERESTING + +; REDUCED-LABEL: define void @func(i32 %k, i32 %extra.arg, ptr %Global, ptr %Local) { + +; Keep one reference to the original value. +; INTERESTING: %[[LOCAL:Local[0-9]*]] = alloca i32, align 4 + +; Everything else must use the function argument. +; REDUCED: store i32 21, ptr %Global, align 4 +; REDUCED: store i32 0, ptr %Local, align 4 +; REDUCED: store i32 0, ptr %Global, align 4 + +; Do not add any arguments for %Keep and @GlobalKeep. +; INTERESTING: %[[KEEP:LocalKeep[0-9]*]] = add i32 %k, 21 +; INTERESTING: store i32 %[[KEEP]], ptr @GlobalKeep, align 4 + +; Do not add any arguments if the call type was already mismatched + +; INTERESTING-LABEL: define void @mismatched_func_caller() { +; REDUCED: call void @func(i32 21) + +@Global = global i32 42 +@GlobalKeep = global i32 42 + +define void @func(i32 %k, i32 %extra.arg) { +entry: + %Local = alloca i32, align 4 + store i32 21, ptr @Global, align 4 + store i32 0, ptr %Local, align 4 + store i32 0, ptr @Global, align 4 + %LocalKeep = add i32 %k, 21 + store i32 %LocalKeep, ptr @GlobalKeep, align 4 + ret void +} + +; This call has the wrong signature for the original underlying call, +; so getCalledFunction does not return a reference to the function. +define void @mismatched_func_caller() { +entry: + call void @func(i32 21) + ret void +} + diff --git a/llvm/tools/llvm-reduce/deltas/ReduceOperandsToArgs.cpp b/llvm/tools/llvm-reduce/deltas/ReduceOperandsToArgs.cpp index aff0b849e8b83..66d4bd3048171 100644 --- a/llvm/tools/llvm-reduce/deltas/ReduceOperandsToArgs.cpp +++ b/llvm/tools/llvm-reduce/deltas/ReduceOperandsToArgs.cpp @@ -61,8 +61,20 @@ static void replaceFunctionCalls(Function *OldF, Function *NewF) { for (Use &U : OldF->uses()) { auto *CI = cast(U.getUser()); assert(&U == &CI->getCalledOperandUse()); - assert(CI->getCalledFunction() == OldF); - Callers.push_back(CI); + + Function *CalledF = CI->getCalledFunction(); + if (CalledF == OldF) { + Callers.push_back(CI); + } else { + // The call may have undefined behavior by calling a function with a + // mismatched signature. In this case, do not bother adjusting the + // callsites to pad with any new arguments. + + // TODO: Better QoI to try to add new arguments to the end, and ignore + // existing mismatches. + assert(!CalledF && CI->getCalledOperand()->stripPointerCasts() == OldF && + "only expected call and function signature mismatch"); + } } // Call arguments for NewF.