llvm-project/llvm/test/CodeGen/X86/widen_arith-2.ll
Simon Pilgrim ad45efc445 [X86][SSE] Consistently prefer lowering to PACKUS over PACKSS
We have some combines/lowerings that attempt to use PACKSS-then-PACKUS and others that use PACKUS-then-PACKSS.

PACKUS is much easier to combine with if we know the upper bits are zero as ComputeKnownBits can easily see through BITCASTs etc. especially now that rL333995 and rL334007 have landed. It also effectively works at byte level which further simplifies shuffle combines.

The only (minor) annoyances are that ComputeKnownBits can sometimes take longer as it doesn't fail as quickly as ComputeNumSignBits (but I'm not seeing any actual regressions in tests) and PACKUSDW only became available after SSE41 so we have more codegen diffs between targets.

llvm-svn: 334276
2018-06-08 10:29:00 +00:00

90 lines
3.0 KiB
LLVM

; NOTE: Assertions have been autogenerated by utils/update_llc_test_checks.py
; RUN: llc < %s -mtriple=i686-unknown-unknown -mattr=+sse4.2 | FileCheck %s
; widen v8i8 to v16i8 (checks even power of 2 widening with add & and)
define void @update(i64* %dst_i, i64* %src_i, i32 %n) nounwind {
; CHECK-LABEL: update:
; CHECK: # %bb.0: # %entry
; CHECK-NEXT: subl $12, %esp
; CHECK-NEXT: movl $0, (%esp)
; CHECK-NEXT: pcmpeqd %xmm0, %xmm0
; CHECK-NEXT: movdqa {{.*#+}} xmm1 = [4,4,4,4,4,4,4,4]
; CHECK-NEXT: jmp .LBB0_1
; CHECK-NEXT: .p2align 4, 0x90
; CHECK-NEXT: .LBB0_2: # %forbody
; CHECK-NEXT: # in Loop: Header=BB0_1 Depth=1
; CHECK-NEXT: movl (%esp), %eax
; CHECK-NEXT: leal (,%eax,8), %ecx
; CHECK-NEXT: movl {{[0-9]+}}(%esp), %edx
; CHECK-NEXT: addl %ecx, %edx
; CHECK-NEXT: movl %edx, {{[0-9]+}}(%esp)
; CHECK-NEXT: addl {{[0-9]+}}(%esp), %ecx
; CHECK-NEXT: movl %ecx, {{[0-9]+}}(%esp)
; CHECK-NEXT: pmovzxbw {{.*#+}} xmm2 = mem[0],zero,mem[1],zero,mem[2],zero,mem[3],zero,mem[4],zero,mem[5],zero,mem[6],zero,mem[7],zero
; CHECK-NEXT: psubw %xmm0, %xmm2
; CHECK-NEXT: pand %xmm1, %xmm2
; CHECK-NEXT: packuswb %xmm0, %xmm2
; CHECK-NEXT: movq %xmm2, (%edx,%eax,8)
; CHECK-NEXT: incl (%esp)
; CHECK-NEXT: .LBB0_1: # %forcond
; CHECK-NEXT: # =>This Inner Loop Header: Depth=1
; CHECK-NEXT: movl (%esp), %eax
; CHECK-NEXT: cmpl {{[0-9]+}}(%esp), %eax
; CHECK-NEXT: jl .LBB0_2
; CHECK-NEXT: # %bb.3: # %afterfor
; CHECK-NEXT: addl $12, %esp
; CHECK-NEXT: retl
entry:
%dst_i.addr = alloca i64*
%src_i.addr = alloca i64*
%n.addr = alloca i32
%i = alloca i32, align 4
%dst = alloca <8 x i8>*, align 4
%src = alloca <8 x i8>*, align 4
store i64* %dst_i, i64** %dst_i.addr
store i64* %src_i, i64** %src_i.addr
store i32 %n, i32* %n.addr
store i32 0, i32* %i
br label %forcond
forcond:
%tmp = load i32, i32* %i
%tmp1 = load i32, i32* %n.addr
%cmp = icmp slt i32 %tmp, %tmp1
br i1 %cmp, label %forbody, label %afterfor
forbody:
%tmp2 = load i32, i32* %i
%tmp3 = load i64*, i64** %dst_i.addr
%arrayidx = getelementptr i64, i64* %tmp3, i32 %tmp2
%conv = bitcast i64* %arrayidx to <8 x i8>*
store <8 x i8>* %conv, <8 x i8>** %dst
%tmp4 = load i32, i32* %i
%tmp5 = load i64*, i64** %src_i.addr
%arrayidx6 = getelementptr i64, i64* %tmp5, i32 %tmp4
%conv7 = bitcast i64* %arrayidx6 to <8 x i8>*
store <8 x i8>* %conv7, <8 x i8>** %src
%tmp8 = load i32, i32* %i
%tmp9 = load <8 x i8>*, <8 x i8>** %dst
%arrayidx10 = getelementptr <8 x i8>, <8 x i8>* %tmp9, i32 %tmp8
%tmp11 = load i32, i32* %i
%tmp12 = load <8 x i8>*, <8 x i8>** %src
%arrayidx13 = getelementptr <8 x i8>, <8 x i8>* %tmp12, i32 %tmp11
%tmp14 = load <8 x i8>, <8 x i8>* %arrayidx13
%add = add <8 x i8> %tmp14, < i8 1, i8 1, i8 1, i8 1, i8 1, i8 1, i8 1, i8 1 >
%and = and <8 x i8> %add, < i8 4, i8 4, i8 4, i8 4, i8 4, i8 4, i8 4, i8 4 >
store <8 x i8> %and, <8 x i8>* %arrayidx10
br label %forinc
forinc:
%tmp15 = load i32, i32* %i
%inc = add i32 %tmp15, 1
store i32 %inc, i32* %i
br label %forcond
afterfor:
ret void
}