[llvm] 89afec3 - [X86] Fold xor(truncate(xor(x,c1)),c2) -> xor(truncate(x),xor(truncate(c1),c2))

Simon Pilgrim via llvm-commits llvm-commits at lists.llvm.org
Sat Apr 3 04:43:41 PDT 2021


Author: Simon Pilgrim
Date: 2021-04-03T12:43:05+01:00
New Revision: 89afec348dbd3e5078f176e978971ee2d3b5dec8

URL: https://github.com/llvm/llvm-project/commit/89afec348dbd3e5078f176e978971ee2d3b5dec8
DIFF: https://github.com/llvm/llvm-project/commit/89afec348dbd3e5078f176e978971ee2d3b5dec8.diff

LOG: [X86] Fold xor(truncate(xor(x,c1)),c2) -> xor(truncate(x),xor(truncate(c1),c2))

Fixes PR47603

This should probably be transferable to DAGCombine - the main limitation with the existing trunc(logicop) DAG fold is we don't know if legalization has tried to promote truncated logicops already. We might be able to peek through extensions as well.

Added: 
    

Modified: 
    llvm/lib/Target/X86/X86ISelLowering.cpp
    llvm/test/CodeGen/X86/clz.ll

Removed: 
    


################################################################################
diff  --git a/llvm/lib/Target/X86/X86ISelLowering.cpp b/llvm/lib/Target/X86/X86ISelLowering.cpp
index f7af01b2338b..4818adb5f590 100644
--- a/llvm/lib/Target/X86/X86ISelLowering.cpp
+++ b/llvm/lib/Target/X86/X86ISelLowering.cpp
@@ -46958,9 +46958,10 @@ static SDValue foldXor1SetCC(SDNode *N, SelectionDAG &DAG) {
 static SDValue combineXor(SDNode *N, SelectionDAG &DAG,
                           TargetLowering::DAGCombinerInfo &DCI,
                           const X86Subtarget &Subtarget) {
+  EVT VT = N->getValueType(0);
+
   // If this is SSE1 only convert to FXOR to avoid scalarization.
-  if (Subtarget.hasSSE1() && !Subtarget.hasSSE2() &&
-      N->getValueType(0) == MVT::v4i32) {
+  if (Subtarget.hasSSE1() && !Subtarget.hasSSE2() && VT == MVT::v4i32) {
     return DAG.getBitcast(
         MVT::v4i32, DAG.getNode(X86ISD::FXOR, SDLoc(N), MVT::v4f32,
                                 DAG.getBitcast(MVT::v4f32, N->getOperand(0)),
@@ -46982,6 +46983,20 @@ static SDValue combineXor(SDNode *N, SelectionDAG &DAG,
   if (SDValue RV = foldXorTruncShiftIntoCmp(N, DAG))
     return RV;
 
+  // Fold xor(truncate(xor(x,c1)),c2) -> xor(truncate(x),xor(truncate(c1),c2))
+  // TODO: Under what circumstances could this be performed in DAGCombine?
+  if (N->getOperand(0).getOpcode() == ISD::TRUNCATE &&
+      N->getOperand(0).getOperand(0).getOpcode() == N->getOpcode() &&
+      isa<ConstantSDNode>(N->getOperand(1)) &&
+      isa<ConstantSDNode>(N->getOperand(0).getOperand(0).getOperand(1))) {
+    SDLoc DL(N);
+    SDValue TruncateSrc = N->getOperand(0).getOperand(0);
+    SDValue LHS = DAG.getNode(ISD::TRUNCATE, DL, VT, TruncateSrc.getOperand(0));
+    SDValue RHS = DAG.getNode(ISD::TRUNCATE, DL, VT, TruncateSrc.getOperand(1));
+    return DAG.getNode(ISD::XOR, DL, VT, LHS,
+                       DAG.getNode(ISD::XOR, DL, VT, RHS, N->getOperand(1)));
+  }
+
   if (SDValue FPLogic = convertIntLogicToFPLogic(N, DAG, Subtarget))
     return FPLogic;
 

diff  --git a/llvm/test/CodeGen/X86/clz.ll b/llvm/test/CodeGen/X86/clz.ll
index 08958cbdad3d..8fa5adba5183 100644
--- a/llvm/test/CodeGen/X86/clz.ll
+++ b/llvm/test/CodeGen/X86/clz.ll
@@ -1060,21 +1060,17 @@ define i64 @cttz_i64_zero_test_knownneverzero(i64 %n) {
   ret i64 %tmp1
 }
 
-; FIXME: Failed to merge the XOR(TRUNC(XOR(BSR(X),31)),31).
+; Ensure we fold away the XOR(TRUNC(XOR(BSR(X),31)),31).
 define i8 @PR47603(i32 %0) {
 ; X86-LABEL: PR47603:
 ; X86:       # %bb.0:
 ; X86-NEXT:    bsrl {{[0-9]+}}(%esp), %eax
-; X86-NEXT:    xorl $31, %eax
-; X86-NEXT:    xorb $31, %al
 ; X86-NEXT:    # kill: def $al killed $al killed $eax
 ; X86-NEXT:    retl
 ;
 ; X64-LABEL: PR47603:
 ; X64:       # %bb.0:
 ; X64-NEXT:    bsrl %edi, %eax
-; X64-NEXT:    xorl $31, %eax
-; X64-NEXT:    xorb $31, %al
 ; X64-NEXT:    # kill: def $al killed $al killed $eax
 ; X64-NEXT:    retq
 ;


        


More information about the llvm-commits mailing list