<html><head><meta http-equiv="Content-Type" content="text/html charset=utf-8"></head><body style="word-wrap: break-word; -webkit-nbsp-mode: space; -webkit-line-break: after-white-space;" class="">Hi Renato, Evgeny,<div class=""><br class=""></div><div class="">could you send me a test case? It seems that bot did not test with my fix:</div><div class=""><br class=""></div><div class=""><blockquote type="cite" class="">It's also failing out test-suite bots:<br class=""><br class=""><a href="http://lab.llvm.org:8011/builders/clang-native-arm-lnt/builds/8518" class="">http://lab.llvm.org:8011/builders/clang-native-arm-lnt/builds/8518</a></blockquote><div class=""><br class=""></div><div class="">Thanks,</div><div class="">Gerolf</div><br class=""><div><blockquote type="cite" class=""><div class="">On Oct 1, 2014, at 2:57 AM, Renato Golin <<a href="mailto:renato.golin@linaro.org" class="">renato.golin@linaro.org</a>> wrote:</div><br class="Apple-interchange-newline"><div class="">Hi Gerolf,<br class=""><br class="">This commit actually broke our self-hosting bot (and hasn't been fixed<br class="">by the commit you mentioned):<br class=""><br class=""><a href="http://lab.llvm.org:8011/builders/clang-cmake-armv7-a15-selfhost/builds/470" class="">http://lab.llvm.org:8011/builders/clang-cmake-armv7-a15-selfhost/builds/470</a><br class=""><br class="">It's also failing out test-suite bots:<br class=""><br class="">http://lab.llvm.org:8011/builders/clang-native-arm-lnt/builds/8518<br class=""><br class="">Do you need the case and script? Can you run the test on ARM machine?<br class=""><br class="">Anyhow, if this is going to take a while, maybe reverting the patch so<br class="">our bots can go back to green would be appreciated.<br class=""><br class="">cheers,<br class="">--renato<br class=""><br class=""><br class="">On 1 October 2014 05:16, Chandler Carruth <chandlerc@google.com> wrote:<br class=""><blockquote type="cite" class="">Awesome, thanks!<br class=""><br class="">On Sep 30, 2014 8:37 PM, "Gerolf Hoflehner" <ghoflehner@apple.com> wrote:<br class=""><blockquote type="cite" class=""><br class="">The fix is<br class=""><br class="">Committed revision 218735.<br class=""><br class=""><br class="">On Sep 30, 2014, at 8:30 PM, Chandler Carruth <chandlerc@google.com><br class="">wrote:<br class=""><br class="">It's already been 3 hours. Please do one quickly, I'm worried about the<br class="">number of commits going in after this that aren't getting sanitizer<br class="">coverage.<br class=""><br class="">On Tue, Sep 30, 2014 at 8:21 PM, Gerolf Hoflehner <ghoflehner@apple.com><br class="">wrote:<br class=""><blockquote type="cite" class=""><br class="">Ok, thanks! I’ll provide a fix or back out shortly.<br class=""><br class=""><br class="">On Sep 30, 2014, at 6:13 PM, Chandler Carruth <chandlerc@google.com><br class="">wrote:<br class=""><br class="">FYI, this is assert failing on build bots:<br class="">http://lab.llvm.org:8011/builders/sanitizer-x86_64-linux/builds/13123<br class=""><br class="">On Tue, Sep 30, 2014 at 5:13 PM, Gerolf Hoflehner <ghoflehner@apple.com><br class="">wrote:<br class=""><blockquote type="cite" class=""><br class="">Author: ghoflehner<br class="">Date: Tue Sep 30 19:13:22 2014<br class="">New Revision: 218721<br class=""><br class="">URL: http://llvm.org/viewvc/llvm-project?rev=218721&view=rev<br class="">Log:<br class="">[InstCombine] Optimize icmp-select-icmp<br class=""><br class="">In special cases select instructions can be eliminated by<br class="">replacing them with a cheaper bitwise operation even when the<br class="">select result is used outside its home block. The instances implemented<br class="">are patterns like<br class=""> %x=icmp.eq<br class=""> %y=select %x,%r, null<br class=""> %z=icmp.eq|neq %y, null<br class=""> br %z,true, false<br class="">==> %x=icmp.ne<br class=""> %y=icmp.eq %r,null<br class=""> %z=or %x,%y<br class=""> br %z,true,false<br class="">The optimization is integrated into the instruction<br class="">combiner and performed only when all uses of the select result can<br class="">be replaced by the select operand proper. For this dominator information<br class="">is used and dominance is now a required analysis pass in the combiner.<br class="">The optimization itself is iterative. The critical step is to replace<br class="">the<br class="">select result with the non-constant select operand. So the select<br class="">becomes<br class="">local and the combiner iteratively works out simpler code pattern and<br class="">eventually eliminates the select.<br class=""><br class="">rdar://17853760<br class=""><br class=""><br class="">Added:<br class=""> llvm/trunk/test/Transforms/InstCombine/select-cmp-br.ll<br class="">Modified:<br class=""> llvm/trunk/lib/Transforms/InstCombine/InstCombine.h<br class=""> llvm/trunk/lib/Transforms/InstCombine/InstCombineCompares.cpp<br class=""> llvm/trunk/lib/Transforms/InstCombine/InstructionCombining.cpp<br class=""> llvm/trunk/test/Transforms/InstCombine/pr12338.ll<br class=""><br class="">Modified: llvm/trunk/lib/Transforms/InstCombine/InstCombine.h<br class="">URL:<br class="">http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/Transforms/InstCombine/InstCombine.h?rev=218721&r1=218720&r2=218721&view=diff<br class=""><br class="">==============================================================================<br class="">--- llvm/trunk/lib/Transforms/InstCombine/InstCombine.h (original)<br class="">+++ llvm/trunk/lib/Transforms/InstCombine/InstCombine.h Tue Sep 30<br class="">19:13:22 2014<br class="">@@ -14,6 +14,7 @@<br class=""> #include "llvm/Analysis/AssumptionTracker.h"<br class=""> #include "llvm/Analysis/TargetFolder.h"<br class=""> #include "llvm/Analysis/ValueTracking.h"<br class="">+#include "llvm/IR/Dominators.h"<br class=""> #include "llvm/IR/IRBuilder.h"<br class=""> #include "llvm/IR/InstVisitor.h"<br class=""> #include "llvm/IR/IntrinsicInst.h"<br class="">@@ -98,7 +99,7 @@ class LLVM_LIBRARY_VISIBILITY InstCombin<br class=""> AssumptionTracker *AT;<br class=""> const DataLayout *DL;<br class=""> TargetLibraryInfo *TLI;<br class="">- DominatorTree *DT; // not required<br class="">+ DominatorTree *DT;<br class=""> bool MadeIRChange;<br class=""> LibCallSimplifier *Simplifier;<br class=""> bool MinimizeSize;<br class="">@@ -113,7 +114,8 @@ public:<br class=""> BuilderTy *Builder;<br class=""><br class=""> static char ID; // Pass identification, replacement for typeid<br class="">- InstCombiner() : FunctionPass(ID), DL(nullptr), Builder(nullptr) {<br class="">+ InstCombiner()<br class="">+ : FunctionPass(ID), DL(nullptr), DT(nullptr), Builder(nullptr) {<br class=""> MinimizeSize = false;<br class=""> initializeInstCombinerPass(*PassRegistry::getPassRegistry());<br class=""> }<br class="">@@ -242,6 +244,11 @@ public:<br class=""><br class=""> // visitInstruction - Specify what to return for unhandled<br class="">instructions...<br class=""> Instruction *visitInstruction(Instruction &I) { return nullptr; }<br class="">+ bool dominatesAllUses(const Instruction *DI, const Instruction *UI,<br class="">+ const BasicBlock *DB) const;<br class="">+ bool replacedSelectWithOperand(SelectInst *SI, const ICmpInst *Icmp,<br class="">+ const ConstantInt *CI1,<br class="">+ const ConstantInt *CI2);<br class=""><br class=""> private:<br class=""> bool ShouldChangeType(Type *From, Type *To) const;<br class=""><br class="">Modified: llvm/trunk/lib/Transforms/InstCombine/InstCombineCompares.cpp<br class="">URL:<br class="">http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/Transforms/InstCombine/InstCombineCompares.cpp?rev=218721&r1=218720&r2=218721&view=diff<br class=""><br class="">==============================================================================<br class="">--- llvm/trunk/lib/Transforms/InstCombine/InstCombineCompares.cpp<br class="">(original)<br class="">+++ llvm/trunk/lib/Transforms/InstCombine/InstCombineCompares.cpp Tue<br class="">Sep 30 19:13:22 2014<br class="">@@ -2429,6 +2429,127 @@ static bool swapMayExposeCSEOpportunitie<br class=""> return GlobalSwapBenefits > 0;<br class=""> }<br class=""><br class="">+/// \brief Check that one use is in the same block as the definition<br class="">and all<br class="">+/// other uses are in blocks dominated by a given block<br class="">+///<br class="">+/// \param DI Definition<br class="">+/// \param UI Use<br class="">+/// \param DB Block that must dominate all uses of \p DI outside<br class="">+/// the parent block. Note there can be a use of \p DI in \p<br class="">DB.<br class="">+/// \return true when \p UI is the only use of \p DI in the parent<br class="">block<br class="">+/// and all other uses of \p DI are in blocks dominated by \p DB.<br class="">+///<br class="">+bool InstCombiner::dominatesAllUses(const Instruction *DI,<br class="">+ const Instruction *UI,<br class="">+ const BasicBlock *DB) const {<br class="">+ assert(DI && DI->getParent() == UI->getParent() &&<br class="">+ "definition and use must be in the same block");<br class="">+ // DominatorTree available?<br class="">+ if (!DT)<br class="">+ return false;<br class="">+ for (const User *U : DI->users()) {<br class="">+ auto *Usr = cast<Instruction>(U);<br class="">+ if (Usr != UI && !DT->dominates(DB, Usr->getParent()))<br class="">+ return false;<br class="">+ }<br class="">+ return true;<br class="">+}<br class="">+<br class="">+///<br class="">+/// true when the instruction sequence within a block is select-cmp-br.<br class="">+///<br class="">+static bool isChainSelectCmpBranch(const SelectInst *SI) {<br class="">+ const BasicBlock *BB = SI->getParent();<br class="">+ if (!BB)<br class="">+ return false;<br class="">+ auto *BI = dyn_cast_or_null<BranchInst>(BB->getTerminator());<br class="">+ if (!BI || BI->getNumSuccessors() != 2)<br class="">+ return false;<br class="">+ auto *IC = dyn_cast<ICmpInst>(BI->getCondition());<br class="">+ if (!IC || (IC->getOperand(0) != SI && IC->getOperand(1) != SI))<br class="">+ return false;<br class="">+ return true;<br class="">+}<br class="">+<br class="">+///<br class="">+/// \brief True when a select result is replaced by one of its operands<br class="">+/// in select-icmp sequence. This will eventually result in the<br class="">elimination<br class="">+/// of the select.<br class="">+///<br class="">+/// \param SI Select instruction<br class="">+/// \param Icmp Compare instruction<br class="">+/// \param CI1 'true' when first select operand is equal to RHSC of<br class="">Icmp<br class="">+/// \param CI2 'true' when second select operand is equal to RHSC of<br class="">Icmp<br class="">+///<br class="">+/// Notes:<br class="">+/// - The replacement is global and requires dominator information<br class="">+/// - The caller is responsible for the actual replacement<br class="">+///<br class="">+/// Example:<br class="">+///<br class="">+/// entry:<br class="">+/// %4 = select i1 %3, %C* %0, %C* null<br class="">+/// %5 = icmp eq %C* %4, null<br class="">+/// br i1 %5, label %9, label %7<br class="">+/// ...<br class="">+/// ; <label>:7 ; preds = %entry<br class="">+/// %8 = getelementptr inbounds %C* %4, i64 0, i32 0<br class="">+/// ...<br class="">+///<br class="">+/// can be transformed to<br class="">+///<br class="">+/// %5 = icmp eq %C* %0, null<br class="">+/// %6 = select i1 %3, i1 %5, i1 true<br class="">+/// br i1 %6, label %9, label %7<br class="">+/// ...<br class="">+/// ; <label>:7 ; preds = %entry<br class="">+/// %8 = getelementptr inbounds %C* %0, i64 0, i32 0 // replace by<br class="">%0!<br class="">+///<br class="">+/// Similar when the first operand of the select is a constant or/and<br class="">+/// the compare is for not equal rather than equal.<br class="">+///<br class="">+/// FIXME: Currently the function considers equal compares only. It<br class="">should be<br class="">+/// possbile to extend it to not equal compares also.<br class="">+///<br class="">+bool InstCombiner::replacedSelectWithOperand(SelectInst *SI,<br class="">+ const ICmpInst *Icmp,<br class="">+ const ConstantInt *CI1,<br class="">+ const ConstantInt *CI2) {<br class="">+ if (isChainSelectCmpBranch(SI) && Icmp->isEquality()) {<br class="">+ // Code sequence is select - icmp.[eq|ne] - br<br class="">+ unsigned ReplaceWithOpd = 0;<br class="">+ if (CI1 && !CI1->isZero())<br class="">+ // The first constant operand of the select and the RHS of<br class="">+ // the compare match, so try to substitute<br class="">+ // the select results with its second operand<br class="">+ // Example:<br class="">+ // %4 = select i1 %3, %C* null, %C* %0<br class="">+ // %5 = icmp eq %C* %4, null<br class="">+ // ==> could replace select with second operand<br class="">+ ReplaceWithOpd = 2;<br class="">+ else if (CI2 && !CI2->isZero())<br class="">+ // Similar when the second operand of the select is a constant<br class="">+ // Example:<br class="">+ // %4 = select i1 %3, %C* %0, %C* null<br class="">+ // %5 = icmp eq %C* %4, null<br class="">+ // ==> could replace select with first operand<br class="">+ ReplaceWithOpd = 1;<br class="">+ if (ReplaceWithOpd) {<br class="">+ // Replace select with operand on else path for EQ compares.<br class="">+ // Replace select with operand on then path for NE compares.<br class="">+ BasicBlock *Succ =<br class="">+ Icmp->getPredicate() == ICmpInst::ICMP_EQ<br class="">+ ? SI->getParent()->getTerminator()->getSuccessor(1)<br class="">+ : SI->getParent()->getTerminator()->getSuccessor(0);<br class="">+ if (InstCombiner::dominatesAllUses(SI, Icmp, Succ)) {<br class="">+ SI->replaceAllUsesWith(SI->getOperand(ReplaceWithOpd));<br class="">+ return true;<br class="">+ }<br class="">+ }<br class="">+ }<br class="">+ return false;<br class="">+}<br class="">+<br class=""> Instruction *InstCombiner::visitICmpInst(ICmpInst &I) {<br class=""> bool Changed = false;<br class=""> Value *Op0 = I.getOperand(0), *Op1 = I.getOperand(1);<br class="">@@ -2885,8 +3006,21 @@ Instruction *InstCombiner::visitICmpInst<br class=""> // fold to a constant (in which case the icmp is replaced with<br class="">a select<br class=""> // which will usually simplify) or this is the only user of the<br class=""> // select (in which case we are trading a select+icmp for a<br class="">simpler<br class="">- // select+icmp).<br class="">- if ((Op1 && Op2) || (LHSI->hasOneUse() && (Op1 || Op2))) {<br class="">+ // select+icmp) or all uses of the select can be replaced based<br class="">on<br class="">+ // dominance information ("Global cases").<br class="">+ bool Transform = false;<br class="">+ if (Op1 && Op2)<br class="">+ Transform = true;<br class="">+ else if (Op1 || Op2) {<br class="">+ if (LHSI->hasOneUse())<br class="">+ Transform = true;<br class="">+ else<br class="">+ // Global cases<br class="">+ Transform = replacedSelectWithOperand(<br class="">+ cast<SelectInst>(LHSI), &I,<br class="">dyn_cast_or_null<ConstantInt>(Op1),<br class="">+ dyn_cast_or_null<ConstantInt>(Op2));<br class="">+ }<br class="">+ if (Transform) {<br class=""> if (!Op1)<br class=""> Op1 = Builder->CreateICmp(I.getPredicate(),<br class="">LHSI->getOperand(1),<br class=""> RHSC, I.getName());<br class=""><br class="">Modified: llvm/trunk/lib/Transforms/InstCombine/InstructionCombining.cpp<br class="">URL:<br class="">http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/Transforms/InstCombine/InstructionCombining.cpp?rev=218721&r1=218720&r2=218721&view=diff<br class=""><br class="">==============================================================================<br class="">--- llvm/trunk/lib/Transforms/InstCombine/InstructionCombining.cpp<br class="">(original)<br class="">+++ llvm/trunk/lib/Transforms/InstCombine/InstructionCombining.cpp Tue<br class="">Sep 30 19:13:22 2014<br class="">@@ -90,6 +90,7 @@ INITIALIZE_PASS_BEGIN(InstCombiner, "ins<br class=""> "Combine redundant instructions", false, false)<br class=""> INITIALIZE_PASS_DEPENDENCY(AssumptionTracker)<br class=""> INITIALIZE_PASS_DEPENDENCY(TargetLibraryInfo)<br class="">+INITIALIZE_PASS_DEPENDENCY(DominatorTreeWrapperPass)<br class=""> INITIALIZE_PASS_END(InstCombiner, "instcombine",<br class=""> "Combine redundant instructions", false, false)<br class=""><br class="">@@ -97,6 +98,8 @@ void InstCombiner::getAnalysisUsage(Anal<br class=""> AU.setPreservesCFG();<br class=""> AU.addRequired<AssumptionTracker>();<br class=""> AU.addRequired<TargetLibraryInfo>();<br class="">+ AU.addRequired<DominatorTreeWrapperPass>();<br class="">+ AU.addPreserved<DominatorTreeWrapperPass>();<br class=""> }<br class=""><br class=""><br class="">@@ -2933,12 +2936,9 @@ bool InstCombiner::runOnFunction(Functio<br class=""> AT = &getAnalysis<AssumptionTracker>();<br class=""> DataLayoutPass *DLP = getAnalysisIfAvailable<DataLayoutPass>();<br class=""> DL = DLP ? &DLP->getDataLayout() : nullptr;<br class="">+ DT = &getAnalysis<DominatorTreeWrapperPass>().getDomTree();<br class=""> TLI = &getAnalysis<TargetLibraryInfo>();<br class=""><br class="">- DominatorTreeWrapperPass *DTWP =<br class="">- getAnalysisIfAvailable<DominatorTreeWrapperPass>();<br class="">- DT = DTWP ? &DTWP->getDomTree() : nullptr;<br class="">-<br class=""> // Minimizing size?<br class=""> MinimizeSize =<br class="">F.getAttributes().hasAttribute(AttributeSet::FunctionIndex,<br class=""> Attribute::MinSize);<br class=""><br class="">Modified: llvm/trunk/test/Transforms/InstCombine/pr12338.ll<br class="">URL:<br class="">http://llvm.org/viewvc/llvm-project/llvm/trunk/test/Transforms/InstCombine/pr12338.ll?rev=218721&r1=218720&r2=218721&view=diff<br class=""><br class="">==============================================================================<br class="">--- llvm/trunk/test/Transforms/InstCombine/pr12338.ll (original)<br class="">+++ llvm/trunk/test/Transforms/InstCombine/pr12338.ll Tue Sep 30<br class="">19:13:22 2014<br class="">@@ -2,11 +2,11 @@<br class=""><br class=""> define void @entry() nounwind {<br class=""> entry:<br class="">+; CHECK: br label %for.cond<br class=""> br label %for.cond<br class=""><br class=""> for.cond:<br class=""> %local = phi <1 x i32> [ <i32 0>, %entry ], [ %phi2, %cond.end47 ]<br class="">-; CHECK: sub <1 x i32> <i32 92>, %local<br class=""> %phi3 = sub <1 x i32> zeroinitializer, %local<br class=""> br label %cond.end<br class=""><br class=""><br class="">Added: llvm/trunk/test/Transforms/InstCombine/select-cmp-br.ll<br class="">URL:<br class="">http://llvm.org/viewvc/llvm-project/llvm/trunk/test/Transforms/InstCombine/select-cmp-br.ll?rev=218721&view=auto<br class=""><br class="">==============================================================================<br class="">--- llvm/trunk/test/Transforms/InstCombine/select-cmp-br.ll (added)<br class="">+++ llvm/trunk/test/Transforms/InstCombine/select-cmp-br.ll Tue Sep 30<br class="">19:13:22 2014<br class="">@@ -0,0 +1,127 @@<br class="">+; Replace a 'select' with 'or' in 'select - cmp [eq|ne] - br' sequence<br class="">+; RUN: opt -instcombine -S < %s | FileCheck %s<br class="">+<br class="">+%C = type <{ %struct.S }><br class="">+%struct.S = type { i64*, i32, i32 }<br class="">+<br class="">+declare void @bar(%struct.S *) #1<br class="">+<br class="">+define void @test1(%C*) {<br class="">+entry:<br class="">+ %1 = getelementptr inbounds %C* %0, i64 0, i32 0, i32 0<br class="">+ %m = load i64** %1, align 8<br class="">+ %2 = getelementptr inbounds %C* %0, i64 1, i32 0, i32 0<br class="">+ %n = load i64** %2, align 8<br class="">+ %3 = getelementptr inbounds i64* %m, i64 9<br class="">+ %4 = bitcast i64* %3 to i64 (%C*)**<br class="">+ %5 = load i64 (%C*)** %4, align 8<br class="">+ %6 = icmp eq i64* %m, %n<br class="">+ %7 = select i1 %6, %C* %0, %C* null<br class="">+ %8 = icmp eq %C* %7, null<br class="">+ br i1 %8, label %12, label %10<br class="">+<br class="">+; <label>:9 ; preds = %10, %12<br class="">+ ret void<br class="">+<br class="">+; <label>:10 ; preds = %entry<br class="">+ %11 = getelementptr inbounds %C* %7, i64 0, i32 0<br class="">+ tail call void @bar(%struct.S* %11)<br class="">+ br label %9<br class="">+<br class="">+; <label>:12 ; preds = %entry<br class="">+ %13 = tail call i64 %5(%C* %0)<br class="">+ br label %9<br class="">+; CHECK-LABEL: @test1(<br class="">+; CHECK-NOT: select<br class="">+; CHECK: or<br class="">+}<br class="">+<br class="">+define void @test2(%C*) {<br class="">+entry:<br class="">+ %1 = getelementptr inbounds %C* %0, i64 0, i32 0, i32 0<br class="">+ %m = load i64** %1, align 8<br class="">+ %2 = getelementptr inbounds %C* %0, i64 1, i32 0, i32 0<br class="">+ %n = load i64** %2, align 8<br class="">+ %3 = getelementptr inbounds i64* %m, i64 9<br class="">+ %4 = bitcast i64* %3 to i64 (%C*)**<br class="">+ %5 = load i64 (%C*)** %4, align 8<br class="">+ %6 = icmp eq i64* %m, %n<br class="">+ %7 = select i1 %6, %C* null, %C* %0<br class="">+ %8 = icmp eq %C* %7, null<br class="">+ br i1 %8, label %12, label %10<br class="">+<br class="">+; <label>:9 ; preds = %10, %12<br class="">+ ret void<br class="">+<br class="">+; <label>:10 ; preds = %entry<br class="">+ %11 = getelementptr inbounds %C* %7, i64 0, i32 0<br class="">+ tail call void @bar(%struct.S* %11)<br class="">+ br label %9<br class="">+<br class="">+; <label>:12 ; preds = %entry<br class="">+ %13 = tail call i64 %5(%C* %0)<br class="">+ br label %9<br class="">+; CHECK-LABEL: @test2(<br class="">+; CHECK-NOT: select<br class="">+; CHECK: or<br class="">+}<br class="">+<br class="">+define void @test3(%C*) {<br class="">+entry:<br class="">+ %1 = getelementptr inbounds %C* %0, i64 0, i32 0, i32 0<br class="">+ %m = load i64** %1, align 8<br class="">+ %2 = getelementptr inbounds %C* %0, i64 1, i32 0, i32 0<br class="">+ %n = load i64** %2, align 8<br class="">+ %3 = getelementptr inbounds i64* %m, i64 9<br class="">+ %4 = bitcast i64* %3 to i64 (%C*)**<br class="">+ %5 = load i64 (%C*)** %4, align 8<br class="">+ %6 = icmp eq i64* %m, %n<br class="">+ %7 = select i1 %6, %C* %0, %C* null<br class="">+ %8 = icmp ne %C* %7, null<br class="">+ br i1 %8, label %10, label %12<br class="">+<br class="">+; <label>:9 ; preds = %10, %12<br class="">+ ret void<br class="">+<br class="">+; <label>:10 ; preds = %entry<br class="">+ %11 = getelementptr inbounds %C* %7, i64 0, i32 0<br class="">+ tail call void @bar(%struct.S* %11)<br class="">+ br label %9<br class="">+<br class="">+; <label>:12 ; preds = %entry<br class="">+ %13 = tail call i64 %5(%C* %0)<br class="">+ br label %9<br class="">+; CHECK-LABEL: @test3(<br class="">+; CHECK-NOT: select<br class="">+; CHECK: or<br class="">+}<br class="">+<br class="">+define void @test4(%C*) {<br class="">+entry:<br class="">+ %1 = getelementptr inbounds %C* %0, i64 0, i32 0, i32 0<br class="">+ %m = load i64** %1, align 8<br class="">+ %2 = getelementptr inbounds %C* %0, i64 1, i32 0, i32 0<br class="">+ %n = load i64** %2, align 8<br class="">+ %3 = getelementptr inbounds i64* %m, i64 9<br class="">+ %4 = bitcast i64* %3 to i64 (%C*)**<br class="">+ %5 = load i64 (%C*)** %4, align 8<br class="">+ %6 = icmp eq i64* %m, %n<br class="">+ %7 = select i1 %6, %C* null, %C* %0<br class="">+ %8 = icmp ne %C* %7, null<br class="">+ br i1 %8, label %10, label %12<br class="">+<br class="">+; <label>:9 ; preds = %10, %12<br class="">+ ret void<br class="">+<br class="">+; <label>:10 ; preds = %entry<br class="">+ %11 = getelementptr inbounds %C* %7, i64 0, i32 0<br class="">+ tail call void @bar(%struct.S* %11)<br class="">+ br label %9<br class="">+<br class="">+; <label>:12 ; preds = %entry<br class="">+ %13 = tail call i64 %5(%C* %0)<br class="">+ br label %9<br class="">+; CHECK-LABEL: @test4(<br class="">+; CHECK-NOT: select<br class="">+; CHECK: or<br class="">+}<br class=""><br class=""><br class="">_______________________________________________<br class="">llvm-commits mailing list<br class="">llvm-commits@cs.uiuc.edu<br class="">http://lists.cs.uiuc.edu/mailman/listinfo/llvm-commits<br class=""></blockquote><br class=""><br class=""><br class=""></blockquote><br class=""><br class=""></blockquote><br class="">_______________________________________________<br class="">llvm-commits mailing list<br class="">llvm-commits@cs.uiuc.edu<br class="">http://lists.cs.uiuc.edu/mailman/listinfo/llvm-commits<br class=""><br class=""></blockquote></div></blockquote></div><br class=""></div></body></html>