<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>