Skip to content

Commit 7f248a6

Browse files
authored
[X86] mayFoldIntoVector - relax load alignment requirements (#171830)
If we're trying to move big integers to vector types, relax the SSE alignment requirements - unlike regular uses of mayFoldLoad, we're not testing to confirm every load will fold into a vector op, just that it can move to the FPU. Fixes #144861
1 parent 85fafd5 commit 7f248a6

File tree

3 files changed

+130
-73
lines changed

3 files changed

+130
-73
lines changed

llvm/lib/Target/X86/X86ISelLowering.cpp

Lines changed: 6 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -2805,16 +2805,17 @@ X86TargetLowering::createFastISel(FunctionLoweringInfo &funcInfo,
28052805
//===----------------------------------------------------------------------===//
28062806

28072807
bool X86::mayFoldLoad(SDValue Op, const X86Subtarget &Subtarget,
2808-
bool AssumeSingleUse) {
2808+
bool AssumeSingleUse, bool IgnoreAlignment) {
28092809
if (!AssumeSingleUse && !Op.hasOneUse())
28102810
return false;
28112811
if (!ISD::isNormalLoad(Op.getNode()))
28122812
return false;
28132813

28142814
// If this is an unaligned vector, make sure the target supports folding it.
28152815
auto *Ld = cast<LoadSDNode>(Op.getNode());
2816-
if (!Subtarget.hasAVX() && !Subtarget.hasSSEUnalignedMem() &&
2817-
Ld->getValueSizeInBits(0) == 128 && Ld->getAlign() < Align(16))
2816+
if (!IgnoreAlignment && !Subtarget.hasAVX() &&
2817+
!Subtarget.hasSSEUnalignedMem() && Ld->getValueSizeInBits(0) == 128 &&
2818+
Ld->getAlign() < Align(16))
28182819
return false;
28192820

28202821
// TODO: If this is a non-temporal load and the target has an instruction
@@ -2864,7 +2865,8 @@ static bool mayFoldIntoVector(SDValue Op, const X86Subtarget &Subtarget) {
28642865
return true;
28652866
if (isa<ConstantSDNode>(Op) || isa<ConstantFPSDNode>(Op))
28662867
return true;
2867-
return X86::mayFoldLoad(Op, Subtarget);
2868+
return X86::mayFoldLoad(Op, Subtarget, /*AssumeSingleUse=*/false,
2869+
/*IgnoreAlignment=*/true);
28682870
}
28692871

28702872
static bool isLogicOp(unsigned Opcode) {

llvm/lib/Target/X86/X86ISelLowering.h

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1042,7 +1042,8 @@ namespace llvm {
10421042
/// Check if Op is a load operation that could be folded into some other x86
10431043
/// instruction as a memory operand. Example: vpaddd (%rdi), %xmm0, %xmm0.
10441044
bool mayFoldLoad(SDValue Op, const X86Subtarget &Subtarget,
1045-
bool AssumeSingleUse = false);
1045+
bool AssumeSingleUse = false,
1046+
bool IgnoreAlignment = false);
10461047

10471048
/// Check if Op is a load operation that could be folded into a vector splat
10481049
/// instruction as a memory operand. Example: vbroadcastss 16(%rdi), %xmm2.

llvm/test/CodeGen/X86/ptest.ll

Lines changed: 122 additions & 68 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
; NOTE: Assertions have been autogenerated by utils/update_llc_test_checks.py
2-
; RUN: llc < %s -mtriple=x86_64-unknown-unknown -mattr=+sse2,-avx | FileCheck %s --check-prefixes=CHECK,SSE,SSE2
3-
; RUN: llc < %s -mtriple=x86_64-unknown-unknown -mattr=+sse4.1,-avx | FileCheck %s --check-prefixes=CHECK,SSE,SSE41
2+
; RUN: llc < %s -mtriple=x86_64-unknown-unknown -mattr=+sse2,-avx | FileCheck %s --check-prefixes=CHECK,SSE2
3+
; RUN: llc < %s -mtriple=x86_64-unknown-unknown -mattr=+sse4.1,-avx | FileCheck %s --check-prefixes=CHECK,SSE41
44
; RUN: llc < %s -mtriple=x86_64-unknown-unknown -mattr=+avx,-avx2 | FileCheck %s --check-prefixes=CHECK,AVX,AVX1
55
; RUN: llc < %s -mtriple=x86_64-unknown-unknown -mattr=+avx512vl,+avx512dq,+avx512bw | FileCheck %s --check-prefixes=CHECK,AVX,AVX512
66

@@ -433,15 +433,26 @@ define i1 @vecmp_load64x4(ptr %p0) {
433433
}
434434

435435
define i1 @vecmp_load128x2(ptr %p0) {
436-
; SSE-LABEL: vecmp_load128x2:
437-
; SSE: # %bb.0:
438-
; SSE-NEXT: movq (%rdi), %rax
439-
; SSE-NEXT: movq 8(%rdi), %rcx
440-
; SSE-NEXT: orq 24(%rdi), %rcx
441-
; SSE-NEXT: orq 16(%rdi), %rax
442-
; SSE-NEXT: orq %rcx, %rax
443-
; SSE-NEXT: sete %al
444-
; SSE-NEXT: retq
436+
; SSE2-LABEL: vecmp_load128x2:
437+
; SSE2: # %bb.0:
438+
; SSE2-NEXT: movdqu (%rdi), %xmm0
439+
; SSE2-NEXT: movdqu 16(%rdi), %xmm1
440+
; SSE2-NEXT: por %xmm0, %xmm1
441+
; SSE2-NEXT: pxor %xmm0, %xmm0
442+
; SSE2-NEXT: pcmpeqd %xmm1, %xmm0
443+
; SSE2-NEXT: movmskps %xmm0, %eax
444+
; SSE2-NEXT: xorl $15, %eax
445+
; SSE2-NEXT: sete %al
446+
; SSE2-NEXT: retq
447+
;
448+
; SSE41-LABEL: vecmp_load128x2:
449+
; SSE41: # %bb.0:
450+
; SSE41-NEXT: movdqu (%rdi), %xmm0
451+
; SSE41-NEXT: movdqu 16(%rdi), %xmm1
452+
; SSE41-NEXT: por %xmm0, %xmm1
453+
; SSE41-NEXT: ptest %xmm1, %xmm1
454+
; SSE41-NEXT: sete %al
455+
; SSE41-NEXT: retq
445456
;
446457
; AVX-LABEL: vecmp_load128x2:
447458
; AVX: # %bb.0:
@@ -461,21 +472,34 @@ define i1 @vecmp_load128x2(ptr %p0) {
461472
}
462473

463474
define i1 @vecmp_load128x4(ptr %p0) {
464-
; SSE-LABEL: vecmp_load128x4:
465-
; SSE: # %bb.0:
466-
; SSE-NEXT: movq (%rdi), %rax
467-
; SSE-NEXT: movq 8(%rdi), %rcx
468-
; SSE-NEXT: movq 24(%rdi), %rdx
469-
; SSE-NEXT: movq 16(%rdi), %rsi
470-
; SSE-NEXT: orq 32(%rdi), %rax
471-
; SSE-NEXT: orq 40(%rdi), %rcx
472-
; SSE-NEXT: orq 48(%rdi), %rsi
473-
; SSE-NEXT: orq %rax, %rsi
474-
; SSE-NEXT: orq 56(%rdi), %rdx
475-
; SSE-NEXT: orq %rcx, %rdx
476-
; SSE-NEXT: orq %rsi, %rdx
477-
; SSE-NEXT: sete %al
478-
; SSE-NEXT: retq
475+
; SSE2-LABEL: vecmp_load128x4:
476+
; SSE2: # %bb.0:
477+
; SSE2-NEXT: movdqu (%rdi), %xmm0
478+
; SSE2-NEXT: movdqu 16(%rdi), %xmm1
479+
; SSE2-NEXT: movdqu 32(%rdi), %xmm2
480+
; SSE2-NEXT: por %xmm0, %xmm2
481+
; SSE2-NEXT: movdqu 48(%rdi), %xmm0
482+
; SSE2-NEXT: por %xmm1, %xmm0
483+
; SSE2-NEXT: por %xmm2, %xmm0
484+
; SSE2-NEXT: pxor %xmm1, %xmm1
485+
; SSE2-NEXT: pcmpeqd %xmm0, %xmm1
486+
; SSE2-NEXT: movmskps %xmm1, %eax
487+
; SSE2-NEXT: xorl $15, %eax
488+
; SSE2-NEXT: sete %al
489+
; SSE2-NEXT: retq
490+
;
491+
; SSE41-LABEL: vecmp_load128x4:
492+
; SSE41: # %bb.0:
493+
; SSE41-NEXT: movdqu (%rdi), %xmm0
494+
; SSE41-NEXT: movdqu 16(%rdi), %xmm1
495+
; SSE41-NEXT: movdqu 32(%rdi), %xmm2
496+
; SSE41-NEXT: por %xmm0, %xmm2
497+
; SSE41-NEXT: movdqu 48(%rdi), %xmm0
498+
; SSE41-NEXT: por %xmm1, %xmm0
499+
; SSE41-NEXT: por %xmm2, %xmm0
500+
; SSE41-NEXT: ptest %xmm0, %xmm0
501+
; SSE41-NEXT: sete %al
502+
; SSE41-NEXT: retq
479503
;
480504
; AVX1-LABEL: vecmp_load128x4:
481505
; AVX1: # %bb.0:
@@ -515,21 +539,34 @@ define i1 @vecmp_load128x4(ptr %p0) {
515539

516540
; PR144861
517541
define i1 @vecmp_load256x2(ptr %p0) {
518-
; SSE-LABEL: vecmp_load256x2:
519-
; SSE: # %bb.0:
520-
; SSE-NEXT: movq 24(%rdi), %rax
521-
; SSE-NEXT: movq (%rdi), %rcx
522-
; SSE-NEXT: movq 8(%rdi), %rdx
523-
; SSE-NEXT: movq 16(%rdi), %rsi
524-
; SSE-NEXT: orq 48(%rdi), %rsi
525-
; SSE-NEXT: orq 32(%rdi), %rcx
526-
; SSE-NEXT: orq %rsi, %rcx
527-
; SSE-NEXT: orq 56(%rdi), %rax
528-
; SSE-NEXT: orq 40(%rdi), %rdx
529-
; SSE-NEXT: orq %rax, %rdx
530-
; SSE-NEXT: orq %rcx, %rdx
531-
; SSE-NEXT: sete %al
532-
; SSE-NEXT: retq
542+
; SSE2-LABEL: vecmp_load256x2:
543+
; SSE2: # %bb.0:
544+
; SSE2-NEXT: movdqu (%rdi), %xmm0
545+
; SSE2-NEXT: movdqu 16(%rdi), %xmm1
546+
; SSE2-NEXT: movdqu 32(%rdi), %xmm2
547+
; SSE2-NEXT: por %xmm0, %xmm2
548+
; SSE2-NEXT: movdqu 48(%rdi), %xmm0
549+
; SSE2-NEXT: por %xmm1, %xmm0
550+
; SSE2-NEXT: por %xmm2, %xmm0
551+
; SSE2-NEXT: pxor %xmm1, %xmm1
552+
; SSE2-NEXT: pcmpeqd %xmm0, %xmm1
553+
; SSE2-NEXT: movmskps %xmm1, %eax
554+
; SSE2-NEXT: xorl $15, %eax
555+
; SSE2-NEXT: sete %al
556+
; SSE2-NEXT: retq
557+
;
558+
; SSE41-LABEL: vecmp_load256x2:
559+
; SSE41: # %bb.0:
560+
; SSE41-NEXT: movdqu (%rdi), %xmm0
561+
; SSE41-NEXT: movdqu 16(%rdi), %xmm1
562+
; SSE41-NEXT: movdqu 32(%rdi), %xmm2
563+
; SSE41-NEXT: por %xmm0, %xmm2
564+
; SSE41-NEXT: movdqu 48(%rdi), %xmm0
565+
; SSE41-NEXT: por %xmm1, %xmm0
566+
; SSE41-NEXT: por %xmm2, %xmm0
567+
; SSE41-NEXT: ptest %xmm0, %xmm0
568+
; SSE41-NEXT: sete %al
569+
; SSE41-NEXT: retq
533570
;
534571
; AVX1-LABEL: vecmp_load256x2:
535572
; AVX1: # %bb.0:
@@ -559,33 +596,50 @@ define i1 @vecmp_load256x2(ptr %p0) {
559596
}
560597

561598
define i1 @vecmp_load512x2(ptr %p0) {
562-
; SSE-LABEL: vecmp_load512x2:
563-
; SSE: # %bb.0:
564-
; SSE-NEXT: movq 24(%rdi), %rax
565-
; SSE-NEXT: movq 56(%rdi), %rdx
566-
; SSE-NEXT: movq 40(%rdi), %rsi
567-
; SSE-NEXT: movq 16(%rdi), %rcx
568-
; SSE-NEXT: movq 48(%rdi), %r8
569-
; SSE-NEXT: movq (%rdi), %r9
570-
; SSE-NEXT: movq 8(%rdi), %r10
571-
; SSE-NEXT: movq 32(%rdi), %r11
572-
; SSE-NEXT: orq 96(%rdi), %r11
573-
; SSE-NEXT: orq 64(%rdi), %r9
574-
; SSE-NEXT: orq %r11, %r9
575-
; SSE-NEXT: orq 112(%rdi), %r8
576-
; SSE-NEXT: orq 80(%rdi), %rcx
577-
; SSE-NEXT: orq %r8, %rcx
578-
; SSE-NEXT: orq %r9, %rcx
579-
; SSE-NEXT: orq 104(%rdi), %rsi
580-
; SSE-NEXT: orq 72(%rdi), %r10
581-
; SSE-NEXT: orq %rsi, %r10
582-
; SSE-NEXT: orq 120(%rdi), %rdx
583-
; SSE-NEXT: orq 88(%rdi), %rax
584-
; SSE-NEXT: orq %rdx, %rax
585-
; SSE-NEXT: orq %r10, %rax
586-
; SSE-NEXT: orq %rcx, %rax
587-
; SSE-NEXT: sete %al
588-
; SSE-NEXT: retq
599+
; SSE2-LABEL: vecmp_load512x2:
600+
; SSE2: # %bb.0:
601+
; SSE2-NEXT: movdqu (%rdi), %xmm0
602+
; SSE2-NEXT: movdqu 16(%rdi), %xmm1
603+
; SSE2-NEXT: movdqu 32(%rdi), %xmm2
604+
; SSE2-NEXT: movdqu 48(%rdi), %xmm3
605+
; SSE2-NEXT: movdqu 80(%rdi), %xmm4
606+
; SSE2-NEXT: por %xmm1, %xmm4
607+
; SSE2-NEXT: movdqu 112(%rdi), %xmm1
608+
; SSE2-NEXT: por %xmm3, %xmm1
609+
; SSE2-NEXT: por %xmm4, %xmm1
610+
; SSE2-NEXT: movdqu 64(%rdi), %xmm3
611+
; SSE2-NEXT: por %xmm0, %xmm3
612+
; SSE2-NEXT: movdqu 96(%rdi), %xmm0
613+
; SSE2-NEXT: por %xmm2, %xmm0
614+
; SSE2-NEXT: por %xmm3, %xmm0
615+
; SSE2-NEXT: por %xmm1, %xmm0
616+
; SSE2-NEXT: pxor %xmm1, %xmm1
617+
; SSE2-NEXT: pcmpeqd %xmm0, %xmm1
618+
; SSE2-NEXT: movmskps %xmm1, %eax
619+
; SSE2-NEXT: xorl $15, %eax
620+
; SSE2-NEXT: sete %al
621+
; SSE2-NEXT: retq
622+
;
623+
; SSE41-LABEL: vecmp_load512x2:
624+
; SSE41: # %bb.0:
625+
; SSE41-NEXT: movdqu (%rdi), %xmm0
626+
; SSE41-NEXT: movdqu 16(%rdi), %xmm1
627+
; SSE41-NEXT: movdqu 32(%rdi), %xmm2
628+
; SSE41-NEXT: movdqu 48(%rdi), %xmm3
629+
; SSE41-NEXT: movdqu 80(%rdi), %xmm4
630+
; SSE41-NEXT: por %xmm1, %xmm4
631+
; SSE41-NEXT: movdqu 112(%rdi), %xmm1
632+
; SSE41-NEXT: por %xmm3, %xmm1
633+
; SSE41-NEXT: por %xmm4, %xmm1
634+
; SSE41-NEXT: movdqu 64(%rdi), %xmm3
635+
; SSE41-NEXT: por %xmm0, %xmm3
636+
; SSE41-NEXT: movdqu 96(%rdi), %xmm0
637+
; SSE41-NEXT: por %xmm2, %xmm0
638+
; SSE41-NEXT: por %xmm3, %xmm0
639+
; SSE41-NEXT: por %xmm1, %xmm0
640+
; SSE41-NEXT: ptest %xmm0, %xmm0
641+
; SSE41-NEXT: sete %al
642+
; SSE41-NEXT: retq
589643
;
590644
; AVX1-LABEL: vecmp_load512x2:
591645
; AVX1: # %bb.0:

0 commit comments

Comments
 (0)