summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorChris Lattner <sabre@nondot.org>2010-01-02 00:00:03 +0000
committerChris Lattner <sabre@nondot.org>2010-01-02 00:00:03 +0000
commit133ce871df8bc161928970216ff9b195b1fa3a14 (patch)
tree41664edfae4616e1a6820e6518b13a0a693d0e09
parentaac00392c38a7ce6b66fd8e39ae6bfe67b46dcf9 (diff)
downloadllvm-133ce871df8bc161928970216ff9b195b1fa3a14.tar.gz
llvm-133ce871df8bc161928970216ff9b195b1fa3a14.tar.bz2
llvm-133ce871df8bc161928970216ff9b195b1fa3a14.tar.xz
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
-rw-r--r--lib/CodeGen/SelectionDAG/SelectionDAGBuilder.cpp12
-rw-r--r--test/CodeGen/X86/brcond.ll44
2 files changed, 54 insertions, 2 deletions
diff --git a/lib/CodeGen/SelectionDAG/SelectionDAGBuilder.cpp b/lib/CodeGen/SelectionDAG/SelectionDAGBuilder.cpp
index 74d624f364..40eb9eeb82 100644
--- a/lib/CodeGen/SelectionDAG/SelectionDAGBuilder.cpp
+++ b/lib/CodeGen/SelectionDAG/SelectionDAGBuilder.cpp
@@ -1195,6 +1195,18 @@ SelectionDAGBuilder::ShouldEmitAsBranches(const std::vector<CaseBlock> &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<Constant>(Cases[0].CmpRHS) &&
+ cast<Constant>(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 12674e91a0..c0ce31c270 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 ; <i1> [#uses=1]
+ %b = icmp eq i32* %Q, null ; <i1> [#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 ; <i1> [#uses=1]
+ %b = icmp ne i32* %Q, null ; <i1> [#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
+}