[llvm] r181395 - DAGCombiner: Simplify inverted bit tests

David Majnemer david.majnemer at gmail.com
Tue May 7 23:44:43 PDT 2013


Author: majnemer
Date: Wed May  8 01:44:42 2013
New Revision: 181395

URL: http://llvm.org/viewvc/llvm-project?rev=181395&view=rev
Log:
DAGCombiner: Simplify inverted bit tests

Fold (xor (and x, y), y) -> (and (not x), y)

This removes an opportunity for a constant to appear twice.

Modified:
    llvm/trunk/lib/CodeGen/SelectionDAG/DAGCombiner.cpp
    llvm/trunk/test/CodeGen/MSP430/setcc.ll
    llvm/trunk/test/CodeGen/X86/xor.ll

Modified: llvm/trunk/lib/CodeGen/SelectionDAG/DAGCombiner.cpp
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/CodeGen/SelectionDAG/DAGCombiner.cpp?rev=181395&r1=181394&r2=181395&view=diff
==============================================================================
--- llvm/trunk/lib/CodeGen/SelectionDAG/DAGCombiner.cpp (original)
+++ llvm/trunk/lib/CodeGen/SelectionDAG/DAGCombiner.cpp Wed May  8 01:44:42 2013
@@ -3460,6 +3460,15 @@ SDValue DAGCombiner::visitXOR(SDNode *N)
       return DAG.getNode(NewOpcode, N->getDebugLoc(), VT, LHS, RHS);
     }
   }
+  // fold (xor (and x, y), y) -> (and (not x), y)
+  if (N0.getOpcode() == ISD::AND && N0.getNode()->hasOneUse() &&
+      N0->getOperand(1) == N1) {
+    SDValue X = N0->getOperand(0);
+    SDValue NotX = DAG.getNode(ISD::XOR, X.getDebugLoc(), VT, X,
+      DAG.getConstant(APInt::getAllOnesValue(VT.getSizeInBits()), VT));
+    AddToWorkList(NotX.getNode());
+    return DAG.getNode(ISD::AND, N->getDebugLoc(), VT, NotX, N1);
+  }
   // fold (xor (xor x, c1), c2) -> (xor x, (xor c1, c2))
   if (N1C && N0.getOpcode() == ISD::XOR) {
     ConstantSDNode *N00C = dyn_cast<ConstantSDNode>(N0.getOperand(0));

Modified: llvm/trunk/test/CodeGen/MSP430/setcc.ll
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/test/CodeGen/MSP430/setcc.ll?rev=181395&r1=181394&r2=181395&view=diff
==============================================================================
--- llvm/trunk/test/CodeGen/MSP430/setcc.ll (original)
+++ llvm/trunk/test/CodeGen/MSP430/setcc.ll Wed May  8 01:44:42 2013
@@ -32,10 +32,10 @@ define i16 @sccwne(i16 %a, i16 %b) nounw
 }
 ; CHECK:sccwne:
 ; CHECK:	cmp.w	r14, r15
-; CHECK:	mov.w	r2, r15
-; CHECK:	rra.w	r15
-; CHECK:	and.w	#1, r15
-; CHECK:	xor.w   #1, r15
+; CHECK:	mov.w	r2, r12
+; CHECK:	rra.w	r12
+; CHECK:	mov.w	#1, r15
+; CHECK:	bic.w	r12, r15
 
 define i16 @sccweq(i16 %a, i16 %b) nounwind {
 	%t1 = icmp eq i16 %a, %b
@@ -55,9 +55,8 @@ define i16 @sccwugt(i16 %a, i16 %b) noun
 }
 ; CHECK:sccwugt:
 ; CHECK:	cmp.w	r15, r14
-; CHECK:	mov.w	r2, r15
-; CHECK:	and.w	#1, r15
-; CHECK:	xor.w	#1, r15
+; CHECK:	mov.w	#1, r15
+; CHECK:	bic.w	r2, r15
 
 define i16 @sccwuge(i16 %a, i16 %b) nounwind {
 	%t1 = icmp uge i16 %a, %b
@@ -76,9 +75,8 @@ define i16 @sccwult(i16 %a, i16 %b) noun
 }
 ; CHECK:sccwult:
 ; CHECK:	cmp.w	r14, r15
-; CHECK:	mov.w	r2, r15
-; CHECK:	and.w	#1, r15
-; CHECK:	xor.w	#1, r15
+; CHECK:	mov.w	#1, r15
+; CHECK:	bic.w	r2, r15
 
 define i16 @sccwule(i16 %a, i16 %b) nounwind {
 	%t1 = icmp ule i16 %a, %b

Modified: llvm/trunk/test/CodeGen/X86/xor.ll
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/test/CodeGen/X86/xor.ll?rev=181395&r1=181394&r2=181395&view=diff
==============================================================================
--- llvm/trunk/test/CodeGen/X86/xor.ll (original)
+++ llvm/trunk/test/CodeGen/X86/xor.ll Wed May  8 01:44:42 2013
@@ -142,3 +142,15 @@ entry:
 ; X32: test8:
 ; X32:   notl %eax
 }
+
+define i32 @test9(i32 %a) nounwind {
+  %1 = and i32 %a, 4096
+  %2 = xor i32 %1, 4096
+  ret i32 %2
+; X64: test9:
+; X64:    notl	[[REG:%[a-z]+]]
+; X64:    andl	{{.*}}[[REG:%[a-z]+]]
+; X32: test9:
+; X32:    notl	[[REG:%[a-z]+]]
+; X32:    andl	{{.*}}[[REG:%[a-z]+]]
+}





More information about the llvm-commits mailing list