From a9f6bbea62f42ab052eca423588e309ab67c3fa3 Mon Sep 17 00:00:00 2001 From: Chris Lattner Date: Mon, 13 Dec 2010 08:12:19 +0000 Subject: [PATCH] reinstate my patch: the miscompile was caused by an inverted branch in the 'and' case. git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@121695 91177308-0d34-0410-b5e6-96231b3b80d8 --- lib/Transforms/Utils/SimplifyCFG.cpp | 9 ++- test/Transforms/SimplifyCFG/switch_create.ll | 75 +++++++++++++------- 2 files changed, 54 insertions(+), 30 deletions(-) diff --git a/lib/Transforms/Utils/SimplifyCFG.cpp b/lib/Transforms/Utils/SimplifyCFG.cpp index d7a6ea4655a..71d9ef84832 100644 --- a/lib/Transforms/Utils/SimplifyCFG.cpp +++ b/lib/Transforms/Utils/SimplifyCFG.cpp @@ -1909,13 +1909,15 @@ static bool SimplifyBranchOnICmpChain(BranchInst *BI, const TargetData *TD) { // then we evaluate them with an explicit branch first. Split the block // right before the condbr to handle it. if (ExtraCase) { - return false; - BasicBlock *NewBB = BB->splitBasicBlock(BI, "switch.early.test"); // Remove the uncond branch added to the old block. TerminatorInst *OldTI = BB->getTerminator(); - BranchInst::Create(EdgeBB, NewBB, ExtraCase, OldTI); + if (TrueWhenEqual) + BranchInst::Create(EdgeBB, NewBB, ExtraCase, OldTI); + else + BranchInst::Create(NewBB, EdgeBB, ExtraCase, OldTI); + OldTI->eraseFromParent(); // If there are PHI nodes in EdgeBB, then we need to add a new entry to them @@ -1955,6 +1957,7 @@ static bool SimplifyBranchOnICmpChain(BranchInst *BI, const TargetData *TD) { // Erase the old branch instruction. EraseTerminatorInstAndDCECond(BI); + return true; } diff --git a/test/Transforms/SimplifyCFG/switch_create.ll b/test/Transforms/SimplifyCFG/switch_create.ll index 2f0dc94c08f..5b96c6b16be 100644 --- a/test/Transforms/SimplifyCFG/switch_create.ll +++ b/test/Transforms/SimplifyCFG/switch_create.ll @@ -168,13 +168,13 @@ if.end: ; preds = %entry ret void ; CHECK: @test7 -; HECK: %cmp = icmp ult i32 %x, 32 -; HECK: br i1 %cmp, label %if.then, label %switch.early.test -; HECK: switch.early.test: -; HECK: switch i8 %c, label %if.end [ -; HECK: i8 99, label %if.then -; HECK: i8 97, label %if.then -; HECK: ] +; CHECK: %cmp = icmp ult i32 %x, 32 +; CHECK: br i1 %cmp, label %if.then, label %switch.early.test +; CHECK: switch.early.test: +; CHECK: switch i8 %c, label %if.end [ +; CHECK: i8 99, label %if.then +; CHECK: i8 97, label %if.then +; CHECK: ] } define i32 @test8(i8 zeroext %c, i32 %x, i1 %C) nounwind ssp noredzone { @@ -197,12 +197,12 @@ if.end: ; preds = %entry ret i32 0 ; CHECK: @test8 -; HECK: switch.early.test: -; HECK: switch i8 %c, label %if.end [ -; HECK: i8 99, label %if.then -; HECK: i8 97, label %if.then -; HECK: ] -; HECK: %A = phi i32 [ 0, %entry ], [ 42, %switch.early.test ], [ 42, %N ], [ 42, %switch.early.test ] +; CHECK: switch.early.test: +; CHECK: switch i8 %c, label %if.end [ +; CHECK: i8 99, label %if.then +; CHECK: i8 97, label %if.then +; CHECK: ] +; CHECK: %A = phi i32 [ 0, %entry ], [ 42, %switch.early.test ], [ 42, %N ], [ 42, %switch.early.test ] } ;; This is "Example 7" from http://blog.regehr.org/archives/320 @@ -254,20 +254,41 @@ lor.end: ; preds = %lor.rhs, %lor.lhs.f ; CHECK: @test9 ; CHECK: %cmp = icmp ult i8 %c, 33 -; HECK: br i1 %cmp, label %lor.end, label %switch.early.test - -; HECK: switch.early.test: -; HECK: switch i8 %c, label %lor.rhs [ -; HECK: i8 46, label %lor.end -; HECK: i8 44, label %lor.end -; HECK: i8 58, label %lor.end -; HECK: i8 59, label %lor.end -; HECK: i8 60, label %lor.end -; HECK: i8 62, label %lor.end -; HECK: i8 34, label %lor.end -; HECK: i8 92, label %lor.end -; HECK: i8 39, label %lor.end -; HECK: ] +; CHECK: br i1 %cmp, label %lor.end, label %switch.early.test + +; CHECK: switch.early.test: +; CHECK: switch i8 %c, label %lor.rhs [ +; CHECK: i8 46, label %lor.end +; CHECK: i8 44, label %lor.end +; CHECK: i8 58, label %lor.end +; CHECK: i8 59, label %lor.end +; CHECK: i8 60, label %lor.end +; CHECK: i8 62, label %lor.end +; CHECK: i8 34, label %lor.end +; CHECK: i8 92, label %lor.end +; CHECK: i8 39, label %lor.end +; CHECK: ] } +define i32 @test10(i32 %mode, i1 %Cond) { + %A = icmp ne i32 %mode, 0 + %B = icmp ne i32 %mode, 51 + %C = and i1 %A, %B + %D = and i1 %C, %Cond + br i1 %D, label %T, label %F +T: + ret i32 123 +F: + ret i32 324 + +; CHECK: @test10 +; CHECK: br i1 %Cond, label %switch.early.test, label %F +; CHECK:switch.early.test: +; CHECK: switch i32 %mode, label %T [ +; CHECK: i32 51, label %F +; CHECK: i32 0, label %F +; CHECK: ] +} + + -- 2.34.1