diff options
author | Sanjay Patel <spatel@rotateright.com> | 2019-02-12 17:07:47 +0000 |
---|---|---|
committer | Sanjay Patel <spatel@rotateright.com> | 2019-02-12 17:07:47 +0000 |
commit | 86fac11d5aaac1aa9d0fef09b10aec062bb0eb63 (patch) | |
tree | e03018c868afbcc3a19faca5d4e1472428cf13d9 /llvm/test/CodeGen | |
parent | 511092cab08819f832a4e3acd0547600a1c41eac (diff) | |
download | bcm5719-llvm-86fac11d5aaac1aa9d0fef09b10aec062bb0eb63.tar.gz bcm5719-llvm-86fac11d5aaac1aa9d0fef09b10aec062bb0eb63.zip |
[DAGCombiner] convert logic-of-setcc into bit magic (PR40611)
If we're comparing some value for equality against 2 constants
and those constants have an absolute difference of just 1 bit,
then we can offset and mask off that 1 bit and reduce to a single
compare against zero:
and/or (setcc X, C0, ne), (setcc X, C1, ne/eq) -->
setcc ((add X, -C1), ~(C0 - C1)), 0, ne/eq
https://rise4fun.com/Alive/XslKj
This transform is disabled by default using a TLI hook
("convertSetCCLogicToBitwiseLogic()").
That should be overridden for AArch64, MIPS, Sparc and possibly
others based on the asm shown in:
https://bugs.llvm.org/show_bug.cgi?id=40611
llvm-svn: 353859
Diffstat (limited to 'llvm/test/CodeGen')
-rw-r--r-- | llvm/test/CodeGen/PowerPC/setcc-logic.ll | 20 | ||||
-rw-r--r-- | llvm/test/CodeGen/X86/setcc-logic.ll | 12 |
2 files changed, 14 insertions, 18 deletions
diff --git a/llvm/test/CodeGen/PowerPC/setcc-logic.ll b/llvm/test/CodeGen/PowerPC/setcc-logic.ll index b0a44ad6b5b..87f73e7b2e8 100644 --- a/llvm/test/CodeGen/PowerPC/setcc-logic.ll +++ b/llvm/test/CodeGen/PowerPC/setcc-logic.ll @@ -481,11 +481,11 @@ define <4 x i1> @and_eq_vec(<4 x i32> %a, <4 x i32> %b, <4 x i32> %c, <4 x i32> define i1 @or_icmps_const_1bit_diff(i64 %x) { ; CHECK-LABEL: or_icmps_const_1bit_diff: ; CHECK: # %bb.0: -; CHECK-NEXT: cmpdi 3, 17 -; CHECK-NEXT: cmpdi 1, 3, 13 -; CHECK-NEXT: li 3, 1 -; CHECK-NEXT: crnor 20, 2, 6 -; CHECK-NEXT: isel 3, 0, 3, 20 +; CHECK-NEXT: li 4, -5 +; CHECK-NEXT: addi 3, 3, -13 +; CHECK-NEXT: and 3, 3, 4 +; CHECK-NEXT: cntlzd 3, 3 +; CHECK-NEXT: rldicl 3, 3, 58, 63 ; CHECK-NEXT: blr %a = icmp eq i64 %x, 17 %b = icmp eq i64 %x, 13 @@ -496,11 +496,11 @@ define i1 @or_icmps_const_1bit_diff(i64 %x) { define i1 @and_icmps_const_1bit_diff(i32 %x) { ; CHECK-LABEL: and_icmps_const_1bit_diff: ; CHECK: # %bb.0: -; CHECK-NEXT: cmpwi 3, 4625 -; CHECK-NEXT: cmpwi 1, 3, 4641 -; CHECK-NEXT: li 3, 1 -; CHECK-NEXT: cror 20, 6, 2 -; CHECK-NEXT: isel 3, 0, 3, 20 +; CHECK-NEXT: addi 3, 3, -4625 +; CHECK-NEXT: rlwinm 3, 3, 0, 28, 26 +; CHECK-NEXT: cntlzw 3, 3 +; CHECK-NEXT: nor 3, 3, 3 +; CHECK-NEXT: rlwinm 3, 3, 27, 31, 31 ; CHECK-NEXT: blr %a = icmp ne i32 %x, 4625 %b = icmp ne i32 %x, 4641 diff --git a/llvm/test/CodeGen/X86/setcc-logic.ll b/llvm/test/CodeGen/X86/setcc-logic.ll index f95ce9bfae2..46db9271d31 100644 --- a/llvm/test/CodeGen/X86/setcc-logic.ll +++ b/llvm/test/CodeGen/X86/setcc-logic.ll @@ -485,11 +485,9 @@ define <4 x i1> @and_eq_vec(<4 x i32> %a, <4 x i32> %b, <4 x i32> %c, <4 x i32> define i1 @or_icmps_const_1bit_diff(i8 %x) { ; CHECK-LABEL: or_icmps_const_1bit_diff: ; CHECK: # %bb.0: -; CHECK-NEXT: cmpb $43, %dil -; CHECK-NEXT: sete %cl -; CHECK-NEXT: cmpb $45, %dil +; CHECK-NEXT: addb $-43, %dil +; CHECK-NEXT: testb $-3, %dil ; CHECK-NEXT: sete %al -; CHECK-NEXT: orb %cl, %al ; CHECK-NEXT: retq %a = icmp eq i8 %x, 43 %b = icmp eq i8 %x, 45 @@ -500,11 +498,9 @@ define i1 @or_icmps_const_1bit_diff(i8 %x) { define i1 @and_icmps_const_1bit_diff(i32 %x) { ; CHECK-LABEL: and_icmps_const_1bit_diff: ; CHECK: # %bb.0: -; CHECK-NEXT: cmpl $44, %edi -; CHECK-NEXT: setne %cl -; CHECK-NEXT: cmpl $60, %edi +; CHECK-NEXT: addl $-44, %edi +; CHECK-NEXT: testl $-17, %edi ; CHECK-NEXT: setne %al -; CHECK-NEXT: andb %cl, %al ; CHECK-NEXT: retq %a = icmp ne i32 %x, 44 %b = icmp ne i32 %x, 60 |