diff options
author | Bjorn Pettersson <bjorn.a.pettersson@ericsson.com> | 2019-01-29 10:19:44 +0000 |
---|---|---|
committer | Bjorn Pettersson <bjorn.a.pettersson@ericsson.com> | 2019-01-29 10:19:44 +0000 |
commit | d014d576a9f87c5e952e325cb1c889c7998878d7 (patch) | |
tree | 29278cd8d18fefa71c7bcb3b9e871617a108f6a0 /llvm/test/Transforms/IPConstantProp/arg-count-mismatch.ll | |
parent | 2c3d49b7183679aaad59f4a45a4017a8b6c26532 (diff) | |
download | bcm5719-llvm-d014d576a9f87c5e952e325cb1c889c7998878d7.tar.gz bcm5719-llvm-d014d576a9f87c5e952e325cb1c889c7998878d7.zip |
[IPCP] Don't crash due to arg count/type mismatch between caller/callee
Summary:
This patch avoids an assert in IPConstantPropagation when
there is a argument count/type mismatch between the caller and
the callee.
While this is actually UB on C-level (clang emits a warning),
the IR verifier seems to accept it. I'm not sure what other
frontends/languages might think about this, so simply bailing out
to avoid hitting an assert (in CallSiteBase<>::getArgOperand or
Value::doRAUW) seems like a simple solution.
The problem is exposed by the fact that AbstractCallSites will look
through a bitcast at the callee position of a call/invoke.
Reviewers: jdoerfert, reames, efriedma
Reviewed By: jdoerfert, efriedma
Subscribers: eli.friedman, efriedma, llvm-commits
Differential Revision: https://reviews.llvm.org/D57052
llvm-svn: 352469
Diffstat (limited to 'llvm/test/Transforms/IPConstantProp/arg-count-mismatch.ll')
-rw-r--r-- | llvm/test/Transforms/IPConstantProp/arg-count-mismatch.ll | 72 |
1 files changed, 72 insertions, 0 deletions
diff --git a/llvm/test/Transforms/IPConstantProp/arg-count-mismatch.ll b/llvm/test/Transforms/IPConstantProp/arg-count-mismatch.ll new file mode 100644 index 00000000000..1f62f646509 --- /dev/null +++ b/llvm/test/Transforms/IPConstantProp/arg-count-mismatch.ll @@ -0,0 +1,72 @@ +; RUN: opt < %s -ipconstprop -S -o - | FileCheck %s + +; The original C source looked like this: +; +; long long a101, b101, e101; +; volatile long c101; +; int d101; +; +; static inline int bar(p1, p2) +; { +; return 0; +; } +; +; void foo(unsigned p1) +; { +; long long *f = &b101, *g = &e101; +; c101 = 0; +; (void)((*f |= a101) - (*g = bar(d101))); +; c101 = (*f |= a101 &= p1) == d101; +; } +; +; When compiled with Clang it gives a warning +; warning: too few arguments in call to 'bar' +; +; This ll reproducer has been reduced to only include tha call. +; +; Note that -lint will report this as UB, but it passes -verify. + +; This test is just to verify that we do not crash/assert due to mismatch in +; argument count between the caller and callee. + +define dso_local void @foo(i16 %a) { +; CHECK-LABEL: @foo( +; CHECK-NEXT: [[CALL:%.*]] = call i16 bitcast (i16 (i16, i16)* @bar to i16 (i16)*)(i16 [[A:%.*]]) +; CHECK-NEXT: ret void +; + %call = call i16 bitcast (i16 (i16, i16) * @bar to i16 (i16) *)(i16 %a) + ret void +} + +define internal i16 @bar(i16 %p1, i16 %p2) { +; CHECK-LABEL: @bar( +; CHECK-NEXT: ret i16 0 +; + ret i16 0 +} + +;------------------------------------------------------------------------------- +; Additional tests to verify that we still optimize when having a mismatch +; in argument count due to varargs (as long as all non-variadic arguments have +; been provided), + +define dso_local void @vararg_tests(i16 %a) { + %call1 = call i16 (i16, ...) @vararg_prop(i16 7, i16 8, i16 %a) + %call2 = call i16 bitcast (i16 (i16, i16, ...) * @vararg_no_prop to i16 (i16) *) (i16 7) + ret void +} + +define internal i16 @vararg_prop(i16 %p1, ...) { +; CHECK-LABEL: define internal i16 @vararg_prop( +; CHECK-NEXT: ret i16 7 +; + ret i16 %p1 +} + +define internal i16 @vararg_no_prop(i16 %p1, i16 %p2, ...) { +; CHECK-LABEL: define internal i16 @vararg_no_prop( +; CHECK-NEXT: ret i16 [[P1:%.*]] +; + ret i16 %p1 +} + |