[llvm] 4916523 - [X86] Replace (31/63 -/^ X) with (NOT X) and ignore (32/64 ^ X) when computing shift count
Phoebe Wang via llvm-commits
llvm-commits at lists.llvm.org
Thu Jan 12 20:54:05 PST 2023
Author: Noah Goldstein
Date: 2023-01-12T20:53:57-08:00
New Revision: 4916523053d791e17d1cc2135f7a14de16ed1dcc
URL: https://github.com/llvm/llvm-project/commit/4916523053d791e17d1cc2135f7a14de16ed1dcc
DIFF: https://github.com/llvm/llvm-project/commit/4916523053d791e17d1cc2135f7a14de16ed1dcc.diff
LOG: [X86] Replace (31/63 -/^ X) with (NOT X) and ignore (32/64 ^ X) when computing shift count
Shift count is masked by hardware so these peepholes just extend
common patterns for NOT to the lower bits of shift count.
As well (32/64 ^ X) is masked off by the shift so can be safely
ignored.
Reviewed By: pengfei, lebedev.ri
Differential Revision: https://reviews.llvm.org/D140087
Added:
Modified:
llvm/lib/Target/X86/X86ISelDAGToDAG.cpp
llvm/test/CodeGen/X86/legalize-shift-64.ll
llvm/test/CodeGen/X86/not-shift.ll
Removed:
################################################################################
diff --git a/llvm/lib/Target/X86/X86ISelDAGToDAG.cpp b/llvm/lib/Target/X86/X86ISelDAGToDAG.cpp
index e90f1b69ad95a..8c13ff8e3281a 100644
--- a/llvm/lib/Target/X86/X86ISelDAGToDAG.cpp
+++ b/llvm/lib/Target/X86/X86ISelDAGToDAG.cpp
@@ -3995,17 +3995,36 @@ bool X86DAGToDAGISel::tryShiftAmountMod(SDNode *N) {
// so we are not afraid that we might mess up BZHI/BEXTR pattern.
SDValue NewShiftAmt;
- if (ShiftAmt->getOpcode() == ISD::ADD || ShiftAmt->getOpcode() == ISD::SUB) {
+ if (ShiftAmt->getOpcode() == ISD::ADD || ShiftAmt->getOpcode() == ISD::SUB ||
+ ShiftAmt->getOpcode() == ISD::XOR) {
SDValue Add0 = ShiftAmt->getOperand(0);
SDValue Add1 = ShiftAmt->getOperand(1);
auto *Add0C = dyn_cast<ConstantSDNode>(Add0);
auto *Add1C = dyn_cast<ConstantSDNode>(Add1);
- // If we are shifting by X+/-N where N == 0 mod Size, then just shift by X
- // to avoid the ADD/SUB.
+ // If we are shifting by X+/-/^N where N == 0 mod Size, then just shift by X
+ // to avoid the ADD/SUB/XOR.
if (Add1C && Add1C->getAPIntValue().urem(Size) == 0) {
NewShiftAmt = Add0;
- // If we are shifting by N-X where N == 0 mod Size, then just shift by -X
- // to generate a NEG instead of a SUB of a constant.
+
+ } else if (ShiftAmt->getOpcode() != ISD::ADD &&
+ ((Add0C && Add0C->getAPIntValue().urem(Size) == Size - 1) ||
+ (Add1C && Add1C->getAPIntValue().urem(Size) == Size - 1))) {
+ // If we are doing a NOT on just the lower bits with (Size*N-1) -/^ X
+ // we can replace it with a NOT. In the XOR case it may save some code
+ // size, in the SUB case it also may save a move.
+ assert(Add0C == nullptr || Add1C == nullptr);
+
+ // We can only do N-X, not X-N
+ if (ShiftAmt->getOpcode() == ISD::SUB && Add0C == nullptr)
+ return false;
+
+ auto *ConstValOp = Add0C == nullptr ? Add1C : Add0C;
+ EVT OpVT = ShiftAmt.getValueType();
+
+ NewShiftAmt = CurDAG->getNOT(DL, Add0C == nullptr ? Add0 : Add1, OpVT);
+ insertDAGNode(*CurDAG, OrigShiftAmt, NewShiftAmt);
+ // If we are shifting by N-X where N == 0 mod Size, then just shift by
+ // -X to generate a NEG instead of a SUB of a constant.
} else if (ShiftAmt->getOpcode() == ISD::SUB && Add0C &&
Add0C->getZExtValue() != 0) {
EVT SubVT = ShiftAmt.getValueType();
diff --git a/llvm/test/CodeGen/X86/legalize-shift-64.ll b/llvm/test/CodeGen/X86/legalize-shift-64.ll
index 57643e3413520..53208de7ea27e 100644
--- a/llvm/test/CodeGen/X86/legalize-shift-64.ll
+++ b/llvm/test/CodeGen/X86/legalize-shift-64.ll
@@ -10,7 +10,7 @@ define i64 @test1(i32 %xx, i32 %test) nounwind {
; CHECK-NEXT: movl %edx, %eax
; CHECK-NEXT: shll %cl, %eax
; CHECK-NEXT: shrl %edx
-; CHECK-NEXT: xorb $31, %cl
+; CHECK-NEXT: notb %cl
; CHECK-NEXT: shrl %cl, %edx
; CHECK-NEXT: retl
%conv = zext i32 %xx to i64
diff --git a/llvm/test/CodeGen/X86/not-shift.ll b/llvm/test/CodeGen/X86/not-shift.ll
index 67de3f240ed58..1d2fd19cff6eb 100644
--- a/llvm/test/CodeGen/X86/not-shift.ll
+++ b/llvm/test/CodeGen/X86/not-shift.ll
@@ -50,17 +50,17 @@ define i64 @sub63_shiftl64(i64 %val, i64 %cnt) nounwind {
;
; X64-NOBMI2-LABEL: sub63_shiftl64:
; X64-NOBMI2: # %bb.0:
+; X64-NOBMI2-NEXT: movq %rsi, %rcx
; X64-NOBMI2-NEXT: movq %rdi, %rax
-; X64-NOBMI2-NEXT: movb $63, %cl
-; X64-NOBMI2-NEXT: subb %sil, %cl
+; X64-NOBMI2-NEXT: notb %cl
+; X64-NOBMI2-NEXT: # kill: def $cl killed $cl killed $rcx
; X64-NOBMI2-NEXT: shlq %cl, %rax
; X64-NOBMI2-NEXT: retq
;
; X64-BMI2-LABEL: sub63_shiftl64:
; X64-BMI2: # %bb.0:
-; X64-BMI2-NEXT: movb $63, %al
-; X64-BMI2-NEXT: subb %sil, %al
-; X64-BMI2-NEXT: shlxq %rax, %rdi, %rax
+; X64-BMI2-NEXT: notb %sil
+; X64-BMI2-NEXT: shlxq %rsi, %rdi, %rax
; X64-BMI2-NEXT: retq
%adjcnt = sub i64 63, %cnt
%result = shl i64 %val, %adjcnt
@@ -107,14 +107,14 @@ define i64 @xor63_shiftr64(i64 %val, i64 %cnt) nounwind {
; X64-NOBMI2: # %bb.0:
; X64-NOBMI2-NEXT: movq %rsi, %rcx
; X64-NOBMI2-NEXT: movq %rdi, %rax
-; X64-NOBMI2-NEXT: xorb $63, %cl
+; X64-NOBMI2-NEXT: notb %cl
; X64-NOBMI2-NEXT: # kill: def $cl killed $cl killed $rcx
; X64-NOBMI2-NEXT: shrq %cl, %rax
; X64-NOBMI2-NEXT: retq
;
; X64-BMI2-LABEL: xor63_shiftr64:
; X64-BMI2: # %bb.0:
-; X64-BMI2-NEXT: xorb $63, %sil
+; X64-BMI2-NEXT: notb %sil
; X64-BMI2-NEXT: shrxq %rsi, %rdi, %rax
; X64-BMI2-NEXT: retq
%adjcnt = xor i64 %cnt, 63
@@ -162,14 +162,14 @@ define i64 @sub127_shiftl64(i64 %val, i64 %cnt) nounwind {
; X64-NOBMI2: # %bb.0:
; X64-NOBMI2-NEXT: movq %rsi, %rcx
; X64-NOBMI2-NEXT: movq %rdi, %rax
-; X64-NOBMI2-NEXT: xorb $127, %cl
+; X64-NOBMI2-NEXT: notb %cl
; X64-NOBMI2-NEXT: # kill: def $cl killed $cl killed $rcx
; X64-NOBMI2-NEXT: shlq %cl, %rax
; X64-NOBMI2-NEXT: retq
;
; X64-BMI2-LABEL: sub127_shiftl64:
; X64-BMI2: # %bb.0:
-; X64-BMI2-NEXT: xorb $127, %sil
+; X64-BMI2-NEXT: notb %sil
; X64-BMI2-NEXT: shlxq %rsi, %rdi, %rax
; X64-BMI2-NEXT: retq
%adjcnt = sub i64 127, %cnt
@@ -217,14 +217,14 @@ define i64 @xor127_shiftr64(i64 %val, i64 %cnt) nounwind {
; X64-NOBMI2: # %bb.0:
; X64-NOBMI2-NEXT: movq %rsi, %rcx
; X64-NOBMI2-NEXT: movq %rdi, %rax
-; X64-NOBMI2-NEXT: xorb $127, %cl
+; X64-NOBMI2-NEXT: notb %cl
; X64-NOBMI2-NEXT: # kill: def $cl killed $cl killed $rcx
; X64-NOBMI2-NEXT: shrq %cl, %rax
; X64-NOBMI2-NEXT: retq
;
; X64-BMI2-LABEL: xor127_shiftr64:
; X64-BMI2: # %bb.0:
-; X64-BMI2-NEXT: xorb $127, %sil
+; X64-BMI2-NEXT: notb %sil
; X64-BMI2-NEXT: shrxq %rsi, %rdi, %rax
; X64-BMI2-NEXT: retq
%adjcnt = xor i64 %cnt, 127
@@ -272,14 +272,12 @@ define i64 @xor64_shiftl64(i64 %val, i64 %cnt) nounwind {
; X64-NOBMI2: # %bb.0:
; X64-NOBMI2-NEXT: movq %rsi, %rcx
; X64-NOBMI2-NEXT: movq %rdi, %rax
-; X64-NOBMI2-NEXT: xorb $64, %cl
; X64-NOBMI2-NEXT: # kill: def $cl killed $cl killed $rcx
; X64-NOBMI2-NEXT: shlq %cl, %rax
; X64-NOBMI2-NEXT: retq
;
; X64-BMI2-LABEL: xor64_shiftl64:
; X64-BMI2: # %bb.0:
-; X64-BMI2-NEXT: xorb $64, %sil
; X64-BMI2-NEXT: shlxq %rsi, %rdi, %rax
; X64-BMI2-NEXT: retq
%adjcnt = xor i64 %cnt, 64
@@ -401,31 +399,31 @@ define i32 @sub31_shiftr32(i32 %val, i32 %cnt) nounwind {
; X86-NOBMI2-LABEL: sub31_shiftr32:
; X86-NOBMI2: # %bb.0:
; X86-NOBMI2-NEXT: movl {{[0-9]+}}(%esp), %eax
-; X86-NOBMI2-NEXT: movb $31, %cl
-; X86-NOBMI2-NEXT: subb {{[0-9]+}}(%esp), %cl
+; X86-NOBMI2-NEXT: movzbl {{[0-9]+}}(%esp), %ecx
+; X86-NOBMI2-NEXT: notb %cl
; X86-NOBMI2-NEXT: shrl %cl, %eax
; X86-NOBMI2-NEXT: retl
;
; X86-BMI2-LABEL: sub31_shiftr32:
; X86-BMI2: # %bb.0:
-; X86-BMI2-NEXT: movb $31, %al
-; X86-BMI2-NEXT: subb {{[0-9]+}}(%esp), %al
+; X86-BMI2-NEXT: movzbl {{[0-9]+}}(%esp), %eax
+; X86-BMI2-NEXT: notb %al
; X86-BMI2-NEXT: shrxl %eax, {{[0-9]+}}(%esp), %eax
; X86-BMI2-NEXT: retl
;
; X64-NOBMI2-LABEL: sub31_shiftr32:
; X64-NOBMI2: # %bb.0:
+; X64-NOBMI2-NEXT: movl %esi, %ecx
; X64-NOBMI2-NEXT: movl %edi, %eax
-; X64-NOBMI2-NEXT: movb $31, %cl
-; X64-NOBMI2-NEXT: subb %sil, %cl
+; X64-NOBMI2-NEXT: notb %cl
+; X64-NOBMI2-NEXT: # kill: def $cl killed $cl killed $ecx
; X64-NOBMI2-NEXT: shrl %cl, %eax
; X64-NOBMI2-NEXT: retq
;
; X64-BMI2-LABEL: sub31_shiftr32:
; X64-BMI2: # %bb.0:
-; X64-BMI2-NEXT: movb $31, %al
-; X64-BMI2-NEXT: subb %sil, %al
-; X64-BMI2-NEXT: shrxl %eax, %edi, %eax
+; X64-BMI2-NEXT: notb %sil
+; X64-BMI2-NEXT: shrxl %esi, %edi, %eax
; X64-BMI2-NEXT: retq
%adjcnt = sub i32 31, %cnt
%result = lshr i32 %val, %adjcnt
@@ -437,14 +435,14 @@ define i32 @xor31_shiftl32(i32 %val, i32 %cnt) nounwind {
; X86-NOBMI2: # %bb.0:
; X86-NOBMI2-NEXT: movl {{[0-9]+}}(%esp), %eax
; X86-NOBMI2-NEXT: movzbl {{[0-9]+}}(%esp), %ecx
-; X86-NOBMI2-NEXT: xorb $31, %cl
+; X86-NOBMI2-NEXT: notb %cl
; X86-NOBMI2-NEXT: shll %cl, %eax
; X86-NOBMI2-NEXT: retl
;
; X86-BMI2-LABEL: xor31_shiftl32:
; X86-BMI2: # %bb.0:
; X86-BMI2-NEXT: movzbl {{[0-9]+}}(%esp), %eax
-; X86-BMI2-NEXT: xorb $31, %al
+; X86-BMI2-NEXT: notb %al
; X86-BMI2-NEXT: shlxl %eax, {{[0-9]+}}(%esp), %eax
; X86-BMI2-NEXT: retl
;
@@ -452,14 +450,14 @@ define i32 @xor31_shiftl32(i32 %val, i32 %cnt) nounwind {
; X64-NOBMI2: # %bb.0:
; X64-NOBMI2-NEXT: movl %esi, %ecx
; X64-NOBMI2-NEXT: movl %edi, %eax
-; X64-NOBMI2-NEXT: xorb $31, %cl
+; X64-NOBMI2-NEXT: notb %cl
; X64-NOBMI2-NEXT: # kill: def $cl killed $cl killed $ecx
; X64-NOBMI2-NEXT: shll %cl, %eax
; X64-NOBMI2-NEXT: retq
;
; X64-BMI2-LABEL: xor31_shiftl32:
; X64-BMI2: # %bb.0:
-; X64-BMI2-NEXT: xorb $31, %sil
+; X64-BMI2-NEXT: notb %sil
; X64-BMI2-NEXT: shlxl %esi, %edi, %eax
; X64-BMI2-NEXT: retq
%adjcnt = xor i32 %cnt, 31
@@ -471,31 +469,31 @@ define i32 @sub63_shiftr32(i32 %val, i32 %cnt) nounwind {
; X86-NOBMI2-LABEL: sub63_shiftr32:
; X86-NOBMI2: # %bb.0:
; X86-NOBMI2-NEXT: movl {{[0-9]+}}(%esp), %eax
-; X86-NOBMI2-NEXT: movb $63, %cl
-; X86-NOBMI2-NEXT: subb {{[0-9]+}}(%esp), %cl
+; X86-NOBMI2-NEXT: movzbl {{[0-9]+}}(%esp), %ecx
+; X86-NOBMI2-NEXT: notb %cl
; X86-NOBMI2-NEXT: shrl %cl, %eax
; X86-NOBMI2-NEXT: retl
;
; X86-BMI2-LABEL: sub63_shiftr32:
; X86-BMI2: # %bb.0:
-; X86-BMI2-NEXT: movb $63, %al
-; X86-BMI2-NEXT: subb {{[0-9]+}}(%esp), %al
+; X86-BMI2-NEXT: movzbl {{[0-9]+}}(%esp), %eax
+; X86-BMI2-NEXT: notb %al
; X86-BMI2-NEXT: shrxl %eax, {{[0-9]+}}(%esp), %eax
; X86-BMI2-NEXT: retl
;
; X64-NOBMI2-LABEL: sub63_shiftr32:
; X64-NOBMI2: # %bb.0:
+; X64-NOBMI2-NEXT: movl %esi, %ecx
; X64-NOBMI2-NEXT: movl %edi, %eax
-; X64-NOBMI2-NEXT: movb $63, %cl
-; X64-NOBMI2-NEXT: subb %sil, %cl
+; X64-NOBMI2-NEXT: notb %cl
+; X64-NOBMI2-NEXT: # kill: def $cl killed $cl killed $ecx
; X64-NOBMI2-NEXT: shrl %cl, %eax
; X64-NOBMI2-NEXT: retq
;
; X64-BMI2-LABEL: sub63_shiftr32:
; X64-BMI2: # %bb.0:
-; X64-BMI2-NEXT: movb $63, %al
-; X64-BMI2-NEXT: subb %sil, %al
-; X64-BMI2-NEXT: shrxl %eax, %edi, %eax
+; X64-BMI2-NEXT: notb %sil
+; X64-BMI2-NEXT: shrxl %esi, %edi, %eax
; X64-BMI2-NEXT: retq
%adjcnt = sub i32 63, %cnt
%result = lshr i32 %val, %adjcnt
@@ -507,14 +505,14 @@ define i32 @xor63_shiftl32(i32 %val, i32 %cnt) nounwind {
; X86-NOBMI2: # %bb.0:
; X86-NOBMI2-NEXT: movl {{[0-9]+}}(%esp), %eax
; X86-NOBMI2-NEXT: movzbl {{[0-9]+}}(%esp), %ecx
-; X86-NOBMI2-NEXT: xorb $63, %cl
+; X86-NOBMI2-NEXT: notb %cl
; X86-NOBMI2-NEXT: shll %cl, %eax
; X86-NOBMI2-NEXT: retl
;
; X86-BMI2-LABEL: xor63_shiftl32:
; X86-BMI2: # %bb.0:
; X86-BMI2-NEXT: movzbl {{[0-9]+}}(%esp), %eax
-; X86-BMI2-NEXT: xorb $63, %al
+; X86-BMI2-NEXT: notb %al
; X86-BMI2-NEXT: shlxl %eax, {{[0-9]+}}(%esp), %eax
; X86-BMI2-NEXT: retl
;
@@ -522,14 +520,14 @@ define i32 @xor63_shiftl32(i32 %val, i32 %cnt) nounwind {
; X64-NOBMI2: # %bb.0:
; X64-NOBMI2-NEXT: movl %esi, %ecx
; X64-NOBMI2-NEXT: movl %edi, %eax
-; X64-NOBMI2-NEXT: xorb $63, %cl
+; X64-NOBMI2-NEXT: notb %cl
; X64-NOBMI2-NEXT: # kill: def $cl killed $cl killed $ecx
; X64-NOBMI2-NEXT: shll %cl, %eax
; X64-NOBMI2-NEXT: retq
;
; X64-BMI2-LABEL: xor63_shiftl32:
; X64-BMI2: # %bb.0:
-; X64-BMI2-NEXT: xorb $63, %sil
+; X64-BMI2-NEXT: notb %sil
; X64-BMI2-NEXT: shlxl %esi, %edi, %eax
; X64-BMI2-NEXT: retq
%adjcnt = xor i32 %cnt, 63
@@ -540,16 +538,14 @@ define i32 @xor63_shiftl32(i32 %val, i32 %cnt) nounwind {
define i32 @xor32_shiftr32(i32 %val, i32 %cnt) nounwind {
; X86-NOBMI2-LABEL: xor32_shiftr32:
; X86-NOBMI2: # %bb.0:
-; X86-NOBMI2-NEXT: movl {{[0-9]+}}(%esp), %eax
; X86-NOBMI2-NEXT: movzbl {{[0-9]+}}(%esp), %ecx
-; X86-NOBMI2-NEXT: xorb $32, %cl
+; X86-NOBMI2-NEXT: movl {{[0-9]+}}(%esp), %eax
; X86-NOBMI2-NEXT: shrl %cl, %eax
; X86-NOBMI2-NEXT: retl
;
; X86-BMI2-LABEL: xor32_shiftr32:
; X86-BMI2: # %bb.0:
; X86-BMI2-NEXT: movzbl {{[0-9]+}}(%esp), %eax
-; X86-BMI2-NEXT: xorb $32, %al
; X86-BMI2-NEXT: shrxl %eax, {{[0-9]+}}(%esp), %eax
; X86-BMI2-NEXT: retl
;
@@ -557,14 +553,12 @@ define i32 @xor32_shiftr32(i32 %val, i32 %cnt) nounwind {
; X64-NOBMI2: # %bb.0:
; X64-NOBMI2-NEXT: movl %esi, %ecx
; X64-NOBMI2-NEXT: movl %edi, %eax
-; X64-NOBMI2-NEXT: xorb $32, %cl
; X64-NOBMI2-NEXT: # kill: def $cl killed $cl killed $ecx
; X64-NOBMI2-NEXT: shrl %cl, %eax
; X64-NOBMI2-NEXT: retq
;
; X64-BMI2-LABEL: xor32_shiftr32:
; X64-BMI2: # %bb.0:
-; X64-BMI2-NEXT: xorb $32, %sil
; X64-BMI2-NEXT: shrxl %esi, %edi, %eax
; X64-BMI2-NEXT: retq
%adjcnt = xor i32 %cnt, 32
More information about the llvm-commits
mailing list