The assert that caused this to be reverted should be fixed now. Original commit message: This patch changes our defualt legalization behavior for 16, 32, and 64 bit vectors with i8/i16/i32/i64 scalar types from promotion to widening. For example, v8i8 will now be widened to v16i8 instead of promoted to v8i16. This keeps the elements widths the same and pads with undef elements. We believe this is a better legalization strategy. But it carries some issues due to the fragmented vector ISA. For example, i8 shifts and multiplies get widened and then later have to be promoted/split into vXi16 vectors. This has the potential to cause regressions so we wanted to get it in early in the 10.0 cycle so we have plenty of time to address them. Next steps will be to merge tests that explicitly test the command line option. And then we can remove the option and its associated code. llvm-svn: 368183
427 lines
12 KiB
LLVM
427 lines
12 KiB
LLVM
; NOTE: Assertions have been autogenerated by utils/update_llc_test_checks.py
|
|
; RUN: llc -mtriple=i686-unknown < %s | FileCheck %s --check-prefix=X32
|
|
; RUN: llc -mtriple=x86_64-unknown < %s | FileCheck %s --check-prefix=X64
|
|
|
|
@array = weak global [4 x i32] zeroinitializer
|
|
|
|
define i32 @test_lshr_and(i32 %x) {
|
|
; X32-LABEL: test_lshr_and:
|
|
; X32: # %bb.0:
|
|
; X32-NEXT: movl {{[0-9]+}}(%esp), %eax
|
|
; X32-NEXT: andl $12, %eax
|
|
; X32-NEXT: movl array(%eax), %eax
|
|
; X32-NEXT: retl
|
|
;
|
|
; X64-LABEL: test_lshr_and:
|
|
; X64: # %bb.0:
|
|
; X64-NEXT: # kill: def $edi killed $edi def $rdi
|
|
; X64-NEXT: shrl $2, %edi
|
|
; X64-NEXT: andl $3, %edi
|
|
; X64-NEXT: movl array(,%rdi,4), %eax
|
|
; X64-NEXT: retq
|
|
%tmp2 = lshr i32 %x, 2
|
|
%tmp3 = and i32 %tmp2, 3
|
|
%tmp4 = getelementptr [4 x i32], [4 x i32]* @array, i32 0, i32 %tmp3
|
|
%tmp5 = load i32, i32* %tmp4, align 4
|
|
ret i32 %tmp5
|
|
}
|
|
|
|
define i32* @test_exact1(i32 %a, i32 %b, i32* %x) {
|
|
; X32-LABEL: test_exact1:
|
|
; X32: # %bb.0:
|
|
; X32-NEXT: movl {{[0-9]+}}(%esp), %eax
|
|
; X32-NEXT: subl {{[0-9]+}}(%esp), %eax
|
|
; X32-NEXT: sarl %eax
|
|
; X32-NEXT: addl {{[0-9]+}}(%esp), %eax
|
|
; X32-NEXT: retl
|
|
;
|
|
; X64-LABEL: test_exact1:
|
|
; X64: # %bb.0:
|
|
; X64-NEXT: subl %edi, %esi
|
|
; X64-NEXT: sarl $3, %esi
|
|
; X64-NEXT: movslq %esi, %rax
|
|
; X64-NEXT: leaq (%rdx,%rax,4), %rax
|
|
; X64-NEXT: retq
|
|
%sub = sub i32 %b, %a
|
|
%shr = ashr exact i32 %sub, 3
|
|
%gep = getelementptr inbounds i32, i32* %x, i32 %shr
|
|
ret i32* %gep
|
|
}
|
|
|
|
define i32* @test_exact2(i32 %a, i32 %b, i32* %x) {
|
|
; X32-LABEL: test_exact2:
|
|
; X32: # %bb.0:
|
|
; X32-NEXT: movl {{[0-9]+}}(%esp), %eax
|
|
; X32-NEXT: subl {{[0-9]+}}(%esp), %eax
|
|
; X32-NEXT: sarl %eax
|
|
; X32-NEXT: addl {{[0-9]+}}(%esp), %eax
|
|
; X32-NEXT: retl
|
|
;
|
|
; X64-LABEL: test_exact2:
|
|
; X64: # %bb.0:
|
|
; X64-NEXT: subl %edi, %esi
|
|
; X64-NEXT: sarl $3, %esi
|
|
; X64-NEXT: movslq %esi, %rax
|
|
; X64-NEXT: leaq (%rdx,%rax,4), %rax
|
|
; X64-NEXT: retq
|
|
%sub = sub i32 %b, %a
|
|
%shr = ashr exact i32 %sub, 3
|
|
%gep = getelementptr inbounds i32, i32* %x, i32 %shr
|
|
ret i32* %gep
|
|
}
|
|
|
|
define i32* @test_exact3(i32 %a, i32 %b, i32* %x) {
|
|
; X32-LABEL: test_exact3:
|
|
; X32: # %bb.0:
|
|
; X32-NEXT: movl {{[0-9]+}}(%esp), %eax
|
|
; X32-NEXT: subl {{[0-9]+}}(%esp), %eax
|
|
; X32-NEXT: addl {{[0-9]+}}(%esp), %eax
|
|
; X32-NEXT: retl
|
|
;
|
|
; X64-LABEL: test_exact3:
|
|
; X64: # %bb.0:
|
|
; X64-NEXT: subl %edi, %esi
|
|
; X64-NEXT: sarl $2, %esi
|
|
; X64-NEXT: movslq %esi, %rax
|
|
; X64-NEXT: leaq (%rdx,%rax,4), %rax
|
|
; X64-NEXT: retq
|
|
%sub = sub i32 %b, %a
|
|
%shr = ashr exact i32 %sub, 2
|
|
%gep = getelementptr inbounds i32, i32* %x, i32 %shr
|
|
ret i32* %gep
|
|
}
|
|
|
|
define i32* @test_exact4(i32 %a, i32 %b, i32* %x) {
|
|
; X32-LABEL: test_exact4:
|
|
; X32: # %bb.0:
|
|
; X32-NEXT: movl {{[0-9]+}}(%esp), %eax
|
|
; X32-NEXT: subl {{[0-9]+}}(%esp), %eax
|
|
; X32-NEXT: shrl %eax
|
|
; X32-NEXT: addl {{[0-9]+}}(%esp), %eax
|
|
; X32-NEXT: retl
|
|
;
|
|
; X64-LABEL: test_exact4:
|
|
; X64: # %bb.0:
|
|
; X64-NEXT: # kill: def $esi killed $esi def $rsi
|
|
; X64-NEXT: subl %edi, %esi
|
|
; X64-NEXT: shrl $3, %esi
|
|
; X64-NEXT: leaq (%rdx,%rsi,4), %rax
|
|
; X64-NEXT: retq
|
|
%sub = sub i32 %b, %a
|
|
%shr = lshr exact i32 %sub, 3
|
|
%gep = getelementptr inbounds i32, i32* %x, i32 %shr
|
|
ret i32* %gep
|
|
}
|
|
|
|
define i32* @test_exact5(i32 %a, i32 %b, i32* %x) {
|
|
; X32-LABEL: test_exact5:
|
|
; X32: # %bb.0:
|
|
; X32-NEXT: movl {{[0-9]+}}(%esp), %eax
|
|
; X32-NEXT: subl {{[0-9]+}}(%esp), %eax
|
|
; X32-NEXT: shrl %eax
|
|
; X32-NEXT: addl {{[0-9]+}}(%esp), %eax
|
|
; X32-NEXT: retl
|
|
;
|
|
; X64-LABEL: test_exact5:
|
|
; X64: # %bb.0:
|
|
; X64-NEXT: # kill: def $esi killed $esi def $rsi
|
|
; X64-NEXT: subl %edi, %esi
|
|
; X64-NEXT: shrl $3, %esi
|
|
; X64-NEXT: leaq (%rdx,%rsi,4), %rax
|
|
; X64-NEXT: retq
|
|
%sub = sub i32 %b, %a
|
|
%shr = lshr exact i32 %sub, 3
|
|
%gep = getelementptr inbounds i32, i32* %x, i32 %shr
|
|
ret i32* %gep
|
|
}
|
|
|
|
define i32* @test_exact6(i32 %a, i32 %b, i32* %x) {
|
|
; X32-LABEL: test_exact6:
|
|
; X32: # %bb.0:
|
|
; X32-NEXT: movl {{[0-9]+}}(%esp), %eax
|
|
; X32-NEXT: subl {{[0-9]+}}(%esp), %eax
|
|
; X32-NEXT: addl {{[0-9]+}}(%esp), %eax
|
|
; X32-NEXT: retl
|
|
;
|
|
; X64-LABEL: test_exact6:
|
|
; X64: # %bb.0:
|
|
; X64-NEXT: # kill: def $esi killed $esi def $rsi
|
|
; X64-NEXT: subl %edi, %esi
|
|
; X64-NEXT: leaq (%rsi,%rdx), %rax
|
|
; X64-NEXT: retq
|
|
%sub = sub i32 %b, %a
|
|
%shr = lshr exact i32 %sub, 2
|
|
%gep = getelementptr inbounds i32, i32* %x, i32 %shr
|
|
ret i32* %gep
|
|
}
|
|
|
|
; PR42644 - https://bugs.llvm.org/show_bug.cgi?id=42644
|
|
|
|
define i64 @ashr_add_shl_i32(i64 %r) nounwind {
|
|
; X32-LABEL: ashr_add_shl_i32:
|
|
; X32: # %bb.0:
|
|
; X32-NEXT: movl {{[0-9]+}}(%esp), %eax
|
|
; X32-NEXT: incl %eax
|
|
; X32-NEXT: movl %eax, %edx
|
|
; X32-NEXT: sarl $31, %edx
|
|
; X32-NEXT: retl
|
|
;
|
|
; X64-LABEL: ashr_add_shl_i32:
|
|
; X64: # %bb.0:
|
|
; X64-NEXT: incl %edi
|
|
; X64-NEXT: movslq %edi, %rax
|
|
; X64-NEXT: retq
|
|
%conv = shl i64 %r, 32
|
|
%sext = add i64 %conv, 4294967296
|
|
%conv1 = ashr i64 %sext, 32
|
|
ret i64 %conv1
|
|
}
|
|
|
|
define i64 @ashr_add_shl_i8(i64 %r) nounwind {
|
|
; X32-LABEL: ashr_add_shl_i8:
|
|
; X32: # %bb.0:
|
|
; X32-NEXT: movb {{[0-9]+}}(%esp), %al
|
|
; X32-NEXT: addb $2, %al
|
|
; X32-NEXT: movsbl %al, %eax
|
|
; X32-NEXT: movl %eax, %edx
|
|
; X32-NEXT: sarl $31, %edx
|
|
; X32-NEXT: retl
|
|
;
|
|
; X64-LABEL: ashr_add_shl_i8:
|
|
; X64: # %bb.0:
|
|
; X64-NEXT: addb $2, %dil
|
|
; X64-NEXT: movsbq %dil, %rax
|
|
; X64-NEXT: retq
|
|
%conv = shl i64 %r, 56
|
|
%sext = add i64 %conv, 144115188075855872
|
|
%conv1 = ashr i64 %sext, 56
|
|
ret i64 %conv1
|
|
}
|
|
|
|
define <4 x i32> @ashr_add_shl_v4i8(<4 x i32> %r) nounwind {
|
|
; X32-LABEL: ashr_add_shl_v4i8:
|
|
; X32: # %bb.0:
|
|
; X32-NEXT: pushl %edi
|
|
; X32-NEXT: pushl %esi
|
|
; X32-NEXT: movl {{[0-9]+}}(%esp), %eax
|
|
; X32-NEXT: movb {{[0-9]+}}(%esp), %cl
|
|
; X32-NEXT: movb {{[0-9]+}}(%esp), %dl
|
|
; X32-NEXT: movb {{[0-9]+}}(%esp), %ch
|
|
; X32-NEXT: movb {{[0-9]+}}(%esp), %dh
|
|
; X32-NEXT: incb %dh
|
|
; X32-NEXT: movsbl %dh, %esi
|
|
; X32-NEXT: incb %ch
|
|
; X32-NEXT: movsbl %ch, %edi
|
|
; X32-NEXT: incb %dl
|
|
; X32-NEXT: movsbl %dl, %edx
|
|
; X32-NEXT: incb %cl
|
|
; X32-NEXT: movsbl %cl, %ecx
|
|
; X32-NEXT: movl %ecx, 12(%eax)
|
|
; X32-NEXT: movl %edx, 8(%eax)
|
|
; X32-NEXT: movl %edi, 4(%eax)
|
|
; X32-NEXT: movl %esi, (%eax)
|
|
; X32-NEXT: popl %esi
|
|
; X32-NEXT: popl %edi
|
|
; X32-NEXT: retl $4
|
|
;
|
|
; X64-LABEL: ashr_add_shl_v4i8:
|
|
; X64: # %bb.0:
|
|
; X64-NEXT: pand {{.*}}(%rip), %xmm0
|
|
; X64-NEXT: packuswb %xmm0, %xmm0
|
|
; X64-NEXT: packuswb %xmm0, %xmm0
|
|
; X64-NEXT: pcmpeqd %xmm1, %xmm1
|
|
; X64-NEXT: psubb %xmm1, %xmm0
|
|
; X64-NEXT: punpcklbw {{.*#+}} xmm0 = xmm0[0,0,1,1,2,2,3,3,4,4,5,5,6,6,7,7]
|
|
; X64-NEXT: punpcklwd {{.*#+}} xmm0 = xmm0[0,0,1,1,2,2,3,3]
|
|
; X64-NEXT: psrad $24, %xmm0
|
|
; X64-NEXT: retq
|
|
%conv = shl <4 x i32> %r, <i32 24, i32 24, i32 24, i32 24>
|
|
%sext = add <4 x i32> %conv, <i32 16777216, i32 16777216, i32 16777216, i32 16777216>
|
|
%conv1 = ashr <4 x i32> %sext, <i32 24, i32 24, i32 24, i32 24>
|
|
ret <4 x i32> %conv1
|
|
}
|
|
|
|
define i64 @ashr_add_shl_i36(i64 %r) nounwind {
|
|
; X32-LABEL: ashr_add_shl_i36:
|
|
; X32: # %bb.0:
|
|
; X32-NEXT: movl {{[0-9]+}}(%esp), %edx
|
|
; X32-NEXT: shll $4, %edx
|
|
; X32-NEXT: movl %edx, %eax
|
|
; X32-NEXT: sarl $4, %eax
|
|
; X32-NEXT: sarl $31, %edx
|
|
; X32-NEXT: retl
|
|
;
|
|
; X64-LABEL: ashr_add_shl_i36:
|
|
; X64: # %bb.0:
|
|
; X64-NEXT: movq %rdi, %rax
|
|
; X64-NEXT: shlq $36, %rax
|
|
; X64-NEXT: sarq $36, %rax
|
|
; X64-NEXT: retq
|
|
%conv = shl i64 %r, 36
|
|
%sext = add i64 %conv, 4294967296
|
|
%conv1 = ashr i64 %sext, 36
|
|
ret i64 %conv1
|
|
}
|
|
|
|
define i64 @ashr_add_shl_mismatch_shifts1(i64 %r) nounwind {
|
|
; X32-LABEL: ashr_add_shl_mismatch_shifts1:
|
|
; X32: # %bb.0:
|
|
; X32-NEXT: movl {{[0-9]+}}(%esp), %eax
|
|
; X32-NEXT: incl %eax
|
|
; X32-NEXT: movl %eax, %edx
|
|
; X32-NEXT: sarl $31, %edx
|
|
; X32-NEXT: retl
|
|
;
|
|
; X64-LABEL: ashr_add_shl_mismatch_shifts1:
|
|
; X64: # %bb.0:
|
|
; X64-NEXT: shlq $8, %rdi
|
|
; X64-NEXT: movabsq $4294967296, %rax # imm = 0x100000000
|
|
; X64-NEXT: addq %rdi, %rax
|
|
; X64-NEXT: sarq $32, %rax
|
|
; X64-NEXT: retq
|
|
%conv = shl i64 %r, 8
|
|
%sext = add i64 %conv, 4294967296
|
|
%conv1 = ashr i64 %sext, 32
|
|
ret i64 %conv1
|
|
}
|
|
|
|
define i64 @ashr_add_shl_mismatch_shifts2(i64 %r) nounwind {
|
|
; X32-LABEL: ashr_add_shl_mismatch_shifts2:
|
|
; X32: # %bb.0:
|
|
; X32-NEXT: movl {{[0-9]+}}(%esp), %eax
|
|
; X32-NEXT: movl {{[0-9]+}}(%esp), %edx
|
|
; X32-NEXT: shrdl $8, %edx, %eax
|
|
; X32-NEXT: shrl $8, %edx
|
|
; X32-NEXT: incl %edx
|
|
; X32-NEXT: shrdl $8, %edx, %eax
|
|
; X32-NEXT: shrl $8, %edx
|
|
; X32-NEXT: retl
|
|
;
|
|
; X64-LABEL: ashr_add_shl_mismatch_shifts2:
|
|
; X64: # %bb.0:
|
|
; X64-NEXT: shrq $8, %rdi
|
|
; X64-NEXT: movabsq $4294967296, %rax # imm = 0x100000000
|
|
; X64-NEXT: addq %rdi, %rax
|
|
; X64-NEXT: shrq $8, %rax
|
|
; X64-NEXT: retq
|
|
%conv = lshr i64 %r, 8
|
|
%sext = add i64 %conv, 4294967296
|
|
%conv1 = ashr i64 %sext, 8
|
|
ret i64 %conv1
|
|
}
|
|
|
|
define i32 @ashr_add_shl_i32_i8_extra_use1(i32 %r, i32* %p) nounwind {
|
|
; X32-LABEL: ashr_add_shl_i32_i8_extra_use1:
|
|
; X32: # %bb.0:
|
|
; X32-NEXT: movl {{[0-9]+}}(%esp), %ecx
|
|
; X32-NEXT: movl {{[0-9]+}}(%esp), %eax
|
|
; X32-NEXT: shll $24, %eax
|
|
; X32-NEXT: addl $33554432, %eax # imm = 0x2000000
|
|
; X32-NEXT: movl %eax, (%ecx)
|
|
; X32-NEXT: sarl $24, %eax
|
|
; X32-NEXT: retl
|
|
;
|
|
; X64-LABEL: ashr_add_shl_i32_i8_extra_use1:
|
|
; X64: # %bb.0:
|
|
; X64-NEXT: movl %edi, %eax
|
|
; X64-NEXT: shll $24, %eax
|
|
; X64-NEXT: addl $33554432, %eax # imm = 0x2000000
|
|
; X64-NEXT: movl %eax, (%rsi)
|
|
; X64-NEXT: sarl $24, %eax
|
|
; X64-NEXT: retq
|
|
%conv = shl i32 %r, 24
|
|
%sext = add i32 %conv, 33554432
|
|
store i32 %sext, i32* %p
|
|
%conv1 = ashr i32 %sext, 24
|
|
ret i32 %conv1
|
|
}
|
|
|
|
define i32 @ashr_add_shl_i32_i8_extra_use2(i32 %r, i32* %p) nounwind {
|
|
; X32-LABEL: ashr_add_shl_i32_i8_extra_use2:
|
|
; X32: # %bb.0:
|
|
; X32-NEXT: movl {{[0-9]+}}(%esp), %ecx
|
|
; X32-NEXT: movl {{[0-9]+}}(%esp), %eax
|
|
; X32-NEXT: shll $24, %eax
|
|
; X32-NEXT: movl %eax, (%ecx)
|
|
; X32-NEXT: addl $33554432, %eax # imm = 0x2000000
|
|
; X32-NEXT: sarl $24, %eax
|
|
; X32-NEXT: retl
|
|
;
|
|
; X64-LABEL: ashr_add_shl_i32_i8_extra_use2:
|
|
; X64: # %bb.0:
|
|
; X64-NEXT: # kill: def $edi killed $edi def $rdi
|
|
; X64-NEXT: shll $24, %edi
|
|
; X64-NEXT: movl %edi, (%rsi)
|
|
; X64-NEXT: leal 33554432(%rdi), %eax
|
|
; X64-NEXT: sarl $24, %eax
|
|
; X64-NEXT: retq
|
|
%conv = shl i32 %r, 24
|
|
store i32 %conv, i32* %p
|
|
%sext = add i32 %conv, 33554432
|
|
%conv1 = ashr i32 %sext, 24
|
|
ret i32 %conv1
|
|
}
|
|
|
|
define i32 @ashr_add_shl_i32_i8_extra_use3(i32 %r, i32* %p1, i32* %p2) nounwind {
|
|
; X32-LABEL: ashr_add_shl_i32_i8_extra_use3:
|
|
; X32: # %bb.0:
|
|
; X32-NEXT: movl {{[0-9]+}}(%esp), %ecx
|
|
; X32-NEXT: movl {{[0-9]+}}(%esp), %edx
|
|
; X32-NEXT: movl {{[0-9]+}}(%esp), %eax
|
|
; X32-NEXT: shll $24, %eax
|
|
; X32-NEXT: movl %eax, (%edx)
|
|
; X32-NEXT: addl $33554432, %eax # imm = 0x2000000
|
|
; X32-NEXT: movl %eax, (%ecx)
|
|
; X32-NEXT: sarl $24, %eax
|
|
; X32-NEXT: retl
|
|
;
|
|
; X64-LABEL: ashr_add_shl_i32_i8_extra_use3:
|
|
; X64: # %bb.0:
|
|
; X64-NEXT: movl %edi, %eax
|
|
; X64-NEXT: shll $24, %eax
|
|
; X64-NEXT: movl %eax, (%rsi)
|
|
; X64-NEXT: addl $33554432, %eax # imm = 0x2000000
|
|
; X64-NEXT: movl %eax, (%rdx)
|
|
; X64-NEXT: sarl $24, %eax
|
|
; X64-NEXT: retq
|
|
%conv = shl i32 %r, 24
|
|
store i32 %conv, i32* %p1
|
|
%sext = add i32 %conv, 33554432
|
|
store i32 %sext, i32* %p2
|
|
%conv1 = ashr i32 %sext, 24
|
|
ret i32 %conv1
|
|
}
|
|
|
|
%"class.QPainterPath" = type { double, double, i32 }
|
|
|
|
define void @PR42880(i32 %t0) {
|
|
; X32-LABEL: PR42880:
|
|
; X32: # %bb.0:
|
|
; X32-NEXT: xorl %eax, %eax
|
|
; X32-NEXT: testb %al, %al
|
|
; X32-NEXT: je .LBB16_1
|
|
; X32-NEXT: # %bb.2: # %if
|
|
; X32-NEXT: .LBB16_1: # %then
|
|
;
|
|
; X64-LABEL: PR42880:
|
|
; X64: # %bb.0:
|
|
; X64-NEXT: xorl %eax, %eax
|
|
; X64-NEXT: testb %al, %al
|
|
; X64-NEXT: je .LBB16_1
|
|
; X64-NEXT: # %bb.2: # %if
|
|
; X64-NEXT: .LBB16_1: # %then
|
|
%sub = add nsw i32 %t0, -1
|
|
%add.ptr.i94 = getelementptr inbounds %"class.QPainterPath", %"class.QPainterPath"* null, i32 %sub
|
|
%x = ptrtoint %"class.QPainterPath"* %add.ptr.i94 to i32
|
|
%sub2 = sub i32 %x, 0
|
|
%div = sdiv exact i32 %sub2, 24
|
|
br i1 undef, label %if, label %then
|
|
|
|
then:
|
|
%t1 = xor i32 %div, -1
|
|
unreachable
|
|
|
|
if:
|
|
unreachable
|
|
}
|