From a3c78f59814f90a06994f720d75ecbae2612c4c3 Mon Sep 17 00:00:00 2001 From: Eli Friedman Date: Thu, 19 Jul 2018 23:02:07 +0000 Subject: [SCCP] Don't use markForcedConstant on branch conditions. It's more aggressive than we need to be, and leads to strange workarounds in other places like call return value inference. Instead, just directly mark an edge viable. Tests by Florian Hahn. Differential Revision: https://reviews.llvm.org/D49408 llvm-svn: 337507 --- .../SCCP/ipsccp-branch-unresolved-undef.ll | 24 +++++++++ .../Transforms/SCCP/ipsccp-phi-one-pred-dead.ll | 4 +- llvm/test/Transforms/SCCP/return-zapped.ll | 62 ++++++++++++++++++++++ 3 files changed, 89 insertions(+), 1 deletion(-) create mode 100644 llvm/test/Transforms/SCCP/ipsccp-branch-unresolved-undef.ll create mode 100644 llvm/test/Transforms/SCCP/return-zapped.ll (limited to 'llvm/test/Transforms') diff --git a/llvm/test/Transforms/SCCP/ipsccp-branch-unresolved-undef.ll b/llvm/test/Transforms/SCCP/ipsccp-branch-unresolved-undef.ll new file mode 100644 index 00000000000..7092b8d587a --- /dev/null +++ b/llvm/test/Transforms/SCCP/ipsccp-branch-unresolved-undef.ll @@ -0,0 +1,24 @@ +; NOTE: Assertions have been autogenerated by utils/update_test_checks.py +; RUN: opt < %s -S -ipsccp | FileCheck %s + +define void @main() { +; CHECK-LABEL: @main( +; CHECK: %call = call i1 @patatino(i1 undef) +; CHECK-NEXT: ret void +; + %call = call i1 @patatino(i1 undef) + ret void +} + +define internal i1 @patatino(i1 %a) { +; CHECK-LABEL: define internal i1 @patatino( +; CHECK-NEXT: br label [[ONFALSE:%.*]] +; CHECK-EMPTY: +; CHECK-NEXT: onfalse: +; CHECK-NEXT: ret i1 undef + br i1 %a, label %ontrue, label %onfalse +ontrue: + ret i1 false +onfalse: + ret i1 false +} diff --git a/llvm/test/Transforms/SCCP/ipsccp-phi-one-pred-dead.ll b/llvm/test/Transforms/SCCP/ipsccp-phi-one-pred-dead.ll index afba1f41957..07637bd8bdb 100644 --- a/llvm/test/Transforms/SCCP/ipsccp-phi-one-pred-dead.ll +++ b/llvm/test/Transforms/SCCP/ipsccp-phi-one-pred-dead.ll @@ -7,11 +7,13 @@ define void @test() { ; CHECK-NEXT: entry: ; CHECK-NEXT: br label %Flow5.pre ; CHECK: Flow6: -; CHECK-NEXT: br label %end2 +; CHECK-NEXT: br i1 undef, label %end1, label %end2 ; CHECK: Flow5.pre: ; CHECK-NEXT: br label %Flow5 ; CHECK: Flow5: ; CHECK-NEXT: br label %Flow6 +; CHECK: end1: +; CHECK-NEXT: unreachable ; CHECK: end2: ; CHECK-NEXT: unreachable ; diff --git a/llvm/test/Transforms/SCCP/return-zapped.ll b/llvm/test/Transforms/SCCP/return-zapped.ll new file mode 100644 index 00000000000..1cdf9076821 --- /dev/null +++ b/llvm/test/Transforms/SCCP/return-zapped.ll @@ -0,0 +1,62 @@ +; RUN: opt < %s -S -ipsccp | FileCheck %s + +; After the first round of Solver.Solve(), the return value of @testf still +; undefined as we hit a branch on undef. Therefore the conditional branch on +; @testf's return value in @bar is unknown. In ResolvedUndefsIn, we force the +; false branch to be feasible. We later discover that @testf actually +; returns true, so we end up with an unfolded "br i1 true". +define void @test1() { +; CHECK-LABEL: @test1( +; CHECK-LABEL: if.then: +; CHECK: [[CALL:%.+]] = call i1 @testf() +; CHECK-NEXT: br i1 true, label %if.end, label %if.then +; +entry: + br label %if.then +if.then: ; preds = %entry, %if.then + %foo = phi i32 [ 0, %entry], [ %next, %if.then] + %next = add i32 %foo, 1 + %call = call i1 @testf() + br i1 %call, label %if.end, label %if.then + +if.end: ; preds = %if.then, %entry + ret void +} + +define internal i1 @testf() { +; CHECK-LABEL: define internal i1 @testf( +; CHECK-NEXT: entry: +; CHECK-NEXT: br label [[IF_END3:%.*]] +; CHECK: if.end3: +; CHECK-NEXT: ret i1 undef +; +entry: + br i1 undef, label %if.then1, label %if.end3 + +if.then1: ; preds = %if.end + br label %if.end3 + +if.end3: ; preds = %if.then1, %entry + ret i1 true +} + + +; Call sites in unreachable blocks should not be a problem. +; CHECK-LABEL: define i1 @test2() { +; CHECK-NEXT: entry: +; CHECK-NEXT: br label %if.end +; CHECK-LABEL: if.end: ; preds = %entry +; CHECK-NEXT: %call2 = call i1 @testf() +; CHECK-NEXT: ret i1 true +define i1 @test2() { +entry: + br label %if.end + +if.then: ; preds = %entry, %if.then + %call = call i1 @testf() + br i1 %call, label %if.end, label %if.then + +if.end: ; preds = %if.then, %entry + %call2 = call i1 @testf() + ret i1 %call2 +} -- cgit v1.2.3