<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="">Ok, thanks! I’ll provide a fix or back out shortly.<div class=""><br class=""><div class=""><br class=""><div><blockquote type="cite" class=""><div class="">On Sep 30, 2014, at 6:13 PM, Chandler Carruth <<a href="mailto:chandlerc@google.com" class="">chandlerc@google.com</a>> wrote:</div><br class="Apple-interchange-newline"><div class=""><div dir="ltr" class="">FYI, this is assert failing on build bots: <a href="http://lab.llvm.org:8011/builders/sanitizer-x86_64-linux/builds/13123" class="">http://lab.llvm.org:8011/builders/sanitizer-x86_64-linux/builds/13123</a></div><div class="gmail_extra"><br class=""><div class="gmail_quote">On Tue, Sep 30, 2014 at 5:13 PM, Gerolf Hoflehner <span dir="ltr" class=""><<a href="mailto:ghoflehner@apple.com" target="_blank" class="">ghoflehner@apple.com</a>></span> wrote:<br class=""><blockquote class="gmail_quote" style="margin:0 0 0 .8ex;border-left:1px #ccc solid;padding-left:1ex">Author: ghoflehner<br class="">
Date: Tue Sep 30 19:13:22 2014<br class="">
New Revision: 218721<br class="">
<br class="">
URL: <a href="http://llvm.org/viewvc/llvm-project?rev=218721&view=rev" target="_blank" class="">http://llvm.org/viewvc/llvm-project?rev=218721&view=rev</a><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=<a href="http://icmp.ne/" target="_blank" class="">icmp.ne</a><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 the<br class="">
select result with the non-constant select operand. So the select becomes<br class="">
local and the combiner iteratively works out simpler code pattern and<br class="">
eventually eliminates the select.<br class="">
<br class="">
<a href="rdar://17853760" class="">rdar://17853760</a><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: <a href="http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/Transforms/InstCombine/InstCombine.h?rev=218721&r1=218720&r2=218721&view=diff" target="_blank" class="">http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/Transforms/InstCombine/InstCombine.h?rev=218721&r1=218720&r2=218721&view=diff</a><br class="">
==============================================================================<br class="">
--- llvm/trunk/lib/Transforms/InstCombine/InstCombine.h (original)<br class="">
+++ llvm/trunk/lib/Transforms/InstCombine/InstCombine.h Tue Sep 30 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 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: <a href="http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/Transforms/InstCombine/InstCombineCompares.cpp?rev=218721&r1=218720&r2=218721&view=diff" target="_blank" class="">http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/Transforms/InstCombine/InstCombineCompares.cpp?rev=218721&r1=218720&r2=218721&view=diff</a><br class="">
==============================================================================<br class="">
--- llvm/trunk/lib/Transforms/InstCombine/InstCombineCompares.cpp (original)<br class="">
+++ llvm/trunk/lib/Transforms/InstCombine/InstCombineCompares.cpp Tue 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 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 DB.<br class="">
+/// \return true when \p UI is the only use of \p DI in the parent 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 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 Icmp<br class="">
+/// \param CI2  'true' when second select operand is equal to RHSC of 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 %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 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 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 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 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, 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(), LHSI->getOperand(1),<br class="">
                                       RHSC, I.getName());<br class="">
<br class="">
Modified: llvm/trunk/lib/Transforms/InstCombine/InstructionCombining.cpp<br class="">
URL: <a href="http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/Transforms/InstCombine/InstructionCombining.cpp?rev=218721&r1=218720&r2=218721&view=diff" target="_blank" class="">http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/Transforms/InstCombine/InstructionCombining.cpp?rev=218721&r1=218720&r2=218721&view=diff</a><br class="">
==============================================================================<br class="">
--- llvm/trunk/lib/Transforms/InstCombine/InstructionCombining.cpp (original)<br class="">
+++ llvm/trunk/lib/Transforms/InstCombine/InstructionCombining.cpp Tue 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 = F.getAttributes().hasAttribute(AttributeSet::FunctionIndex,<br class="">
                                                 Attribute::MinSize);<br class="">
<br class="">
Modified: llvm/trunk/test/Transforms/InstCombine/pr12338.ll<br class="">
URL: <a href="http://llvm.org/viewvc/llvm-project/llvm/trunk/test/Transforms/InstCombine/pr12338.ll?rev=218721&r1=218720&r2=218721&view=diff" target="_blank" class="">http://llvm.org/viewvc/llvm-project/llvm/trunk/test/Transforms/InstCombine/pr12338.ll?rev=218721&r1=218720&r2=218721&view=diff</a><br class="">
==============================================================================<br class="">
--- llvm/trunk/test/Transforms/InstCombine/pr12338.ll (original)<br class="">
+++ llvm/trunk/test/Transforms/InstCombine/pr12338.ll Tue Sep 30 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: <a href="http://llvm.org/viewvc/llvm-project/llvm/trunk/test/Transforms/InstCombine/select-cmp-br.ll?rev=218721&view=auto" target="_blank" class="">http://llvm.org/viewvc/llvm-project/llvm/trunk/test/Transforms/InstCombine/select-cmp-br.ll?rev=218721&view=auto</a><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 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="">
<a href="mailto:llvm-commits@cs.uiuc.edu" class="">llvm-commits@cs.uiuc.edu</a><br class="">
<a href="http://lists.cs.uiuc.edu/mailman/listinfo/llvm-commits" target="_blank" class="">http://lists.cs.uiuc.edu/mailman/listinfo/llvm-commits</a><br class="">
</blockquote></div><br class=""></div>
</div></blockquote></div><br class=""></div></div></body></html>