From 665021e7ee2faad573840b7698ad1419aa2fcd92 Mon Sep 17 00:00:00 2001 From: Sanjay Patel Date: Sat, 1 Apr 2017 15:05:54 +0000 Subject: [PATCH] [DAGCombiner] enable vector transforms for any/all {sign} bits set/clear The code already allowed vector types in via "isInteger" (which might want a more specific name), so use splat-friendly constant predicates to match those types. llvm-svn: 299304 --- llvm/lib/CodeGen/SelectionDAG/DAGCombiner.cpp | 30 ++++++------ llvm/test/CodeGen/PowerPC/setcc-logic.ll | 30 ++++-------- llvm/test/CodeGen/X86/setcc-logic.ll | 66 +++++++++++---------------- 3 files changed, 54 insertions(+), 72 deletions(-) diff --git a/llvm/lib/CodeGen/SelectionDAG/DAGCombiner.cpp b/llvm/lib/CodeGen/SelectionDAG/DAGCombiner.cpp index d21dde0..ab21b40 100644 --- a/llvm/lib/CodeGen/SelectionDAG/DAGCombiner.cpp +++ b/llvm/lib/CodeGen/SelectionDAG/DAGCombiner.cpp @@ -3201,22 +3201,17 @@ SDValue DAGCombiner::foldLogicOfSetCCs(bool IsAnd, SDValue N0, SDValue N1, ISD::CondCode CC1 = cast(N1CC)->get(); bool IsInteger = OpVT.isInteger(); if (LR == RR && CC0 == CC1 && IsInteger) { - // All bits set? - bool AndEqNeg1 = IsAnd && CC1 == ISD::SETEQ && isAllOnesConstant(LR); - // All sign bits clear? - bool AndGtNeg1 = IsAnd && CC1 == ISD::SETGT && isAllOnesConstant(LR); + bool IsZero = isNullConstantOrNullSplatConstant(LR); + bool IsNeg1 = isAllOnesConstantOrAllOnesSplatConstant(LR); + // All bits clear? - bool AndEqZero = IsAnd && CC1 == ISD::SETEQ && isNullConstant(LR); - // All sign bits set? - bool AndLtZero = IsAnd && CC1 == ISD::SETLT && isNullConstant(LR); - // Any bits clear? - bool OrNeNeg1 = !IsAnd && CC1 == ISD::SETNE && isAllOnesConstant(LR); - // Any sign bits clear? - bool OrGtNeg1 = !IsAnd && CC1 == ISD::SETGT && isAllOnesConstant(LR); + bool AndEqZero = IsAnd && CC1 == ISD::SETEQ && IsZero; + // All sign bits clear? + bool AndGtNeg1 = IsAnd && CC1 == ISD::SETGT && IsNeg1; // Any bits set? - bool OrNeZero = !IsAnd && CC1 == ISD::SETNE && isNullConstant(LR); + bool OrNeZero = !IsAnd && CC1 == ISD::SETNE && IsZero; // Any sign bits set? - bool OrLtZero = !IsAnd && CC1 == ISD::SETLT && isNullConstant(LR); + bool OrLtZero = !IsAnd && CC1 == ISD::SETLT && IsZero; // (and (seteq X, 0), (seteq Y, 0)) --> (seteq (or X, Y), 0) // (and (setgt X, -1), (setgt Y, -1)) --> (setgt (or X, Y), -1) @@ -3228,6 +3223,15 @@ SDValue DAGCombiner::foldLogicOfSetCCs(bool IsAnd, SDValue N0, SDValue N1, return DAG.getSetCC(DL, VT, Or, LR, CC1); } + // All bits set? + bool AndEqNeg1 = IsAnd && CC1 == ISD::SETEQ && IsNeg1; + // All sign bits set? + bool AndLtZero = IsAnd && CC1 == ISD::SETLT && IsZero; + // Any bits clear? + bool OrNeNeg1 = !IsAnd && CC1 == ISD::SETNE && IsNeg1; + // Any sign bits clear? + bool OrGtNeg1 = !IsAnd && CC1 == ISD::SETGT && IsNeg1; + // (and (seteq X, -1), (seteq Y, -1)) --> (seteq (and X, Y), -1) // (and (setlt X, 0), (setlt Y, 0)) --> (setlt (and X, Y), 0) // (or (setne X, -1), (setne Y, -1)) --> (setne (and X, Y), -1) diff --git a/llvm/test/CodeGen/PowerPC/setcc-logic.ll b/llvm/test/CodeGen/PowerPC/setcc-logic.ll index 33c372f..6646c23 100644 --- a/llvm/test/CodeGen/PowerPC/setcc-logic.ll +++ b/llvm/test/CodeGen/PowerPC/setcc-logic.ll @@ -311,9 +311,8 @@ define <4 x i1> @all_bits_clear_vec(<4 x i32> %P, <4 x i32> %Q) { ; CHECK-LABEL: all_bits_clear_vec: ; CHECK: # BB#0: ; CHECK-NEXT: xxlxor 36, 36, 36 +; CHECK-NEXT: xxlor 34, 34, 35 ; CHECK-NEXT: vcmpequw 2, 2, 4 -; CHECK-NEXT: vcmpequw 3, 3, 4 -; CHECK-NEXT: xxland 34, 34, 35 ; CHECK-NEXT: blr %a = icmp eq <4 x i32> %P, zeroinitializer %b = icmp eq <4 x i32> %Q, zeroinitializer @@ -325,9 +324,8 @@ define <4 x i1> @all_sign_bits_clear_vec(<4 x i32> %P, <4 x i32> %Q) { ; CHECK-LABEL: all_sign_bits_clear_vec: ; CHECK: # BB#0: ; CHECK-NEXT: vspltisb 4, -1 +; CHECK-NEXT: xxlor 34, 34, 35 ; CHECK-NEXT: vcmpgtsw 2, 2, 4 -; CHECK-NEXT: vcmpgtsw 3, 3, 4 -; CHECK-NEXT: xxland 34, 34, 35 ; CHECK-NEXT: blr %a = icmp sgt <4 x i32> %P, %b = icmp sgt <4 x i32> %Q, @@ -339,9 +337,8 @@ define <4 x i1> @all_bits_set_vec(<4 x i32> %P, <4 x i32> %Q) { ; CHECK-LABEL: all_bits_set_vec: ; CHECK: # BB#0: ; CHECK-NEXT: vspltisb 4, -1 -; CHECK-NEXT: vcmpequw 2, 2, 4 -; CHECK-NEXT: vcmpequw 3, 3, 4 ; CHECK-NEXT: xxland 34, 34, 35 +; CHECK-NEXT: vcmpequw 2, 2, 4 ; CHECK-NEXT: blr %a = icmp eq <4 x i32> %P, %b = icmp eq <4 x i32> %Q, @@ -353,9 +350,8 @@ define <4 x i1> @all_sign_bits_set_vec(<4 x i32> %P, <4 x i32> %Q) { ; CHECK-LABEL: all_sign_bits_set_vec: ; CHECK: # BB#0: ; CHECK-NEXT: xxlxor 36, 36, 36 -; CHECK-NEXT: vcmpgtsw 2, 4, 2 -; CHECK-NEXT: vcmpgtsw 3, 4, 3 ; CHECK-NEXT: xxland 34, 34, 35 +; CHECK-NEXT: vcmpgtsw 2, 4, 2 ; CHECK-NEXT: blr %a = icmp slt <4 x i32> %P, zeroinitializer %b = icmp slt <4 x i32> %Q, zeroinitializer @@ -367,11 +363,9 @@ define <4 x i1> @any_bits_set_vec(<4 x i32> %P, <4 x i32> %Q) { ; CHECK-LABEL: any_bits_set_vec: ; CHECK: # BB#0: ; CHECK-NEXT: xxlxor 36, 36, 36 +; CHECK-NEXT: xxlor 34, 34, 35 ; CHECK-NEXT: vcmpequw 2, 2, 4 -; CHECK-NEXT: vcmpequw 3, 3, 4 -; CHECK-NEXT: xxlnor 0, 34, 34 -; CHECK-NEXT: xxlnor 1, 35, 35 -; CHECK-NEXT: xxlor 34, 0, 1 +; CHECK-NEXT: xxlnor 34, 34, 34 ; CHECK-NEXT: blr %a = icmp ne <4 x i32> %P, zeroinitializer %b = icmp ne <4 x i32> %Q, zeroinitializer @@ -383,9 +377,8 @@ define <4 x i1> @any_sign_bits_set_vec(<4 x i32> %P, <4 x i32> %Q) { ; CHECK-LABEL: any_sign_bits_set_vec: ; CHECK: # BB#0: ; CHECK-NEXT: xxlxor 36, 36, 36 -; CHECK-NEXT: vcmpgtsw 2, 4, 2 -; CHECK-NEXT: vcmpgtsw 3, 4, 3 ; CHECK-NEXT: xxlor 34, 34, 35 +; CHECK-NEXT: vcmpgtsw 2, 4, 2 ; CHECK-NEXT: blr %a = icmp slt <4 x i32> %P, zeroinitializer %b = icmp slt <4 x i32> %Q, zeroinitializer @@ -397,11 +390,9 @@ define <4 x i1> @any_bits_clear_vec(<4 x i32> %P, <4 x i32> %Q) { ; CHECK-LABEL: any_bits_clear_vec: ; CHECK: # BB#0: ; CHECK-NEXT: vspltisb 4, -1 +; CHECK-NEXT: xxland 34, 34, 35 ; CHECK-NEXT: vcmpequw 2, 2, 4 -; CHECK-NEXT: vcmpequw 3, 3, 4 -; CHECK-NEXT: xxlnor 0, 34, 34 -; CHECK-NEXT: xxlnor 1, 35, 35 -; CHECK-NEXT: xxlor 34, 0, 1 +; CHECK-NEXT: xxlnor 34, 34, 34 ; CHECK-NEXT: blr %a = icmp ne <4 x i32> %P, %b = icmp ne <4 x i32> %Q, @@ -413,9 +404,8 @@ define <4 x i1> @any_sign_bits_clear_vec(<4 x i32> %P, <4 x i32> %Q) { ; CHECK-LABEL: any_sign_bits_clear_vec: ; CHECK: # BB#0: ; CHECK-NEXT: vspltisb 4, -1 +; CHECK-NEXT: xxland 34, 34, 35 ; CHECK-NEXT: vcmpgtsw 2, 2, 4 -; CHECK-NEXT: vcmpgtsw 3, 3, 4 -; CHECK-NEXT: xxlor 34, 34, 35 ; CHECK-NEXT: blr %a = icmp sgt <4 x i32> %P, %b = icmp sgt <4 x i32> %Q, diff --git a/llvm/test/CodeGen/X86/setcc-logic.ll b/llvm/test/CodeGen/X86/setcc-logic.ll index 1a145e2..2f0828c 100644 --- a/llvm/test/CodeGen/X86/setcc-logic.ll +++ b/llvm/test/CodeGen/X86/setcc-logic.ll @@ -316,10 +316,9 @@ return: define <4 x i1> @all_bits_clear_vec(<4 x i32> %P, <4 x i32> %Q) nounwind { ; CHECK-LABEL: all_bits_clear_vec: ; CHECK: # BB#0: -; CHECK-NEXT: pxor %xmm2, %xmm2 -; CHECK-NEXT: pcmpeqd %xmm2, %xmm0 -; CHECK-NEXT: pcmpeqd %xmm2, %xmm1 -; CHECK-NEXT: pand %xmm1, %xmm0 +; CHECK-NEXT: por %xmm1, %xmm0 +; CHECK-NEXT: pxor %xmm1, %xmm1 +; CHECK-NEXT: pcmpeqd %xmm1, %xmm0 ; CHECK-NEXT: retq %a = icmp eq <4 x i32> %P, zeroinitializer %b = icmp eq <4 x i32> %Q, zeroinitializer @@ -330,10 +329,9 @@ define <4 x i1> @all_bits_clear_vec(<4 x i32> %P, <4 x i32> %Q) nounwind { define <4 x i1> @all_sign_bits_clear_vec(<4 x i32> %P, <4 x i32> %Q) nounwind { ; CHECK-LABEL: all_sign_bits_clear_vec: ; CHECK: # BB#0: -; CHECK-NEXT: pcmpeqd %xmm2, %xmm2 -; CHECK-NEXT: pcmpgtd %xmm2, %xmm0 -; CHECK-NEXT: pcmpgtd %xmm2, %xmm1 -; CHECK-NEXT: pand %xmm1, %xmm0 +; CHECK-NEXT: por %xmm1, %xmm0 +; CHECK-NEXT: pcmpeqd %xmm1, %xmm1 +; CHECK-NEXT: pcmpgtd %xmm1, %xmm0 ; CHECK-NEXT: retq %a = icmp sgt <4 x i32> %P, %b = icmp sgt <4 x i32> %Q, @@ -344,10 +342,9 @@ define <4 x i1> @all_sign_bits_clear_vec(<4 x i32> %P, <4 x i32> %Q) nounwind { define <4 x i1> @all_bits_set_vec(<4 x i32> %P, <4 x i32> %Q) nounwind { ; CHECK-LABEL: all_bits_set_vec: ; CHECK: # BB#0: -; CHECK-NEXT: pcmpeqd %xmm2, %xmm2 -; CHECK-NEXT: pcmpeqd %xmm2, %xmm0 -; CHECK-NEXT: pcmpeqd %xmm2, %xmm1 ; CHECK-NEXT: pand %xmm1, %xmm0 +; CHECK-NEXT: pcmpeqd %xmm1, %xmm1 +; CHECK-NEXT: pcmpeqd %xmm1, %xmm0 ; CHECK-NEXT: retq %a = icmp eq <4 x i32> %P, %b = icmp eq <4 x i32> %Q, @@ -358,12 +355,10 @@ define <4 x i1> @all_bits_set_vec(<4 x i32> %P, <4 x i32> %Q) nounwind { define <4 x i1> @all_sign_bits_set_vec(<4 x i32> %P, <4 x i32> %Q) nounwind { ; CHECK-LABEL: all_sign_bits_set_vec: ; CHECK: # BB#0: -; CHECK-NEXT: pxor %xmm2, %xmm2 -; CHECK-NEXT: pxor %xmm3, %xmm3 -; CHECK-NEXT: pcmpgtd %xmm0, %xmm3 -; CHECK-NEXT: pcmpgtd %xmm1, %xmm2 -; CHECK-NEXT: pand %xmm3, %xmm2 -; CHECK-NEXT: movdqa %xmm2, %xmm0 +; CHECK-NEXT: pand %xmm1, %xmm0 +; CHECK-NEXT: pxor %xmm1, %xmm1 +; CHECK-NEXT: pcmpgtd %xmm0, %xmm1 +; CHECK-NEXT: movdqa %xmm1, %xmm0 ; CHECK-NEXT: retq %a = icmp slt <4 x i32> %P, zeroinitializer %b = icmp slt <4 x i32> %Q, zeroinitializer @@ -374,13 +369,11 @@ define <4 x i1> @all_sign_bits_set_vec(<4 x i32> %P, <4 x i32> %Q) nounwind { define <4 x i1> @any_bits_set_vec(<4 x i32> %P, <4 x i32> %Q) nounwind { ; CHECK-LABEL: any_bits_set_vec: ; CHECK: # BB#0: -; CHECK-NEXT: pxor %xmm2, %xmm2 -; CHECK-NEXT: pcmpeqd %xmm2, %xmm0 -; CHECK-NEXT: pcmpeqd %xmm3, %xmm3 -; CHECK-NEXT: pxor %xmm3, %xmm0 -; CHECK-NEXT: pcmpeqd %xmm2, %xmm1 -; CHECK-NEXT: pxor %xmm3, %xmm1 ; CHECK-NEXT: por %xmm1, %xmm0 +; CHECK-NEXT: pxor %xmm1, %xmm1 +; CHECK-NEXT: pcmpeqd %xmm1, %xmm0 +; CHECK-NEXT: pcmpeqd %xmm1, %xmm1 +; CHECK-NEXT: pxor %xmm1, %xmm0 ; CHECK-NEXT: retq %a = icmp ne <4 x i32> %P, zeroinitializer %b = icmp ne <4 x i32> %Q, zeroinitializer @@ -391,12 +384,10 @@ define <4 x i1> @any_bits_set_vec(<4 x i32> %P, <4 x i32> %Q) nounwind { define <4 x i1> @any_sign_bits_set_vec(<4 x i32> %P, <4 x i32> %Q) nounwind { ; CHECK-LABEL: any_sign_bits_set_vec: ; CHECK: # BB#0: -; CHECK-NEXT: pxor %xmm2, %xmm2 -; CHECK-NEXT: pxor %xmm3, %xmm3 -; CHECK-NEXT: pcmpgtd %xmm0, %xmm3 -; CHECK-NEXT: pcmpgtd %xmm1, %xmm2 -; CHECK-NEXT: por %xmm3, %xmm2 -; CHECK-NEXT: movdqa %xmm2, %xmm0 +; CHECK-NEXT: por %xmm1, %xmm0 +; CHECK-NEXT: pxor %xmm1, %xmm1 +; CHECK-NEXT: pcmpgtd %xmm0, %xmm1 +; CHECK-NEXT: movdqa %xmm1, %xmm0 ; CHECK-NEXT: retq %a = icmp slt <4 x i32> %P, zeroinitializer %b = icmp slt <4 x i32> %Q, zeroinitializer @@ -407,12 +398,10 @@ define <4 x i1> @any_sign_bits_set_vec(<4 x i32> %P, <4 x i32> %Q) nounwind { define <4 x i1> @any_bits_clear_vec(<4 x i32> %P, <4 x i32> %Q) nounwind { ; CHECK-LABEL: any_bits_clear_vec: ; CHECK: # BB#0: -; CHECK-NEXT: pcmpeqd %xmm2, %xmm2 -; CHECK-NEXT: pcmpeqd %xmm2, %xmm0 -; CHECK-NEXT: pxor %xmm2, %xmm0 -; CHECK-NEXT: pcmpeqd %xmm2, %xmm1 -; CHECK-NEXT: pxor %xmm2, %xmm1 -; CHECK-NEXT: por %xmm1, %xmm0 +; CHECK-NEXT: pand %xmm1, %xmm0 +; CHECK-NEXT: pcmpeqd %xmm1, %xmm1 +; CHECK-NEXT: pcmpeqd %xmm1, %xmm0 +; CHECK-NEXT: pxor %xmm1, %xmm0 ; CHECK-NEXT: retq %a = icmp ne <4 x i32> %P, %b = icmp ne <4 x i32> %Q, @@ -423,10 +412,9 @@ define <4 x i1> @any_bits_clear_vec(<4 x i32> %P, <4 x i32> %Q) nounwind { define <4 x i1> @any_sign_bits_clear_vec(<4 x i32> %P, <4 x i32> %Q) nounwind { ; CHECK-LABEL: any_sign_bits_clear_vec: ; CHECK: # BB#0: -; CHECK-NEXT: pcmpeqd %xmm2, %xmm2 -; CHECK-NEXT: pcmpgtd %xmm2, %xmm0 -; CHECK-NEXT: pcmpgtd %xmm2, %xmm1 -; CHECK-NEXT: por %xmm1, %xmm0 +; CHECK-NEXT: pand %xmm1, %xmm0 +; CHECK-NEXT: pcmpeqd %xmm1, %xmm1 +; CHECK-NEXT: pcmpgtd %xmm1, %xmm0 ; CHECK-NEXT: retq %a = icmp sgt <4 x i32> %P, %b = icmp sgt <4 x i32> %Q, -- 2.7.4