Index: lib/Transforms/InstCombine/InstructionCombining.cpp =================================================================== --- lib/Transforms/InstCombine/InstructionCombining.cpp +++ lib/Transforms/InstCombine/InstructionCombining.cpp @@ -2392,6 +2392,32 @@ return &BI; } + // Propagate null op from cmp to next basic blocks + if (match(&BI, m_Br(m_OneUse(m_Cmp(Pred, m_Value(), m_Zero())), TrueDest, + FalseDest)) && + isCanonicalPredicate(Pred)) { + auto Cmp = dyn_cast(BI.getOperand(0)); + auto NullOp = Cmp->getOperand(0); + auto B = TrueDest; + bool NullOpReplaced = false; + while (B) { + for (auto &I : *B) { + for (unsigned i = 0; i < I.getNumOperands(); ++i) { + auto Arg = I.getOperand(i); + if (match(Arg, m_Zero()) && NullOp->getType() == Arg->getType()) { + I.setOperand(i, NullOp); + NullOpReplaced |= true; + } + } + } + + B = B->getNextNode(); + } + + if (NullOpReplaced) + return &BI; + } + return nullptr; } Index: test/Transforms/InstCombine/cond-return-null.ll =================================================================== --- /dev/null +++ test/Transforms/InstCombine/cond-return-null.ll @@ -0,0 +1,41 @@ +; RUN: opt < %s -instcombine -S | FileCheck %s + +@.str = private unnamed_addr constant [1 x i8] zeroinitializer, align 1 + +define i8* @propagate_null(i8* %ptr) #0 { +; CHECK-LABEL: @propagate_null( +; CHECK-NEXT: entry: +; CHECK-NEXT: [[TOBOOL:%.*]] = icmp eq i8* [[PTR:%.*]], null +; CHECK-NEXT: br i1 [[TOBOOL]], label [[IF_THEN:%.*]], label [[IF_END:%.*]] +; CHECK: if.then: +; CHECK-NEXT: br label [[RETURN:%.*]] +; CHECK: if.end: +; CHECK-NEXT: [[PUTCHAR:%.*]] = call i32 @putchar(i32 10) +; CHECK-NEXT: br label [[RETURN]] +; CHECK: return: +; CHECK-NEXT: [[STOREMERGE:%.*]] = phi i8* [ [[PTR]], [[IF_END]] ], [ null, [[IF_THEN]] ] +; CHECK-NEXT: ret i8* [[STOREMERGE]] +; + + + +entry: + %retval = alloca i8*, align 4 + %tobool = icmp ne i8* %ptr, null + br i1 %tobool, label %if.end, label %if.then + +if.then: ; preds = %entry + store i8* null, i8** %retval, align 4 + br label %return + +if.end: ; preds = %entry + %call = call i32 @puts(i8* getelementptr inbounds ([1 x i8], [1 x i8]* @.str, i32 0, i32 0)) + store i8* %ptr, i8** %retval, align 4 + br label %return + +return: ; preds = %if.end, %if.then + %0 = load i8*, i8** %retval, align 4 + ret i8* %0 +} + +declare i32 @puts(i8*) #1