Skip to content

Commit

Permalink
[X86] Add a pattern in PreprocessISelDAG.
Browse files Browse the repository at this point in the history
`%c = shl <X x i1> %a, %b -> %c = %a`
As discussed in llvm#85681, this pattern is added to avoid cannot selection error.
Since shift one is either identical or UB, we consider it as identical and replace all uses of %c with %a.

Tests for shl, ashr, lshr are added.
This fixes llvm#85681.

Signed-off-by: Peter Rong <PeterRong96@gmail.com>
  • Loading branch information
DataCorrupted committed Mar 19, 2024
1 parent 4bade55 commit e8dda97
Show file tree
Hide file tree
Showing 2 changed files with 49 additions and 1 deletion.
11 changes: 10 additions & 1 deletion llvm/lib/Target/X86/X86ISelDAGToDAG.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -1151,10 +1151,19 @@ void X86DAGToDAGISel::PreprocessISelDAG() {
case ISD::SHL:
case ISD::SRA:
case ISD::SRL: {
auto Ty = N->getValueType(0);
// Replace vector shifts with their X86 specific equivalent so we don't
// need 2 sets of patterns.
if (!N->getValueType(0).isVector())
if (!Ty.isVector())
break;

// Per discussion in #85681, `%c = shl <X x i1> %a, %b -> %c = %a`,
// aka, replace all `%c` with `%a` and erase this instruction.
if (Ty.getVectorElementType().getFixedSizeInBits() == 1) {
CurDAG->ReplaceAllUsesOfValueWith(SDValue(N, 0), N->getOperand(0));
CurDAG->DeleteNode(N);
break;
}

unsigned NewOpc;
switch (N->getOpcode()) {
Expand Down
39 changes: 39 additions & 0 deletions llvm/test/CodeGen/X86/pr85681.ll
Original file line number Diff line number Diff line change
@@ -0,0 +1,39 @@
; NOTE: Assertions have been autogenerated by utils/update_llc_test_checks.py
; RUN: llc < %s -mtriple=x86_64-- -mcpu=emeraldrapids | FileCheck %s
; RUN: llc < %s -mtriple=x86_64-- -mcpu=sapphirerapids | FileCheck %s
; RUN: llc < %s -mtriple=x86_64-- -mcpu=znver4 | FileCheck %s

define i32 @shl(i32 %a0) {
; CHECK-LABEL: shl:
; CHECK: # %bb.0:
; CHECK-NEXT: kxnord %k0, %k0, %k0
; CHECK-NEXT: kmovd %k0, %eax
; CHECK-NEXT: retq
%v0 = bitcast i32 %a0 to <32 x i1>
%s = shl <32 x i1> <i1 true, i1 true, i1 true, i1 true, i1 true, i1 true, i1 true, i1 true, i1 true, i1 true, i1 true, i1 true, i1 true, i1 true, i1 true, i1 true, i1 true, i1 true, i1 true, i1 true, i1 true, i1 true, i1 true, i1 true, i1 true, i1 true, i1 true, i1 true, i1 true, i1 true, i1 true, i1 true>, %v0
%r = bitcast <32 x i1> %s to i32
ret i32 %r
}

define i32 @lshr(i32 %a0) {
; CHECK-LABEL: lshr:
; CHECK: # %bb.0:
; CHECK-NEXT: movl $-1, %eax
; CHECK-NEXT: retq
%v0 = bitcast i32 %a0 to <32 x i1>
%s = lshr <32 x i1> <i1 true, i1 true, i1 true, i1 true, i1 true, i1 true, i1 true, i1 true, i1 true, i1 true, i1 true, i1 true, i1 true, i1 true, i1 true, i1 true, i1 true, i1 true, i1 true, i1 true, i1 true, i1 true, i1 true, i1 true, i1 true, i1 true, i1 true, i1 true, i1 true, i1 true, i1 true, i1 true>, %v0
%r = bitcast <32 x i1> %s to i32
ret i32 %r
}


define i32 @ashr(i32 %a0) {
; CHECK-LABEL: ashr:
; CHECK: # %bb.0:
; CHECK-NEXT: movl $-1, %eax
; CHECK-NEXT: retq
%v0 = bitcast i32 %a0 to <32 x i1>
%s = ashr <32 x i1> <i1 true, i1 true, i1 true, i1 true, i1 true, i1 true, i1 true, i1 true, i1 true, i1 true, i1 true, i1 true, i1 true, i1 true, i1 true, i1 true, i1 true, i1 true, i1 true, i1 true, i1 true, i1 true, i1 true, i1 true, i1 true, i1 true, i1 true, i1 true, i1 true, i1 true, i1 true, i1 true>, %v0
%r = bitcast <32 x i1> %s to i32
ret i32 %r
}

0 comments on commit e8dda97

Please sign in to comment.