diff options
| author | Reid Kleckner <rnk@google.com> | 2018-03-01 01:19:18 +0000 |
|---|---|---|
| committer | Reid Kleckner <rnk@google.com> | 2018-03-01 01:19:18 +0000 |
| commit | 3762a089d7411665bbc619466d20f5d25e40b02c (patch) | |
| tree | de008788bca1994a8d8ea28763817f2dafb0d03e /llvm/test/Transforms/IPConstantProp | |
| parent | dc32dc1770d0cc3efec93dac1a9695acde02699e (diff) | |
| download | bcm5719-llvm-3762a089d7411665bbc619466d20f5d25e40b02c.tar.gz bcm5719-llvm-3762a089d7411665bbc619466d20f5d25e40b02c.zip | |
[IPSCCP] do not break musttail invariant (PR36485)
Do not replace results of `musttail` calls with a constant if the
call itself can't be removed.
Do not zap returns of `musttail` callees, if the call site can't be
removed and replaced with a constant.
Do not zap returns of `musttail`-calling blocks, this breaks
invariant too.
Patch by Fedor Indutny
Differential Revision: https://reviews.llvm.org/D43695
llvm-svn: 326404
Diffstat (limited to 'llvm/test/Transforms/IPConstantProp')
| -rw-r--r-- | llvm/test/Transforms/IPConstantProp/musttail-call.ll | 58 |
1 files changed, 58 insertions, 0 deletions
diff --git a/llvm/test/Transforms/IPConstantProp/musttail-call.ll b/llvm/test/Transforms/IPConstantProp/musttail-call.ll new file mode 100644 index 00000000000..75877585710 --- /dev/null +++ b/llvm/test/Transforms/IPConstantProp/musttail-call.ll @@ -0,0 +1,58 @@ +; RUN: opt < %s -ipsccp -S | FileCheck %s +; PR36485 +; musttail call result can\'t be replaced with a constant, unless the call +; can be removed + +declare i32 @external() + +define i8* @start(i8 %v) { + %c1 = icmp eq i8 %v, 0 + br i1 %c1, label %true, label %false +true: + ; CHECK: %ca = musttail call i8* @side_effects(i8 %v) + ; CHECK: ret i8* %ca + %ca = musttail call i8* @side_effects(i8 %v) + ret i8* %ca +false: + %c2 = icmp eq i8 %v, 1 + br i1 %c2, label %c2_true, label %c2_false +c2_true: + %ca1 = musttail call i8* @no_side_effects(i8 %v) + ; CHECK: ret i8* null + ret i8* %ca1 +c2_false: + ; CHECK: %ca2 = musttail call i8* @dont_zap_me(i8 %v) + ; CHECK: ret i8* %ca2 + %ca2 = musttail call i8* @dont_zap_me(i8 %v) + ret i8* %ca2 +} + +define internal i8* @side_effects(i8 %v) { + %i1 = call i32 @external() + + ; since this goes back to `start` the SCPP should be see that the return value + ; is always `null`. + ; The call can't be removed due to `external` call above, though. + + ; CHECK: %ca = musttail call i8* @start(i8 %v) + %ca = musttail call i8* @start(i8 %v) + + ; Thus the result must be returned anyway + ; CHECK: ret i8* %ca + ret i8* %ca +} + +define internal i8* @no_side_effects(i8 %v) readonly nounwind { + ; The call to this function is removed, so the return value must be zapped + ; CHECK: ret i8* undef + ret i8* null +} + +define internal i8* @dont_zap_me(i8 %v) { + %i1 = call i32 @external() + + ; The call to this function cannot be removed due to side effects. Thus the + ; return value should stay as it is, and should not be zapped. + ; CHECK: ret i8* null + ret i8* null +} |

