mirror of
https://github.com/c64scene-ar/llvm-6502.git
synced 2024-12-28 04:33:05 +00:00
6077ca9abb
1) (AND (shuf (A, C, Mask), shuf (B, C, Mask)) -> shuf (AND (A, B), C, Mask) 2) (OR (shuf (A, C, Mask), shuf (B, C, Mask)) -> shuf (OR (A, B), C, Mask) 3) (XOR (shuf (A, C, Mask), shuf (B, C, Mask)) -> shuf (XOR (A, B), V_0, Mask) 4) (AND (shuf (C, A, Mask), shuf (C, B, Mask)) -> shuf (C, AND (A, B), Mask) 5) (OR (shuf (C, A, Mask), shuf (C, B, Mask)) -> shuf (C, OR (A, B), Mask) 6) (XOR (shuf (C, A, Mask), shuf (C, B, Mask)) -> shuf (V_0, XOR (A, B), Mask) git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@204160 91177308-0d34-0410-b5e6-96231b3b80d8
270 lines
7.8 KiB
LLVM
270 lines
7.8 KiB
LLVM
; RUN: llc < %s -mtriple=x86_64-unknown-linux-gnu -mcpu=corei7 | FileCheck %s
|
|
|
|
|
|
; Verify that each of the following test cases is folded into a single
|
|
; instruction which performs a blend operation.
|
|
|
|
define <2 x i64> @test1(<2 x i64> %a, <2 x i64> %b) {
|
|
%shuf1 = shufflevector <2 x i64> %a, <2 x i64> zeroinitializer, <2 x i32><i32 0, i32 2>
|
|
%shuf2 = shufflevector <2 x i64> %b, <2 x i64> zeroinitializer, <2 x i32><i32 2, i32 1>
|
|
%or = or <2 x i64> %shuf1, %shuf2
|
|
ret <2 x i64> %or
|
|
}
|
|
; CHECK-LABEL: test1
|
|
; CHECK-NOT: xorps
|
|
; CHECK: movsd
|
|
; CHECK-NOT: orps
|
|
; CHECK: ret
|
|
|
|
|
|
define <4 x i32> @test2(<4 x i32> %a, <4 x i32> %b) {
|
|
%shuf1 = shufflevector <4 x i32> %a, <4 x i32> zeroinitializer, <4 x i32><i32 4, i32 4, i32 2, i32 3>
|
|
%shuf2 = shufflevector <4 x i32> %b, <4 x i32> zeroinitializer, <4 x i32><i32 0, i32 1, i32 4, i32 4>
|
|
%or = or <4 x i32> %shuf1, %shuf2
|
|
ret <4 x i32> %or
|
|
}
|
|
; CHECK-LABEL: test2
|
|
; CHECK-NOT: xorps
|
|
; CHECK: shufps
|
|
; CHECK: ret
|
|
|
|
|
|
define <2 x i64> @test3(<2 x i64> %a, <2 x i64> %b) {
|
|
%shuf1 = shufflevector <2 x i64> %a, <2 x i64> zeroinitializer, <2 x i32><i32 2, i32 1>
|
|
%shuf2 = shufflevector <2 x i64> %b, <2 x i64> zeroinitializer, <2 x i32><i32 0, i32 2>
|
|
%or = or <2 x i64> %shuf1, %shuf2
|
|
ret <2 x i64> %or
|
|
}
|
|
; CHECK-LABEL: test3
|
|
; CHECK-NOT: xorps
|
|
; CHECK: movsd
|
|
; CHECK-NEXT: ret
|
|
|
|
|
|
define <4 x i32> @test4(<4 x i32> %a, <4 x i32> %b) {
|
|
%shuf1 = shufflevector <4 x i32> %a, <4 x i32> zeroinitializer, <4 x i32><i32 0, i32 4, i32 4, i32 4>
|
|
%shuf2 = shufflevector <4 x i32> %b, <4 x i32> zeroinitializer, <4 x i32><i32 4, i32 1, i32 2, i32 3>
|
|
%or = or <4 x i32> %shuf1, %shuf2
|
|
ret <4 x i32> %or
|
|
}
|
|
; CHECK-LABEL: test4
|
|
; CHECK-NOT: xorps
|
|
; CHECK: movss
|
|
; CHECK-NOT: orps
|
|
; CHECK: ret
|
|
|
|
|
|
define <4 x i32> @test5(<4 x i32> %a, <4 x i32> %b) {
|
|
%shuf1 = shufflevector <4 x i32> %a, <4 x i32> zeroinitializer, <4 x i32><i32 4, i32 1, i32 2, i32 3>
|
|
%shuf2 = shufflevector <4 x i32> %b, <4 x i32> zeroinitializer, <4 x i32><i32 0, i32 4, i32 4, i32 4>
|
|
%or = or <4 x i32> %shuf1, %shuf2
|
|
ret <4 x i32> %or
|
|
}
|
|
; CHECK-LABEL: test5
|
|
; CHECK-NOT: xorps
|
|
; CHECK: movss
|
|
; CHECK-NEXT: ret
|
|
|
|
|
|
define <4 x i32> @test6(<4 x i32> %a, <4 x i32> %b) {
|
|
%shuf1 = shufflevector <4 x i32> %a, <4 x i32> zeroinitializer, <4 x i32><i32 0, i32 1, i32 4, i32 4>
|
|
%shuf2 = shufflevector <4 x i32> %b, <4 x i32> zeroinitializer, <4 x i32><i32 4, i32 4, i32 2, i32 3>
|
|
%or = or <4 x i32> %shuf1, %shuf2
|
|
ret <4 x i32> %or
|
|
}
|
|
; CHECK-LABEL: test6
|
|
; CHECK-NOT: xorps
|
|
; CHECK: shufps
|
|
; CHECK-NEXT: ret
|
|
|
|
|
|
define <4 x i32> @test7(<4 x i32> %a, <4 x i32> %b) {
|
|
%and1 = and <4 x i32> %a, <i32 -1, i32 -1, i32 0, i32 0>
|
|
%and2 = and <4 x i32> %b, <i32 0, i32 0, i32 -1, i32 -1>
|
|
%or = or <4 x i32> %and1, %and2
|
|
ret <4 x i32> %or
|
|
}
|
|
; CHECK-LABEL: test7
|
|
; CHECK-NOT: xorps
|
|
; CHECK: shufps
|
|
; CHECK-NEXT: ret
|
|
|
|
|
|
define <2 x i64> @test8(<2 x i64> %a, <2 x i64> %b) {
|
|
%and1 = and <2 x i64> %a, <i64 -1, i64 0>
|
|
%and2 = and <2 x i64> %b, <i64 0, i64 -1>
|
|
%or = or <2 x i64> %and1, %and2
|
|
ret <2 x i64> %or
|
|
}
|
|
; CHECK-LABEL: test8
|
|
; CHECK-NOT: xorps
|
|
; CHECK: movsd
|
|
; CHECK-NOT: orps
|
|
; CHECK: ret
|
|
|
|
|
|
define <4 x i32> @test9(<4 x i32> %a, <4 x i32> %b) {
|
|
%and1 = and <4 x i32> %a, <i32 0, i32 0, i32 -1, i32 -1>
|
|
%and2 = and <4 x i32> %b, <i32 -1, i32 -1, i32 0, i32 0>
|
|
%or = or <4 x i32> %and1, %and2
|
|
ret <4 x i32> %or
|
|
}
|
|
; CHECK-LABEL: test9
|
|
; CHECK-NOT: xorps
|
|
; CHECK: shufps
|
|
; CHECK: ret
|
|
|
|
|
|
define <2 x i64> @test10(<2 x i64> %a, <2 x i64> %b) {
|
|
%and1 = and <2 x i64> %a, <i64 0, i64 -1>
|
|
%and2 = and <2 x i64> %b, <i64 -1, i64 0>
|
|
%or = or <2 x i64> %and1, %and2
|
|
ret <2 x i64> %or
|
|
}
|
|
; CHECK-LABEL: test10
|
|
; CHECK-NOT: xorps
|
|
; CHECK: movsd
|
|
; CHECK-NEXT: ret
|
|
|
|
|
|
define <4 x i32> @test11(<4 x i32> %a, <4 x i32> %b) {
|
|
%and1 = and <4 x i32> %a, <i32 -1, i32 0, i32 0, i32 0>
|
|
%and2 = and <4 x i32> %b, <i32 0, i32 -1, i32 -1, i32 -1>
|
|
%or = or <4 x i32> %and1, %and2
|
|
ret <4 x i32> %or
|
|
}
|
|
; CHECK-LABEL: test11
|
|
; CHECK-NOT: xorps
|
|
; CHECK: movss
|
|
; CHECK-NOT: orps
|
|
; CHECK: ret
|
|
|
|
|
|
define <4 x i32> @test12(<4 x i32> %a, <4 x i32> %b) {
|
|
%and1 = and <4 x i32> %a, <i32 0, i32 -1, i32 -1, i32 -1>
|
|
%and2 = and <4 x i32> %b, <i32 -1, i32 0, i32 0, i32 0>
|
|
%or = or <4 x i32> %and1, %and2
|
|
ret <4 x i32> %or
|
|
}
|
|
; CHECK-LABEL: test12
|
|
; CHECK-NOT: xorps
|
|
; CHECK: movss
|
|
; CHECK-NEXT: ret
|
|
|
|
|
|
; Verify that the following test cases are folded into single shuffles.
|
|
|
|
define <4 x i32> @test13(<4 x i32> %a, <4 x i32> %b) {
|
|
%shuf1 = shufflevector <4 x i32> %a, <4 x i32> zeroinitializer, <4 x i32><i32 1, i32 1, i32 4, i32 4>
|
|
%shuf2 = shufflevector <4 x i32> %b, <4 x i32> zeroinitializer, <4 x i32><i32 4, i32 4, i32 2, i32 3>
|
|
%or = or <4 x i32> %shuf1, %shuf2
|
|
ret <4 x i32> %or
|
|
}
|
|
; CHECK-LABEL: test13
|
|
; CHECK-NOT: xorps
|
|
; CHECK: shufps
|
|
; CHECK-NEXT: ret
|
|
|
|
|
|
define <2 x i64> @test14(<2 x i64> %a, <2 x i64> %b) {
|
|
%shuf1 = shufflevector <2 x i64> %a, <2 x i64> zeroinitializer, <2 x i32><i32 0, i32 2>
|
|
%shuf2 = shufflevector <2 x i64> %b, <2 x i64> zeroinitializer, <2 x i32><i32 2, i32 0>
|
|
%or = or <2 x i64> %shuf1, %shuf2
|
|
ret <2 x i64> %or
|
|
}
|
|
; CHECK-LABEL: test14
|
|
; CHECK-NOT: pslldq
|
|
; CHECK-NOT: por
|
|
; CHECK: punpcklqdq
|
|
; CHECK-NEXT: ret
|
|
|
|
|
|
define <4 x i32> @test15(<4 x i32> %a, <4 x i32> %b) {
|
|
%shuf1 = shufflevector <4 x i32> %a, <4 x i32> zeroinitializer, <4 x i32><i32 4, i32 4, i32 2, i32 1>
|
|
%shuf2 = shufflevector <4 x i32> %b, <4 x i32> zeroinitializer, <4 x i32><i32 2, i32 1, i32 4, i32 4>
|
|
%or = or <4 x i32> %shuf1, %shuf2
|
|
ret <4 x i32> %or
|
|
}
|
|
; CHECK-LABEL: test15
|
|
; CHECK-NOT: xorps
|
|
; CHECK: shufps
|
|
; CHECK-NOT: shufps
|
|
; CHECK-NOT: orps
|
|
; CHECK: ret
|
|
|
|
|
|
define <2 x i64> @test16(<2 x i64> %a, <2 x i64> %b) {
|
|
%shuf1 = shufflevector <2 x i64> %a, <2 x i64> zeroinitializer, <2 x i32><i32 2, i32 0>
|
|
%shuf2 = shufflevector <2 x i64> %b, <2 x i64> zeroinitializer, <2 x i32><i32 0, i32 2>
|
|
%or = or <2 x i64> %shuf1, %shuf2
|
|
ret <2 x i64> %or
|
|
}
|
|
; CHECK-LABEL: test16
|
|
; CHECK-NOT: pslldq
|
|
; CHECK-NOT: por
|
|
; CHECK: punpcklqdq
|
|
; CHECK: ret
|
|
|
|
|
|
; Verify that the dag-combiner does not fold a OR of two shuffles into a single
|
|
; shuffle instruction when the shuffle indexes are not compatible.
|
|
|
|
define <4 x i32> @test17(<4 x i32> %a, <4 x i32> %b) {
|
|
%shuf1 = shufflevector <4 x i32> %a, <4 x i32> zeroinitializer, <4 x i32><i32 4, i32 0, i32 4, i32 2>
|
|
%shuf2 = shufflevector <4 x i32> %b, <4 x i32> zeroinitializer, <4 x i32><i32 0, i32 1, i32 4, i32 4>
|
|
%or = or <4 x i32> %shuf1, %shuf2
|
|
ret <4 x i32> %or
|
|
}
|
|
; CHECK-LABEL: test17
|
|
; CHECK: por
|
|
; CHECK-NEXT: ret
|
|
|
|
|
|
define <4 x i32> @test18(<4 x i32> %a, <4 x i32> %b) {
|
|
%shuf1 = shufflevector <4 x i32> %a, <4 x i32> zeroinitializer, <4 x i32><i32 4, i32 0, i32 4, i32 4>
|
|
%shuf2 = shufflevector <4 x i32> %b, <4 x i32> zeroinitializer, <4 x i32><i32 0, i32 4, i32 4, i32 4>
|
|
%or = or <4 x i32> %shuf1, %shuf2
|
|
ret <4 x i32> %or
|
|
}
|
|
; CHECK-LABEL: test18
|
|
; CHECK: orps
|
|
; CHECK: ret
|
|
|
|
|
|
define <4 x i32> @test19(<4 x i32> %a, <4 x i32> %b) {
|
|
%shuf1 = shufflevector <4 x i32> %a, <4 x i32> zeroinitializer, <4 x i32><i32 4, i32 0, i32 4, i32 3>
|
|
%shuf2 = shufflevector <4 x i32> %b, <4 x i32> zeroinitializer, <4 x i32><i32 0, i32 4, i32 2, i32 2>
|
|
%or = or <4 x i32> %shuf1, %shuf2
|
|
ret <4 x i32> %or
|
|
}
|
|
; CHECK-LABEL: test19
|
|
; CHECK: por
|
|
; CHECK-NEXT: ret
|
|
|
|
|
|
define <2 x i64> @test20(<2 x i64> %a, <2 x i64> %b) {
|
|
%shuf1 = shufflevector <2 x i64> %a, <2 x i64> zeroinitializer, <2 x i32><i32 0, i32 2>
|
|
%shuf2 = shufflevector <2 x i64> %b, <2 x i64> zeroinitializer, <2 x i32><i32 0, i32 2>
|
|
%or = or <2 x i64> %shuf1, %shuf2
|
|
ret <2 x i64> %or
|
|
}
|
|
; CHECK-LABEL: test20
|
|
; CHECK-NOT: xorps
|
|
; CHECK: orps
|
|
; CHECK-NEXT: movq
|
|
; CHECK-NEXT: ret
|
|
|
|
|
|
define <2 x i64> @test21(<2 x i64> %a, <2 x i64> %b) {
|
|
%shuf1 = shufflevector <2 x i64> %a, <2 x i64> zeroinitializer, <2 x i32><i32 2, i32 0>
|
|
%shuf2 = shufflevector <2 x i64> %b, <2 x i64> zeroinitializer, <2 x i32><i32 2, i32 0>
|
|
%or = or <2 x i64> %shuf1, %shuf2
|
|
ret <2 x i64> %or
|
|
}
|
|
; CHECK-LABEL: test21
|
|
; CHECK: por
|
|
; CHECK-NEXT: pslldq
|
|
; CHECK-NEXT: ret
|
|
|
|
|