From 133ce871df8bc161928970216ff9b195b1fa3a14 Mon Sep 17 00:00:00 2001 From: Chris Lattner Date: Sat, 2 Jan 2010 00:00:03 +0000 Subject: [PATCH] Teach codegen to handle: (X != null) | (Y != null) --> (X|Y) != 0 (X == null) & (Y == null) --> (X|Y) == 0 so that instcombine can stop doing this for pointers. This is part of PR3351, which is a case where instcombine doing this for pointers (inserting ptrtoint) is pessimizing code. git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@92406 91177308-0d34-0410-b5e6-96231b3b80d8 --- .../SelectionDAG/SelectionDAGBuilder.cpp | 12 +++++ test/CodeGen/X86/brcond.ll | 44 ++++++++++++++++++- 2 files changed, 54 insertions(+), 2 deletions(-) diff --git a/lib/CodeGen/SelectionDAG/SelectionDAGBuilder.cpp b/lib/CodeGen/SelectionDAG/SelectionDAGBuilder.cpp index 74d624f3647..40eb9eeb82a 100644 --- a/lib/CodeGen/SelectionDAG/SelectionDAGBuilder.cpp +++ b/lib/CodeGen/SelectionDAG/SelectionDAGBuilder.cpp @@ -1195,6 +1195,18 @@ SelectionDAGBuilder::ShouldEmitAsBranches(const std::vector &Cases){ return false; } + // Handle: (X != null) | (Y != null) --> (X|Y) != 0 + // Handle: (X == null) & (Y == null) --> (X|Y) == 0 + if (Cases[0].CmpRHS == Cases[1].CmpRHS && + Cases[0].CC == Cases[1].CC && + isa(Cases[0].CmpRHS) && + cast(Cases[0].CmpRHS)->isNullValue()) { + if (Cases[0].CC == ISD::SETEQ && Cases[0].TrueBB == Cases[1].ThisBB) + return false; + if (Cases[0].CC == ISD::SETNE && Cases[0].FalseBB == Cases[1].ThisBB) + return false; + } + return true; } diff --git a/test/CodeGen/X86/brcond.ll b/test/CodeGen/X86/brcond.ll index 12674e91a0b..c0ce31c2709 100644 --- a/test/CodeGen/X86/brcond.ll +++ b/test/CodeGen/X86/brcond.ll @@ -1,9 +1,9 @@ ; RUN: llc < %s -march=x86 | FileCheck %s ; rdar://7475489 -define i32 @t(i32 %a, i32 %b) nounwind ssp { +define i32 @test1(i32 %a, i32 %b) nounwind ssp { entry: -; CHECK: t: +; CHECK: test1: ; CHECK: xorb ; CHECK-NOT: andb ; CHECK-NOT: shrb @@ -27,3 +27,43 @@ bb1: ; preds = %entry declare i32 @foo(...) declare i32 @bar(...) + + + +; PR3351 - (P == 0) & (Q == 0) -> (P|Q) == 0 +define i32 @test2(i32* %P, i32* %Q) nounwind ssp { +entry: + %a = icmp eq i32* %P, null ; [#uses=1] + %b = icmp eq i32* %Q, null ; [#uses=1] + %c = and i1 %a, %b + br i1 %c, label %bb1, label %return + +bb1: ; preds = %entry + ret i32 4 + +return: ; preds = %entry + ret i32 192 +; CHECK: test2: +; CHECK: movl 4(%esp), %eax +; CHECK-NEXT: orl 8(%esp), %eax +; CHECK-NEXT: jne LBB2_2 +} + +; PR3351 - (P != 0) | (Q != 0) -> (P|Q) != 0 +define i32 @test3(i32* %P, i32* %Q) nounwind ssp { +entry: + %a = icmp ne i32* %P, null ; [#uses=1] + %b = icmp ne i32* %Q, null ; [#uses=1] + %c = or i1 %a, %b + br i1 %c, label %bb1, label %return + +bb1: ; preds = %entry + ret i32 4 + +return: ; preds = %entry + ret i32 192 +; CHECK: test3: +; CHECK: movl 4(%esp), %eax +; CHECK-NEXT: orl 8(%esp), %eax +; CHECK-NEXT: je LBB3_2 +}