From d3fa093dc94237e697025333dc15a512d4ed56cc Mon Sep 17 00:00:00 2001 From: Jan Vesely Date: Wed, 13 Aug 2014 20:31:53 +0000 Subject: [PATCH] utils: Fix segfault in flattencfg v2: continue iterating through the rest of the bb use for loop v3: initialize FlattenCFG pass in ScalarOps add test v4: split off initializing flattencfg to a separate patch add comment Signed-off-by: Jan Vesely git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@215574 91177308-0d34-0410-b5e6-96231b3b80d8 --- lib/Transforms/Utils/FlattenCFG.cpp | 9 +++++---- test/Transforms/Util/flattencfg.ll | 26 ++++++++++++++++++++++++++ 2 files changed, 31 insertions(+), 4 deletions(-) create mode 100644 test/Transforms/Util/flattencfg.ll diff --git a/lib/Transforms/Utils/FlattenCFG.cpp b/lib/Transforms/Utils/FlattenCFG.cpp index 51ead40c916..4eb3e3dd17d 100644 --- a/lib/Transforms/Utils/FlattenCFG.cpp +++ b/lib/Transforms/Utils/FlattenCFG.cpp @@ -238,9 +238,13 @@ bool FlattenCFGOpt::FlattenParallelAndOr(BasicBlock *BB, IRBuilder<> &Builder, // Do branch inversion. BasicBlock *CurrBlock = LastCondBlock; bool EverChanged = false; - while (1) { + for (;CurrBlock != FirstCondBlock; + CurrBlock = CurrBlock->getSinglePredecessor()) { BranchInst *BI = dyn_cast(CurrBlock->getTerminator()); CmpInst *CI = dyn_cast(BI->getCondition()); + if (!CI) + continue; + CmpInst::Predicate Predicate = CI->getPredicate(); // Canonicalize icmp_ne -> icmp_eq, fcmp_one -> fcmp_oeq if ((Predicate == CmpInst::ICMP_NE) || (Predicate == CmpInst::FCMP_ONE)) { @@ -248,9 +252,6 @@ bool FlattenCFGOpt::FlattenParallelAndOr(BasicBlock *BB, IRBuilder<> &Builder, BI->swapSuccessors(); EverChanged = true; } - if (CurrBlock == FirstCondBlock) - break; - CurrBlock = CurrBlock->getSinglePredecessor(); } return EverChanged; } diff --git a/test/Transforms/Util/flattencfg.ll b/test/Transforms/Util/flattencfg.ll new file mode 100644 index 00000000000..4fcb77ab023 --- /dev/null +++ b/test/Transforms/Util/flattencfg.ll @@ -0,0 +1,26 @@ +; RUN: opt -flattencfg -S < %s | FileCheck %s + + +; This test checks whether the pass completes without a crash. +; The code is not transformed in any way +; +; CHECK-LABEL: @test_not_crash +define void @test_not_crash(i32 %in_a) #0 { +entry: + %cmp0 = icmp eq i32 %in_a, -1 + %cmp1 = icmp ne i32 %in_a, 0 + %cond0 = and i1 %cmp0, %cmp1 + br i1 %cond0, label %b0, label %b1 + +b0: ; preds = %entry + %cmp2 = icmp eq i32 %in_a, 0 + %cmp3 = icmp ne i32 %in_a, 1 + %cond1 = or i1 %cmp2, %cmp3 + br i1 %cond1, label %exit, label %b1 + +b1: ; preds = %entry, %b0 + br label %exit + +exit: ; preds = %entry, %b0, %b1 + ret void +}