[AArch64][GlobalISel] Legalize G_VECREDUCE_AND.

These are handled identically to the already handled G_VECREDUCE_OR instructions.
This commit is contained in:
Amara Emerson 2021-10-04 21:47:04 -07:00
parent 0bd4365445
commit 3fe475367c
4 changed files with 975 additions and 3 deletions

View File

@ -715,7 +715,7 @@ AArch64LegalizerInfo::AArch64LegalizerInfo(const AArch64Subtarget &ST)
.clampMaxNumElements(1, s32, 4)
.lower();
getActionDefinitionsBuilder(G_VECREDUCE_OR)
getActionDefinitionsBuilder({G_VECREDUCE_OR, G_VECREDUCE_AND})
// Try to break down into smaller vectors as long as they're at least 64
// bits. This lets us use vector operations for some parts of the
// reduction.

View File

@ -0,0 +1,653 @@
# NOTE: Assertions have been autogenerated by utils/update_mir_test_checks.py
# RUN: llc -O0 -march=aarch64 -run-pass=legalizer -global-isel-abort=1 -verify-machineinstrs %s -o - | FileCheck %s
---
name: test_redand_v1i1
alignment: 4
tracksRegLiveness: true
liveins:
- { reg: '$w0' }
body: |
bb.1:
liveins: $w0
; CHECK-LABEL: name: test_redand_v1i1
; CHECK: liveins: $w0
; CHECK-NEXT: {{ $}}
; CHECK-NEXT: [[COPY:%[0-9]+]]:_(s32) = COPY $w0
; CHECK-NEXT: [[C:%[0-9]+]]:_(s32) = G_CONSTANT i32 1
; CHECK-NEXT: [[AND:%[0-9]+]]:_(s32) = G_AND [[COPY]], [[C]]
; CHECK-NEXT: $w0 = COPY [[AND]](s32)
; CHECK-NEXT: RET_ReallyLR implicit $w0
%1:_(s32) = COPY $w0
%0:_(s1) = G_TRUNC %1(s32)
%2:_(s1) = G_VECREDUCE_AND %0(s1)
%4:_(s32) = G_ZEXT %2(s1)
$w0 = COPY %4(s32)
RET_ReallyLR implicit $w0
...
---
name: test_redand_v2i1
alignment: 4
tracksRegLiveness: true
liveins:
- { reg: '$d0' }
body: |
bb.1:
liveins: $d0
; CHECK-LABEL: name: test_redand_v2i1
; CHECK: liveins: $d0
; CHECK-NEXT: {{ $}}
; CHECK-NEXT: [[COPY:%[0-9]+]]:_(<2 x s32>) = COPY $d0
; CHECK-NEXT: [[UV:%[0-9]+]]:_(s32), [[UV1:%[0-9]+]]:_(s32) = G_UNMERGE_VALUES [[COPY]](<2 x s32>)
; CHECK-NEXT: [[AND:%[0-9]+]]:_(s32) = G_AND [[UV]], [[UV1]]
; CHECK-NEXT: [[C:%[0-9]+]]:_(s32) = G_CONSTANT i32 1
; CHECK-NEXT: [[AND1:%[0-9]+]]:_(s32) = G_AND [[AND]], [[C]]
; CHECK-NEXT: $w0 = COPY [[AND1]](s32)
; CHECK-NEXT: RET_ReallyLR implicit $w0
%1:_(<2 x s32>) = COPY $d0
%0:_(<2 x s1>) = G_TRUNC %1(<2 x s32>)
%2:_(s1) = G_VECREDUCE_AND %0(<2 x s1>)
%4:_(s32) = G_ZEXT %2(s1)
$w0 = COPY %4(s32)
RET_ReallyLR implicit $w0
...
---
name: test_redand_v4i1
alignment: 4
tracksRegLiveness: true
liveins:
- { reg: '$d0' }
body: |
bb.1:
liveins: $d0
; CHECK-LABEL: name: test_redand_v4i1
; CHECK: liveins: $d0
; CHECK-NEXT: {{ $}}
; CHECK-NEXT: [[COPY:%[0-9]+]]:_(<4 x s16>) = COPY $d0
; CHECK-NEXT: [[UV:%[0-9]+]]:_(s16), [[UV1:%[0-9]+]]:_(s16), [[UV2:%[0-9]+]]:_(s16), [[UV3:%[0-9]+]]:_(s16) = G_UNMERGE_VALUES [[COPY]](<4 x s16>)
; CHECK-NEXT: [[ANYEXT:%[0-9]+]]:_(s32) = G_ANYEXT [[UV]](s16)
; CHECK-NEXT: [[ANYEXT1:%[0-9]+]]:_(s32) = G_ANYEXT [[UV1]](s16)
; CHECK-NEXT: [[AND:%[0-9]+]]:_(s32) = G_AND [[ANYEXT]], [[ANYEXT1]]
; CHECK-NEXT: [[ANYEXT2:%[0-9]+]]:_(s32) = G_ANYEXT [[UV2]](s16)
; CHECK-NEXT: [[ANYEXT3:%[0-9]+]]:_(s32) = G_ANYEXT [[UV3]](s16)
; CHECK-NEXT: [[AND1:%[0-9]+]]:_(s32) = G_AND [[ANYEXT2]], [[ANYEXT3]]
; CHECK-NEXT: [[AND2:%[0-9]+]]:_(s32) = G_AND [[AND]], [[AND1]]
; CHECK-NEXT: [[C:%[0-9]+]]:_(s32) = G_CONSTANT i32 1
; CHECK-NEXT: [[AND3:%[0-9]+]]:_(s32) = G_AND [[AND2]], [[C]]
; CHECK-NEXT: $w0 = COPY [[AND3]](s32)
; CHECK-NEXT: RET_ReallyLR implicit $w0
%1:_(<4 x s16>) = COPY $d0
%0:_(<4 x s1>) = G_TRUNC %1(<4 x s16>)
%2:_(s1) = G_VECREDUCE_AND %0(<4 x s1>)
%4:_(s32) = G_ZEXT %2(s1)
$w0 = COPY %4(s32)
RET_ReallyLR implicit $w0
...
---
name: test_redand_v8i1
alignment: 4
tracksRegLiveness: true
liveins:
- { reg: '$d0' }
body: |
bb.1:
liveins: $d0
; CHECK-LABEL: name: test_redand_v8i1
; CHECK: liveins: $d0
; CHECK-NEXT: {{ $}}
; CHECK-NEXT: [[COPY:%[0-9]+]]:_(<8 x s8>) = COPY $d0
; CHECK-NEXT: [[UV:%[0-9]+]]:_(s8), [[UV1:%[0-9]+]]:_(s8), [[UV2:%[0-9]+]]:_(s8), [[UV3:%[0-9]+]]:_(s8), [[UV4:%[0-9]+]]:_(s8), [[UV5:%[0-9]+]]:_(s8), [[UV6:%[0-9]+]]:_(s8), [[UV7:%[0-9]+]]:_(s8) = G_UNMERGE_VALUES [[COPY]](<8 x s8>)
; CHECK-NEXT: [[ANYEXT:%[0-9]+]]:_(s32) = G_ANYEXT [[UV]](s8)
; CHECK-NEXT: [[ANYEXT1:%[0-9]+]]:_(s32) = G_ANYEXT [[UV1]](s8)
; CHECK-NEXT: [[AND:%[0-9]+]]:_(s32) = G_AND [[ANYEXT]], [[ANYEXT1]]
; CHECK-NEXT: [[ANYEXT2:%[0-9]+]]:_(s32) = G_ANYEXT [[UV2]](s8)
; CHECK-NEXT: [[ANYEXT3:%[0-9]+]]:_(s32) = G_ANYEXT [[UV3]](s8)
; CHECK-NEXT: [[AND1:%[0-9]+]]:_(s32) = G_AND [[ANYEXT2]], [[ANYEXT3]]
; CHECK-NEXT: [[ANYEXT4:%[0-9]+]]:_(s32) = G_ANYEXT [[UV4]](s8)
; CHECK-NEXT: [[ANYEXT5:%[0-9]+]]:_(s32) = G_ANYEXT [[UV5]](s8)
; CHECK-NEXT: [[AND2:%[0-9]+]]:_(s32) = G_AND [[ANYEXT4]], [[ANYEXT5]]
; CHECK-NEXT: [[ANYEXT6:%[0-9]+]]:_(s32) = G_ANYEXT [[UV6]](s8)
; CHECK-NEXT: [[ANYEXT7:%[0-9]+]]:_(s32) = G_ANYEXT [[UV7]](s8)
; CHECK-NEXT: [[AND3:%[0-9]+]]:_(s32) = G_AND [[ANYEXT6]], [[ANYEXT7]]
; CHECK-NEXT: [[AND4:%[0-9]+]]:_(s32) = G_AND [[AND]], [[AND1]]
; CHECK-NEXT: [[AND5:%[0-9]+]]:_(s32) = G_AND [[AND2]], [[AND3]]
; CHECK-NEXT: [[AND6:%[0-9]+]]:_(s32) = G_AND [[AND4]], [[AND5]]
; CHECK-NEXT: [[C:%[0-9]+]]:_(s32) = G_CONSTANT i32 1
; CHECK-NEXT: [[AND7:%[0-9]+]]:_(s32) = G_AND [[AND6]], [[C]]
; CHECK-NEXT: $w0 = COPY [[AND7]](s32)
; CHECK-NEXT: RET_ReallyLR implicit $w0
%1:_(<8 x s8>) = COPY $d0
%0:_(<8 x s1>) = G_TRUNC %1(<8 x s8>)
%2:_(s1) = G_VECREDUCE_AND %0(<8 x s1>)
%4:_(s32) = G_ZEXT %2(s1)
$w0 = COPY %4(s32)
RET_ReallyLR implicit $w0
...
---
name: test_redand_v16i1
alignment: 4
tracksRegLiveness: true
liveins:
- { reg: '$q0' }
frameInfo:
maxAlignment: 1
machineFunctionInfo: {}
body: |
bb.1:
liveins: $q0
; CHECK-LABEL: name: test_redand_v16i1
; CHECK: liveins: $q0
; CHECK-NEXT: {{ $}}
; CHECK-NEXT: [[COPY:%[0-9]+]]:_(<16 x s8>) = COPY $q0
; CHECK-NEXT: [[UV:%[0-9]+]]:_(s8), [[UV1:%[0-9]+]]:_(s8), [[UV2:%[0-9]+]]:_(s8), [[UV3:%[0-9]+]]:_(s8), [[UV4:%[0-9]+]]:_(s8), [[UV5:%[0-9]+]]:_(s8), [[UV6:%[0-9]+]]:_(s8), [[UV7:%[0-9]+]]:_(s8), [[UV8:%[0-9]+]]:_(s8), [[UV9:%[0-9]+]]:_(s8), [[UV10:%[0-9]+]]:_(s8), [[UV11:%[0-9]+]]:_(s8), [[UV12:%[0-9]+]]:_(s8), [[UV13:%[0-9]+]]:_(s8), [[UV14:%[0-9]+]]:_(s8), [[UV15:%[0-9]+]]:_(s8) = G_UNMERGE_VALUES [[COPY]](<16 x s8>)
; CHECK-NEXT: [[ANYEXT:%[0-9]+]]:_(s32) = G_ANYEXT [[UV]](s8)
; CHECK-NEXT: [[ANYEXT1:%[0-9]+]]:_(s32) = G_ANYEXT [[UV1]](s8)
; CHECK-NEXT: [[AND:%[0-9]+]]:_(s32) = G_AND [[ANYEXT]], [[ANYEXT1]]
; CHECK-NEXT: [[ANYEXT2:%[0-9]+]]:_(s32) = G_ANYEXT [[UV2]](s8)
; CHECK-NEXT: [[ANYEXT3:%[0-9]+]]:_(s32) = G_ANYEXT [[UV3]](s8)
; CHECK-NEXT: [[AND1:%[0-9]+]]:_(s32) = G_AND [[ANYEXT2]], [[ANYEXT3]]
; CHECK-NEXT: [[ANYEXT4:%[0-9]+]]:_(s32) = G_ANYEXT [[UV4]](s8)
; CHECK-NEXT: [[ANYEXT5:%[0-9]+]]:_(s32) = G_ANYEXT [[UV5]](s8)
; CHECK-NEXT: [[AND2:%[0-9]+]]:_(s32) = G_AND [[ANYEXT4]], [[ANYEXT5]]
; CHECK-NEXT: [[ANYEXT6:%[0-9]+]]:_(s32) = G_ANYEXT [[UV6]](s8)
; CHECK-NEXT: [[ANYEXT7:%[0-9]+]]:_(s32) = G_ANYEXT [[UV7]](s8)
; CHECK-NEXT: [[AND3:%[0-9]+]]:_(s32) = G_AND [[ANYEXT6]], [[ANYEXT7]]
; CHECK-NEXT: [[ANYEXT8:%[0-9]+]]:_(s32) = G_ANYEXT [[UV8]](s8)
; CHECK-NEXT: [[ANYEXT9:%[0-9]+]]:_(s32) = G_ANYEXT [[UV9]](s8)
; CHECK-NEXT: [[AND4:%[0-9]+]]:_(s32) = G_AND [[ANYEXT8]], [[ANYEXT9]]
; CHECK-NEXT: [[ANYEXT10:%[0-9]+]]:_(s32) = G_ANYEXT [[UV10]](s8)
; CHECK-NEXT: [[ANYEXT11:%[0-9]+]]:_(s32) = G_ANYEXT [[UV11]](s8)
; CHECK-NEXT: [[AND5:%[0-9]+]]:_(s32) = G_AND [[ANYEXT10]], [[ANYEXT11]]
; CHECK-NEXT: [[ANYEXT12:%[0-9]+]]:_(s32) = G_ANYEXT [[UV12]](s8)
; CHECK-NEXT: [[ANYEXT13:%[0-9]+]]:_(s32) = G_ANYEXT [[UV13]](s8)
; CHECK-NEXT: [[AND6:%[0-9]+]]:_(s32) = G_AND [[ANYEXT12]], [[ANYEXT13]]
; CHECK-NEXT: [[ANYEXT14:%[0-9]+]]:_(s32) = G_ANYEXT [[UV14]](s8)
; CHECK-NEXT: [[ANYEXT15:%[0-9]+]]:_(s32) = G_ANYEXT [[UV15]](s8)
; CHECK-NEXT: [[AND7:%[0-9]+]]:_(s32) = G_AND [[ANYEXT14]], [[ANYEXT15]]
; CHECK-NEXT: [[AND8:%[0-9]+]]:_(s32) = G_AND [[AND]], [[AND1]]
; CHECK-NEXT: [[AND9:%[0-9]+]]:_(s32) = G_AND [[AND2]], [[AND3]]
; CHECK-NEXT: [[AND10:%[0-9]+]]:_(s32) = G_AND [[AND4]], [[AND5]]
; CHECK-NEXT: [[AND11:%[0-9]+]]:_(s32) = G_AND [[AND6]], [[AND7]]
; CHECK-NEXT: [[AND12:%[0-9]+]]:_(s32) = G_AND [[AND8]], [[AND9]]
; CHECK-NEXT: [[AND13:%[0-9]+]]:_(s32) = G_AND [[AND10]], [[AND11]]
; CHECK-NEXT: [[AND14:%[0-9]+]]:_(s32) = G_AND [[AND12]], [[AND13]]
; CHECK-NEXT: [[C:%[0-9]+]]:_(s32) = G_CONSTANT i32 1
; CHECK-NEXT: [[AND15:%[0-9]+]]:_(s32) = G_AND [[AND14]], [[C]]
; CHECK-NEXT: $w0 = COPY [[AND15]](s32)
; CHECK-NEXT: RET_ReallyLR implicit $w0
%1:_(<16 x s8>) = COPY $q0
%0:_(<16 x s1>) = G_TRUNC %1(<16 x s8>)
%2:_(s1) = G_VECREDUCE_AND %0(<16 x s1>)
%4:_(s32) = G_ZEXT %2(s1)
$w0 = COPY %4(s32)
RET_ReallyLR implicit $w0
...
---
name: test_redand_v1i8
alignment: 4
tracksRegLiveness: true
liveins:
- { reg: '$d0' }
body: |
bb.1:
liveins: $d0
; CHECK-LABEL: name: test_redand_v1i8
; CHECK: liveins: $d0
; CHECK-NEXT: {{ $}}
; CHECK-NEXT: [[COPY:%[0-9]+]]:_(<8 x s8>) = COPY $d0
; CHECK-NEXT: [[BITCAST:%[0-9]+]]:_(s64) = G_BITCAST [[COPY]](<8 x s8>)
; CHECK-NEXT: [[TRUNC:%[0-9]+]]:_(s32) = G_TRUNC [[BITCAST]](s64)
; CHECK-NEXT: $w0 = COPY [[TRUNC]](s32)
; CHECK-NEXT: RET_ReallyLR implicit $w0
%1:_(<8 x s8>) = COPY $d0
%11:_(s64) = G_BITCAST %1(<8 x s8>)
%0:_(s8) = G_TRUNC %11(s64)
%9:_(s8) = G_VECREDUCE_AND %0(s8)
%10:_(s32) = G_ANYEXT %9(s8)
$w0 = COPY %10(s32)
RET_ReallyLR implicit $w0
...
---
name: test_redand_v3i8
alignment: 4
tracksRegLiveness: true
liveins:
- { reg: '$w0' }
- { reg: '$w1' }
- { reg: '$w2' }
body: |
bb.1:
liveins: $w0, $w1, $w2
; CHECK-LABEL: name: test_redand_v3i8
; CHECK: liveins: $w0, $w1, $w2
; CHECK-NEXT: {{ $}}
; CHECK-NEXT: [[COPY:%[0-9]+]]:_(s32) = COPY $w0
; CHECK-NEXT: [[COPY1:%[0-9]+]]:_(s32) = COPY $w1
; CHECK-NEXT: [[COPY2:%[0-9]+]]:_(s32) = COPY $w2
; CHECK-NEXT: [[AND:%[0-9]+]]:_(s32) = G_AND [[COPY]], [[COPY1]]
; CHECK-NEXT: [[AND1:%[0-9]+]]:_(s32) = G_AND [[AND]], [[COPY2]]
; CHECK-NEXT: $w0 = COPY [[AND1]](s32)
; CHECK-NEXT: RET_ReallyLR implicit $w0
%1:_(s32) = COPY $w0
%2:_(s32) = COPY $w1
%3:_(s32) = COPY $w2
%4:_(<3 x s32>) = G_BUILD_VECTOR %1(s32), %2(s32), %3(s32)
%0:_(<3 x s8>) = G_TRUNC %4(<3 x s32>)
%5:_(s8) = G_VECREDUCE_AND %0(<3 x s8>)
%6:_(s32) = G_ANYEXT %5(s8)
$w0 = COPY %6(s32)
RET_ReallyLR implicit $w0
...
---
name: test_redand_v4i8
alignment: 4
tracksRegLiveness: true
liveins:
- { reg: '$d0' }
body: |
bb.1:
liveins: $d0
; CHECK-LABEL: name: test_redand_v4i8
; CHECK: liveins: $d0
; CHECK-NEXT: {{ $}}
; CHECK-NEXT: [[COPY:%[0-9]+]]:_(<4 x s16>) = COPY $d0
; CHECK-NEXT: [[UV:%[0-9]+]]:_(s16), [[UV1:%[0-9]+]]:_(s16), [[UV2:%[0-9]+]]:_(s16), [[UV3:%[0-9]+]]:_(s16) = G_UNMERGE_VALUES [[COPY]](<4 x s16>)
; CHECK-NEXT: [[ANYEXT:%[0-9]+]]:_(s32) = G_ANYEXT [[UV]](s16)
; CHECK-NEXT: [[ANYEXT1:%[0-9]+]]:_(s32) = G_ANYEXT [[UV1]](s16)
; CHECK-NEXT: [[AND:%[0-9]+]]:_(s32) = G_AND [[ANYEXT]], [[ANYEXT1]]
; CHECK-NEXT: [[ANYEXT2:%[0-9]+]]:_(s32) = G_ANYEXT [[UV2]](s16)
; CHECK-NEXT: [[ANYEXT3:%[0-9]+]]:_(s32) = G_ANYEXT [[UV3]](s16)
; CHECK-NEXT: [[AND1:%[0-9]+]]:_(s32) = G_AND [[ANYEXT2]], [[ANYEXT3]]
; CHECK-NEXT: [[AND2:%[0-9]+]]:_(s32) = G_AND [[AND]], [[AND1]]
; CHECK-NEXT: $w0 = COPY [[AND2]](s32)
; CHECK-NEXT: RET_ReallyLR implicit $w0
%1:_(<4 x s16>) = COPY $d0
%0:_(<4 x s8>) = G_TRUNC %1(<4 x s16>)
%2:_(s8) = G_VECREDUCE_AND %0(<4 x s8>)
%3:_(s32) = G_ANYEXT %2(s8)
$w0 = COPY %3(s32)
RET_ReallyLR implicit $w0
...
---
name: test_redand_v8i8
alignment: 4
tracksRegLiveness: true
liveins:
- { reg: '$d0' }
body: |
bb.1:
liveins: $d0
; CHECK-LABEL: name: test_redand_v8i8
; CHECK: liveins: $d0
; CHECK-NEXT: {{ $}}
; CHECK-NEXT: [[COPY:%[0-9]+]]:_(<8 x s8>) = COPY $d0
; CHECK-NEXT: [[UV:%[0-9]+]]:_(s8), [[UV1:%[0-9]+]]:_(s8), [[UV2:%[0-9]+]]:_(s8), [[UV3:%[0-9]+]]:_(s8), [[UV4:%[0-9]+]]:_(s8), [[UV5:%[0-9]+]]:_(s8), [[UV6:%[0-9]+]]:_(s8), [[UV7:%[0-9]+]]:_(s8) = G_UNMERGE_VALUES [[COPY]](<8 x s8>)
; CHECK-NEXT: [[ANYEXT:%[0-9]+]]:_(s32) = G_ANYEXT [[UV]](s8)
; CHECK-NEXT: [[ANYEXT1:%[0-9]+]]:_(s32) = G_ANYEXT [[UV1]](s8)
; CHECK-NEXT: [[AND:%[0-9]+]]:_(s32) = G_AND [[ANYEXT]], [[ANYEXT1]]
; CHECK-NEXT: [[ANYEXT2:%[0-9]+]]:_(s32) = G_ANYEXT [[UV2]](s8)
; CHECK-NEXT: [[ANYEXT3:%[0-9]+]]:_(s32) = G_ANYEXT [[UV3]](s8)
; CHECK-NEXT: [[AND1:%[0-9]+]]:_(s32) = G_AND [[ANYEXT2]], [[ANYEXT3]]
; CHECK-NEXT: [[ANYEXT4:%[0-9]+]]:_(s32) = G_ANYEXT [[UV4]](s8)
; CHECK-NEXT: [[ANYEXT5:%[0-9]+]]:_(s32) = G_ANYEXT [[UV5]](s8)
; CHECK-NEXT: [[AND2:%[0-9]+]]:_(s32) = G_AND [[ANYEXT4]], [[ANYEXT5]]
; CHECK-NEXT: [[ANYEXT6:%[0-9]+]]:_(s32) = G_ANYEXT [[UV6]](s8)
; CHECK-NEXT: [[ANYEXT7:%[0-9]+]]:_(s32) = G_ANYEXT [[UV7]](s8)
; CHECK-NEXT: [[AND3:%[0-9]+]]:_(s32) = G_AND [[ANYEXT6]], [[ANYEXT7]]
; CHECK-NEXT: [[AND4:%[0-9]+]]:_(s32) = G_AND [[AND]], [[AND1]]
; CHECK-NEXT: [[AND5:%[0-9]+]]:_(s32) = G_AND [[AND2]], [[AND3]]
; CHECK-NEXT: [[AND6:%[0-9]+]]:_(s32) = G_AND [[AND4]], [[AND5]]
; CHECK-NEXT: $w0 = COPY [[AND6]](s32)
; CHECK-NEXT: RET_ReallyLR implicit $w0
%0:_(<8 x s8>) = COPY $d0
%1:_(s8) = G_VECREDUCE_AND %0(<8 x s8>)
%2:_(s32) = G_ANYEXT %1(s8)
$w0 = COPY %2(s32)
RET_ReallyLR implicit $w0
...
---
name: test_redand_v16i8
alignment: 4
tracksRegLiveness: true
liveins:
- { reg: '$q0' }
body: |
bb.1:
liveins: $q0
; CHECK-LABEL: name: test_redand_v16i8
; CHECK: liveins: $q0
; CHECK-NEXT: {{ $}}
; CHECK-NEXT: [[COPY:%[0-9]+]]:_(<16 x s8>) = COPY $q0
; CHECK-NEXT: [[UV:%[0-9]+]]:_(<8 x s8>), [[UV1:%[0-9]+]]:_(<8 x s8>) = G_UNMERGE_VALUES [[COPY]](<16 x s8>)
; CHECK-NEXT: [[AND:%[0-9]+]]:_(<8 x s8>) = G_AND [[UV]], [[UV1]]
; CHECK-NEXT: [[UV2:%[0-9]+]]:_(s8), [[UV3:%[0-9]+]]:_(s8), [[UV4:%[0-9]+]]:_(s8), [[UV5:%[0-9]+]]:_(s8), [[UV6:%[0-9]+]]:_(s8), [[UV7:%[0-9]+]]:_(s8), [[UV8:%[0-9]+]]:_(s8), [[UV9:%[0-9]+]]:_(s8) = G_UNMERGE_VALUES [[AND]](<8 x s8>)
; CHECK-NEXT: [[ANYEXT:%[0-9]+]]:_(s32) = G_ANYEXT [[UV2]](s8)
; CHECK-NEXT: [[ANYEXT1:%[0-9]+]]:_(s32) = G_ANYEXT [[UV3]](s8)
; CHECK-NEXT: [[AND1:%[0-9]+]]:_(s32) = G_AND [[ANYEXT]], [[ANYEXT1]]
; CHECK-NEXT: [[ANYEXT2:%[0-9]+]]:_(s32) = G_ANYEXT [[UV4]](s8)
; CHECK-NEXT: [[ANYEXT3:%[0-9]+]]:_(s32) = G_ANYEXT [[UV5]](s8)
; CHECK-NEXT: [[AND2:%[0-9]+]]:_(s32) = G_AND [[ANYEXT2]], [[ANYEXT3]]
; CHECK-NEXT: [[ANYEXT4:%[0-9]+]]:_(s32) = G_ANYEXT [[UV6]](s8)
; CHECK-NEXT: [[ANYEXT5:%[0-9]+]]:_(s32) = G_ANYEXT [[UV7]](s8)
; CHECK-NEXT: [[AND3:%[0-9]+]]:_(s32) = G_AND [[ANYEXT4]], [[ANYEXT5]]
; CHECK-NEXT: [[ANYEXT6:%[0-9]+]]:_(s32) = G_ANYEXT [[UV8]](s8)
; CHECK-NEXT: [[ANYEXT7:%[0-9]+]]:_(s32) = G_ANYEXT [[UV9]](s8)
; CHECK-NEXT: [[AND4:%[0-9]+]]:_(s32) = G_AND [[ANYEXT6]], [[ANYEXT7]]
; CHECK-NEXT: [[AND5:%[0-9]+]]:_(s32) = G_AND [[AND1]], [[AND2]]
; CHECK-NEXT: [[AND6:%[0-9]+]]:_(s32) = G_AND [[AND3]], [[AND4]]
; CHECK-NEXT: [[AND7:%[0-9]+]]:_(s32) = G_AND [[AND5]], [[AND6]]
; CHECK-NEXT: $w0 = COPY [[AND7]](s32)
; CHECK-NEXT: RET_ReallyLR implicit $w0
%0:_(<16 x s8>) = COPY $q0
%1:_(s8) = G_VECREDUCE_AND %0(<16 x s8>)
%2:_(s32) = G_ANYEXT %1(s8)
$w0 = COPY %2(s32)
RET_ReallyLR implicit $w0
...
---
name: test_redand_v32i8
alignment: 4
tracksRegLiveness: true
liveins:
- { reg: '$q0' }
- { reg: '$q1' }
body: |
bb.1:
liveins: $q0, $q1
; CHECK-LABEL: name: test_redand_v32i8
; CHECK: liveins: $q0, $q1
; CHECK-NEXT: {{ $}}
; CHECK-NEXT: [[COPY:%[0-9]+]]:_(<16 x s8>) = COPY $q0
; CHECK-NEXT: [[COPY1:%[0-9]+]]:_(<16 x s8>) = COPY $q1
; CHECK-NEXT: [[AND:%[0-9]+]]:_(<16 x s8>) = G_AND [[COPY]], [[COPY1]]
; CHECK-NEXT: [[UV:%[0-9]+]]:_(<8 x s8>), [[UV1:%[0-9]+]]:_(<8 x s8>) = G_UNMERGE_VALUES [[AND]](<16 x s8>)
; CHECK-NEXT: [[AND1:%[0-9]+]]:_(<8 x s8>) = G_AND [[UV]], [[UV1]]
; CHECK-NEXT: [[UV2:%[0-9]+]]:_(s8), [[UV3:%[0-9]+]]:_(s8), [[UV4:%[0-9]+]]:_(s8), [[UV5:%[0-9]+]]:_(s8), [[UV6:%[0-9]+]]:_(s8), [[UV7:%[0-9]+]]:_(s8), [[UV8:%[0-9]+]]:_(s8), [[UV9:%[0-9]+]]:_(s8) = G_UNMERGE_VALUES [[AND1]](<8 x s8>)
; CHECK-NEXT: [[ANYEXT:%[0-9]+]]:_(s32) = G_ANYEXT [[UV2]](s8)
; CHECK-NEXT: [[ANYEXT1:%[0-9]+]]:_(s32) = G_ANYEXT [[UV3]](s8)
; CHECK-NEXT: [[AND2:%[0-9]+]]:_(s32) = G_AND [[ANYEXT]], [[ANYEXT1]]
; CHECK-NEXT: [[ANYEXT2:%[0-9]+]]:_(s32) = G_ANYEXT [[UV4]](s8)
; CHECK-NEXT: [[ANYEXT3:%[0-9]+]]:_(s32) = G_ANYEXT [[UV5]](s8)
; CHECK-NEXT: [[AND3:%[0-9]+]]:_(s32) = G_AND [[ANYEXT2]], [[ANYEXT3]]
; CHECK-NEXT: [[ANYEXT4:%[0-9]+]]:_(s32) = G_ANYEXT [[UV6]](s8)
; CHECK-NEXT: [[ANYEXT5:%[0-9]+]]:_(s32) = G_ANYEXT [[UV7]](s8)
; CHECK-NEXT: [[AND4:%[0-9]+]]:_(s32) = G_AND [[ANYEXT4]], [[ANYEXT5]]
; CHECK-NEXT: [[ANYEXT6:%[0-9]+]]:_(s32) = G_ANYEXT [[UV8]](s8)
; CHECK-NEXT: [[ANYEXT7:%[0-9]+]]:_(s32) = G_ANYEXT [[UV9]](s8)
; CHECK-NEXT: [[AND5:%[0-9]+]]:_(s32) = G_AND [[ANYEXT6]], [[ANYEXT7]]
; CHECK-NEXT: [[AND6:%[0-9]+]]:_(s32) = G_AND [[AND2]], [[AND3]]
; CHECK-NEXT: [[AND7:%[0-9]+]]:_(s32) = G_AND [[AND4]], [[AND5]]
; CHECK-NEXT: [[AND8:%[0-9]+]]:_(s32) = G_AND [[AND6]], [[AND7]]
; CHECK-NEXT: $w0 = COPY [[AND8]](s32)
; CHECK-NEXT: RET_ReallyLR implicit $w0
%1:_(<16 x s8>) = COPY $q0
%2:_(<16 x s8>) = COPY $q1
%0:_(<32 x s8>) = G_CONCAT_VECTORS %1(<16 x s8>), %2(<16 x s8>)
%3:_(s8) = G_VECREDUCE_AND %0(<32 x s8>)
%4:_(s32) = G_ANYEXT %3(s8)
$w0 = COPY %4(s32)
RET_ReallyLR implicit $w0
...
---
name: test_redand_v4i16
alignment: 4
tracksRegLiveness: true
liveins:
- { reg: '$d0' }
body: |
bb.1:
liveins: $d0
; CHECK-LABEL: name: test_redand_v4i16
; CHECK: liveins: $d0
; CHECK-NEXT: {{ $}}
; CHECK-NEXT: [[COPY:%[0-9]+]]:_(<4 x s16>) = COPY $d0
; CHECK-NEXT: [[UV:%[0-9]+]]:_(s16), [[UV1:%[0-9]+]]:_(s16), [[UV2:%[0-9]+]]:_(s16), [[UV3:%[0-9]+]]:_(s16) = G_UNMERGE_VALUES [[COPY]](<4 x s16>)
; CHECK-NEXT: [[ANYEXT:%[0-9]+]]:_(s32) = G_ANYEXT [[UV]](s16)
; CHECK-NEXT: [[ANYEXT1:%[0-9]+]]:_(s32) = G_ANYEXT [[UV1]](s16)
; CHECK-NEXT: [[AND:%[0-9]+]]:_(s32) = G_AND [[ANYEXT]], [[ANYEXT1]]
; CHECK-NEXT: [[ANYEXT2:%[0-9]+]]:_(s32) = G_ANYEXT [[UV2]](s16)
; CHECK-NEXT: [[ANYEXT3:%[0-9]+]]:_(s32) = G_ANYEXT [[UV3]](s16)
; CHECK-NEXT: [[AND1:%[0-9]+]]:_(s32) = G_AND [[ANYEXT2]], [[ANYEXT3]]
; CHECK-NEXT: [[AND2:%[0-9]+]]:_(s32) = G_AND [[AND]], [[AND1]]
; CHECK-NEXT: $w0 = COPY [[AND2]](s32)
; CHECK-NEXT: RET_ReallyLR implicit $w0
%0:_(<4 x s16>) = COPY $d0
%1:_(s16) = G_VECREDUCE_AND %0(<4 x s16>)
%2:_(s32) = G_ANYEXT %1(s16)
$w0 = COPY %2(s32)
RET_ReallyLR implicit $w0
...
---
name: test_redand_v8i16
alignment: 4
tracksRegLiveness: true
liveins:
- { reg: '$q0' }
body: |
bb.1:
liveins: $q0
; CHECK-LABEL: name: test_redand_v8i16
; CHECK: liveins: $q0
; CHECK-NEXT: {{ $}}
; CHECK-NEXT: [[COPY:%[0-9]+]]:_(<8 x s16>) = COPY $q0
; CHECK-NEXT: [[UV:%[0-9]+]]:_(<4 x s16>), [[UV1:%[0-9]+]]:_(<4 x s16>) = G_UNMERGE_VALUES [[COPY]](<8 x s16>)
; CHECK-NEXT: [[AND:%[0-9]+]]:_(<4 x s16>) = G_AND [[UV]], [[UV1]]
; CHECK-NEXT: [[UV2:%[0-9]+]]:_(s16), [[UV3:%[0-9]+]]:_(s16), [[UV4:%[0-9]+]]:_(s16), [[UV5:%[0-9]+]]:_(s16) = G_UNMERGE_VALUES [[AND]](<4 x s16>)
; CHECK-NEXT: [[ANYEXT:%[0-9]+]]:_(s32) = G_ANYEXT [[UV2]](s16)
; CHECK-NEXT: [[ANYEXT1:%[0-9]+]]:_(s32) = G_ANYEXT [[UV3]](s16)
; CHECK-NEXT: [[AND1:%[0-9]+]]:_(s32) = G_AND [[ANYEXT]], [[ANYEXT1]]
; CHECK-NEXT: [[ANYEXT2:%[0-9]+]]:_(s32) = G_ANYEXT [[UV4]](s16)
; CHECK-NEXT: [[ANYEXT3:%[0-9]+]]:_(s32) = G_ANYEXT [[UV5]](s16)
; CHECK-NEXT: [[AND2:%[0-9]+]]:_(s32) = G_AND [[ANYEXT2]], [[ANYEXT3]]
; CHECK-NEXT: [[AND3:%[0-9]+]]:_(s32) = G_AND [[AND1]], [[AND2]]
; CHECK-NEXT: $w0 = COPY [[AND3]](s32)
; CHECK-NEXT: RET_ReallyLR implicit $w0
%0:_(<8 x s16>) = COPY $q0
%1:_(s16) = G_VECREDUCE_AND %0(<8 x s16>)
%2:_(s32) = G_ANYEXT %1(s16)
$w0 = COPY %2(s32)
RET_ReallyLR implicit $w0
...
---
name: test_redand_v16i16
alignment: 4
tracksRegLiveness: true
liveins:
- { reg: '$q0' }
- { reg: '$q1' }
body: |
bb.1:
liveins: $q0, $q1
; CHECK-LABEL: name: test_redand_v16i16
; CHECK: liveins: $q0, $q1
; CHECK-NEXT: {{ $}}
; CHECK-NEXT: [[COPY:%[0-9]+]]:_(<8 x s16>) = COPY $q0
; CHECK-NEXT: [[COPY1:%[0-9]+]]:_(<8 x s16>) = COPY $q1
; CHECK-NEXT: [[AND:%[0-9]+]]:_(<8 x s16>) = G_AND [[COPY]], [[COPY1]]
; CHECK-NEXT: [[UV:%[0-9]+]]:_(<4 x s16>), [[UV1:%[0-9]+]]:_(<4 x s16>) = G_UNMERGE_VALUES [[AND]](<8 x s16>)
; CHECK-NEXT: [[AND1:%[0-9]+]]:_(<4 x s16>) = G_AND [[UV]], [[UV1]]
; CHECK-NEXT: [[UV2:%[0-9]+]]:_(s16), [[UV3:%[0-9]+]]:_(s16), [[UV4:%[0-9]+]]:_(s16), [[UV5:%[0-9]+]]:_(s16) = G_UNMERGE_VALUES [[AND1]](<4 x s16>)
; CHECK-NEXT: [[ANYEXT:%[0-9]+]]:_(s32) = G_ANYEXT [[UV2]](s16)
; CHECK-NEXT: [[ANYEXT1:%[0-9]+]]:_(s32) = G_ANYEXT [[UV3]](s16)
; CHECK-NEXT: [[AND2:%[0-9]+]]:_(s32) = G_AND [[ANYEXT]], [[ANYEXT1]]
; CHECK-NEXT: [[ANYEXT2:%[0-9]+]]:_(s32) = G_ANYEXT [[UV4]](s16)
; CHECK-NEXT: [[ANYEXT3:%[0-9]+]]:_(s32) = G_ANYEXT [[UV5]](s16)
; CHECK-NEXT: [[AND3:%[0-9]+]]:_(s32) = G_AND [[ANYEXT2]], [[ANYEXT3]]
; CHECK-NEXT: [[AND4:%[0-9]+]]:_(s32) = G_AND [[AND2]], [[AND3]]
; CHECK-NEXT: $w0 = COPY [[AND4]](s32)
; CHECK-NEXT: RET_ReallyLR implicit $w0
%1:_(<8 x s16>) = COPY $q0
%2:_(<8 x s16>) = COPY $q1
%0:_(<16 x s16>) = G_CONCAT_VECTORS %1(<8 x s16>), %2(<8 x s16>)
%3:_(s16) = G_VECREDUCE_AND %0(<16 x s16>)
%4:_(s32) = G_ANYEXT %3(s16)
$w0 = COPY %4(s32)
RET_ReallyLR implicit $w0
...
---
name: test_redand_v2i32
alignment: 4
tracksRegLiveness: true
liveins:
- { reg: '$d0' }
body: |
bb.1:
liveins: $d0
; CHECK-LABEL: name: test_redand_v2i32
; CHECK: liveins: $d0
; CHECK-NEXT: {{ $}}
; CHECK-NEXT: [[COPY:%[0-9]+]]:_(<2 x s32>) = COPY $d0
; CHECK-NEXT: [[UV:%[0-9]+]]:_(s32), [[UV1:%[0-9]+]]:_(s32) = G_UNMERGE_VALUES [[COPY]](<2 x s32>)
; CHECK-NEXT: [[AND:%[0-9]+]]:_(s32) = G_AND [[UV]], [[UV1]]
; CHECK-NEXT: [[COPY1:%[0-9]+]]:_(s32) = COPY [[AND]](s32)
; CHECK-NEXT: $w0 = COPY [[COPY1]](s32)
; CHECK-NEXT: RET_ReallyLR implicit $w0
%0:_(<2 x s32>) = COPY $d0
%1:_(s32) = G_VECREDUCE_AND %0(<2 x s32>)
$w0 = COPY %1(s32)
RET_ReallyLR implicit $w0
...
---
name: test_redand_v4i32
alignment: 4
tracksRegLiveness: true
liveins:
- { reg: '$q0' }
body: |
bb.1:
liveins: $q0
; CHECK-LABEL: name: test_redand_v4i32
; CHECK: liveins: $q0
; CHECK-NEXT: {{ $}}
; CHECK-NEXT: [[COPY:%[0-9]+]]:_(<4 x s32>) = COPY $q0
; CHECK-NEXT: [[UV:%[0-9]+]]:_(<2 x s32>), [[UV1:%[0-9]+]]:_(<2 x s32>) = G_UNMERGE_VALUES [[COPY]](<4 x s32>)
; CHECK-NEXT: [[AND:%[0-9]+]]:_(<2 x s32>) = G_AND [[UV]], [[UV1]]
; CHECK-NEXT: [[UV2:%[0-9]+]]:_(s32), [[UV3:%[0-9]+]]:_(s32) = G_UNMERGE_VALUES [[AND]](<2 x s32>)
; CHECK-NEXT: [[AND1:%[0-9]+]]:_(s32) = G_AND [[UV2]], [[UV3]]
; CHECK-NEXT: [[COPY1:%[0-9]+]]:_(s32) = COPY [[AND1]](s32)
; CHECK-NEXT: $w0 = COPY [[COPY1]](s32)
; CHECK-NEXT: RET_ReallyLR implicit $w0
%0:_(<4 x s32>) = COPY $q0
%1:_(s32) = G_VECREDUCE_AND %0(<4 x s32>)
$w0 = COPY %1(s32)
RET_ReallyLR implicit $w0
...
---
name: test_redand_v8i32
alignment: 4
tracksRegLiveness: true
liveins:
- { reg: '$q0' }
- { reg: '$q1' }
body: |
bb.1:
liveins: $q0, $q1
; CHECK-LABEL: name: test_redand_v8i32
; CHECK: liveins: $q0, $q1
; CHECK-NEXT: {{ $}}
; CHECK-NEXT: [[COPY:%[0-9]+]]:_(<4 x s32>) = COPY $q0
; CHECK-NEXT: [[COPY1:%[0-9]+]]:_(<4 x s32>) = COPY $q1
; CHECK-NEXT: [[AND:%[0-9]+]]:_(<4 x s32>) = G_AND [[COPY]], [[COPY1]]
; CHECK-NEXT: [[UV:%[0-9]+]]:_(<2 x s32>), [[UV1:%[0-9]+]]:_(<2 x s32>) = G_UNMERGE_VALUES [[AND]](<4 x s32>)
; CHECK-NEXT: [[AND1:%[0-9]+]]:_(<2 x s32>) = G_AND [[UV]], [[UV1]]
; CHECK-NEXT: [[UV2:%[0-9]+]]:_(s32), [[UV3:%[0-9]+]]:_(s32) = G_UNMERGE_VALUES [[AND1]](<2 x s32>)
; CHECK-NEXT: [[AND2:%[0-9]+]]:_(s32) = G_AND [[UV2]], [[UV3]]
; CHECK-NEXT: [[COPY2:%[0-9]+]]:_(s32) = COPY [[AND2]](s32)
; CHECK-NEXT: $w0 = COPY [[COPY2]](s32)
; CHECK-NEXT: RET_ReallyLR implicit $w0
%1:_(<4 x s32>) = COPY $q0
%2:_(<4 x s32>) = COPY $q1
%0:_(<8 x s32>) = G_CONCAT_VECTORS %1(<4 x s32>), %2(<4 x s32>)
%3:_(s32) = G_VECREDUCE_AND %0(<8 x s32>)
$w0 = COPY %3(s32)
RET_ReallyLR implicit $w0
...
---
name: test_redand_v2i64
alignment: 4
tracksRegLiveness: true
liveins:
- { reg: '$q0' }
body: |
bb.1:
liveins: $q0
; CHECK-LABEL: name: test_redand_v2i64
; CHECK: liveins: $q0
; CHECK-NEXT: {{ $}}
; CHECK-NEXT: [[COPY:%[0-9]+]]:_(<2 x s64>) = COPY $q0
; CHECK-NEXT: [[UV:%[0-9]+]]:_(s64), [[UV1:%[0-9]+]]:_(s64) = G_UNMERGE_VALUES [[COPY]](<2 x s64>)
; CHECK-NEXT: [[AND:%[0-9]+]]:_(s64) = G_AND [[UV]], [[UV1]]
; CHECK-NEXT: [[COPY1:%[0-9]+]]:_(s64) = COPY [[AND]](s64)
; CHECK-NEXT: $x0 = COPY [[COPY1]](s64)
; CHECK-NEXT: RET_ReallyLR implicit $x0
%0:_(<2 x s64>) = COPY $q0
%1:_(s64) = G_VECREDUCE_AND %0(<2 x s64>)
$x0 = COPY %1(s64)
RET_ReallyLR implicit $x0
...
---
name: test_redand_v4i64
alignment: 4
tracksRegLiveness: true
liveins:
- { reg: '$q0' }
- { reg: '$q1' }
body: |
bb.1:
liveins: $q0, $q1
; CHECK-LABEL: name: test_redand_v4i64
; CHECK: liveins: $q0, $q1
; CHECK-NEXT: {{ $}}
; CHECK-NEXT: [[COPY:%[0-9]+]]:_(<2 x s64>) = COPY $q0
; CHECK-NEXT: [[COPY1:%[0-9]+]]:_(<2 x s64>) = COPY $q1
; CHECK-NEXT: [[AND:%[0-9]+]]:_(<2 x s64>) = G_AND [[COPY]], [[COPY1]]
; CHECK-NEXT: [[UV:%[0-9]+]]:_(s64), [[UV1:%[0-9]+]]:_(s64) = G_UNMERGE_VALUES [[AND]](<2 x s64>)
; CHECK-NEXT: [[AND1:%[0-9]+]]:_(s64) = G_AND [[UV]], [[UV1]]
; CHECK-NEXT: [[COPY2:%[0-9]+]]:_(s64) = COPY [[AND1]](s64)
; CHECK-NEXT: $x0 = COPY [[COPY2]](s64)
; CHECK-NEXT: RET_ReallyLR implicit $x0
%1:_(<2 x s64>) = COPY $q0
%2:_(<2 x s64>) = COPY $q1
%0:_(<4 x s64>) = G_CONCAT_VECTORS %1(<2 x s64>), %2(<2 x s64>)
%3:_(s64) = G_VECREDUCE_AND %0(<4 x s64>)
$x0 = COPY %3(s64)
RET_ReallyLR implicit $x0
...

View File

@ -677,8 +677,9 @@
# DEBUG-NEXT: .. type index coverage check SKIPPED: no rules defined
# DEBUG-NEXT: .. imm index coverage check SKIPPED: no rules defined
# DEBUG-NEXT: G_VECREDUCE_AND (opcode {{[0-9]+}}): 2 type indices, 0 imm indices
# DEBUG-NEXT: .. type index coverage check SKIPPED: no rules defined
# DEBUG-NEXT: .. imm index coverage check SKIPPED: no rules defined
# DEBUG-NEXT: .. opcode {{[0-9]+}} is aliased to {{[0-9]+}}
# DEBUG-NEXT: .. type index coverage check SKIPPED: user-defined predicate detected
# DEBUG-NEXT: .. imm index coverage check SKIPPED: user-defined predicate detected
# DEBUG-NEXT: G_VECREDUCE_OR (opcode {{[0-9]+}}): 2 type indices, 0 imm indices
# DEBUG-NEXT: .. type index coverage check SKIPPED: user-defined predicate detected
# DEBUG-NEXT: .. imm index coverage check SKIPPED: user-defined predicate detected

View File

@ -1,11 +1,18 @@
; NOTE: Assertions have been autogenerated by utils/update_llc_test_checks.py
; RUN: llc < %s -mtriple=aarch64-unknown-linux-gnu -mattr=+neon | FileCheck %s
; RUN: llc < %s -mtriple=aarch64-none-linux-gnu -mattr=+neon -global-isel -global-isel-abort=1 | FileCheck %s --check-prefix=GISEL
define i1 @test_redand_v1i1(<1 x i1> %a) {
; CHECK-LABEL: test_redand_v1i1:
; CHECK: // %bb.0:
; CHECK-NEXT: and w0, w0, #0x1
; CHECK-NEXT: ret
;
; GISEL-LABEL: test_redand_v1i1:
; GISEL: // %bb.0:
; GISEL-NEXT: and w0, w0, #0x1
; GISEL-NEXT: ret
%or_result = call i1 @llvm.vector.reduce.and.v1i1(<1 x i1> %a)
ret i1 %or_result
}
@ -19,6 +26,16 @@ define i1 @test_redand_v2i1(<2 x i1> %a) {
; CHECK-NEXT: and w8, w9, w8
; CHECK-NEXT: and w0, w8, #0x1
; CHECK-NEXT: ret
;
; GISEL-LABEL: test_redand_v2i1:
; GISEL: // %bb.0:
; GISEL-NEXT: // kill: def $d0 killed $d0 def $q0
; GISEL-NEXT: mov s1, v0.s[1]
; GISEL-NEXT: fmov w8, s0
; GISEL-NEXT: fmov w9, s1
; GISEL-NEXT: and w8, w8, w9
; GISEL-NEXT: and w0, w8, #0x1
; GISEL-NEXT: ret
%or_result = call i1 @llvm.vector.reduce.and.v2i1(<2 x i1> %a)
ret i1 %or_result
}
@ -36,6 +53,22 @@ define i1 @test_redand_v4i1(<4 x i1> %a) {
; CHECK-NEXT: and w8, w9, w8
; CHECK-NEXT: and w0, w8, #0x1
; CHECK-NEXT: ret
;
; GISEL-LABEL: test_redand_v4i1:
; GISEL: // %bb.0:
; GISEL-NEXT: // kill: def $d0 killed $d0 def $q0
; GISEL-NEXT: mov h1, v0.h[1]
; GISEL-NEXT: mov h2, v0.h[2]
; GISEL-NEXT: mov h3, v0.h[3]
; GISEL-NEXT: fmov w8, s0
; GISEL-NEXT: fmov w9, s1
; GISEL-NEXT: and w8, w8, w9
; GISEL-NEXT: fmov w9, s2
; GISEL-NEXT: fmov w10, s3
; GISEL-NEXT: and w9, w9, w10
; GISEL-NEXT: and w8, w8, w9
; GISEL-NEXT: and w0, w8, #0x1
; GISEL-NEXT: ret
%or_result = call i1 @llvm.vector.reduce.and.v4i1(<4 x i1> %a)
ret i1 %or_result
}
@ -61,6 +94,34 @@ define i1 @test_redand_v8i1(<8 x i1> %a) {
; CHECK-NEXT: and w8, w9, w8
; CHECK-NEXT: and w0, w8, #0x1
; CHECK-NEXT: ret
;
; GISEL-LABEL: test_redand_v8i1:
; GISEL: // %bb.0:
; GISEL-NEXT: // kill: def $d0 killed $d0 def $q0
; GISEL-NEXT: mov b1, v0.b[1]
; GISEL-NEXT: mov b2, v0.b[2]
; GISEL-NEXT: mov b3, v0.b[3]
; GISEL-NEXT: fmov w8, s0
; GISEL-NEXT: fmov w9, s1
; GISEL-NEXT: mov b4, v0.b[4]
; GISEL-NEXT: mov b5, v0.b[5]
; GISEL-NEXT: and w8, w8, w9
; GISEL-NEXT: fmov w9, s2
; GISEL-NEXT: fmov w10, s3
; GISEL-NEXT: mov b6, v0.b[6]
; GISEL-NEXT: mov b7, v0.b[7]
; GISEL-NEXT: and w9, w9, w10
; GISEL-NEXT: fmov w10, s4
; GISEL-NEXT: fmov w11, s5
; GISEL-NEXT: and w10, w10, w11
; GISEL-NEXT: fmov w11, s6
; GISEL-NEXT: fmov w12, s7
; GISEL-NEXT: and w11, w11, w12
; GISEL-NEXT: and w8, w8, w9
; GISEL-NEXT: and w9, w10, w11
; GISEL-NEXT: and w8, w8, w9
; GISEL-NEXT: and w0, w8, #0x1
; GISEL-NEXT: ret
%or_result = call i1 @llvm.vector.reduce.and.v8i1(<8 x i1> %a)
ret i1 %or_result
}
@ -87,6 +148,57 @@ define i1 @test_redand_v16i1(<16 x i1> %a) {
; CHECK-NEXT: and w8, w8, w9
; CHECK-NEXT: and w0, w8, #0x1
; CHECK-NEXT: ret
;
; GISEL-LABEL: test_redand_v16i1:
; GISEL: // %bb.0:
; GISEL-NEXT: mov b1, v0.b[1]
; GISEL-NEXT: mov b2, v0.b[2]
; GISEL-NEXT: mov b3, v0.b[3]
; GISEL-NEXT: fmov w8, s0
; GISEL-NEXT: fmov w9, s1
; GISEL-NEXT: mov b4, v0.b[4]
; GISEL-NEXT: mov b5, v0.b[5]
; GISEL-NEXT: and w8, w8, w9
; GISEL-NEXT: fmov w9, s2
; GISEL-NEXT: fmov w10, s3
; GISEL-NEXT: mov b6, v0.b[6]
; GISEL-NEXT: mov b7, v0.b[7]
; GISEL-NEXT: and w9, w9, w10
; GISEL-NEXT: fmov w10, s4
; GISEL-NEXT: fmov w11, s5
; GISEL-NEXT: mov b16, v0.b[8]
; GISEL-NEXT: mov b17, v0.b[9]
; GISEL-NEXT: and w10, w10, w11
; GISEL-NEXT: fmov w11, s6
; GISEL-NEXT: fmov w12, s7
; GISEL-NEXT: mov b18, v0.b[10]
; GISEL-NEXT: mov b19, v0.b[11]
; GISEL-NEXT: and w11, w11, w12
; GISEL-NEXT: fmov w12, s16
; GISEL-NEXT: fmov w13, s17
; GISEL-NEXT: mov b20, v0.b[12]
; GISEL-NEXT: mov b21, v0.b[13]
; GISEL-NEXT: and w12, w12, w13
; GISEL-NEXT: fmov w13, s18
; GISEL-NEXT: fmov w14, s19
; GISEL-NEXT: mov b22, v0.b[14]
; GISEL-NEXT: mov b23, v0.b[15]
; GISEL-NEXT: and w13, w13, w14
; GISEL-NEXT: fmov w14, s20
; GISEL-NEXT: fmov w15, s21
; GISEL-NEXT: and w14, w14, w15
; GISEL-NEXT: fmov w15, s22
; GISEL-NEXT: fmov w16, s23
; GISEL-NEXT: and w15, w15, w16
; GISEL-NEXT: and w8, w8, w9
; GISEL-NEXT: and w9, w10, w11
; GISEL-NEXT: and w10, w12, w13
; GISEL-NEXT: and w11, w14, w15
; GISEL-NEXT: and w8, w8, w9
; GISEL-NEXT: and w9, w10, w11
; GISEL-NEXT: and w8, w8, w9
; GISEL-NEXT: and w0, w8, #0x1
; GISEL-NEXT: ret
%or_result = call i1 @llvm.vector.reduce.and.v16i1(<16 x i1> %a)
ret i1 %or_result
}
@ -97,6 +209,12 @@ define i8 @test_redand_v1i8(<1 x i8> %a) {
; CHECK-NEXT: // kill: def $d0 killed $d0 def $q0
; CHECK-NEXT: umov w0, v0.b[0]
; CHECK-NEXT: ret
;
; GISEL-LABEL: test_redand_v1i8:
; GISEL: // %bb.0:
; GISEL-NEXT: fmov x0, d0
; GISEL-NEXT: // kill: def $w0 killed $w0 killed $x0
; GISEL-NEXT: ret
%and_result = call i8 @llvm.vector.reduce.and.v1i8(<1 x i8> %a)
ret i8 %and_result
}
@ -108,6 +226,12 @@ define i8 @test_redand_v3i8(<3 x i8> %a) {
; CHECK-NEXT: and w8, w8, w2
; CHECK-NEXT: and w0, w8, #0xff
; CHECK-NEXT: ret
;
; GISEL-LABEL: test_redand_v3i8:
; GISEL: // %bb.0:
; GISEL-NEXT: and w8, w0, w1
; GISEL-NEXT: and w0, w8, w2
; GISEL-NEXT: ret
%and_result = call i8 @llvm.vector.reduce.and.v3i8(<3 x i8> %a)
ret i8 %and_result
}
@ -124,6 +248,21 @@ define i8 @test_redand_v4i8(<4 x i8> %a) {
; CHECK-NEXT: and w9, w10, w9
; CHECK-NEXT: and w0, w9, w8
; CHECK-NEXT: ret
;
; GISEL-LABEL: test_redand_v4i8:
; GISEL: // %bb.0:
; GISEL-NEXT: // kill: def $d0 killed $d0 def $q0
; GISEL-NEXT: mov h1, v0.h[1]
; GISEL-NEXT: mov h2, v0.h[2]
; GISEL-NEXT: mov h3, v0.h[3]
; GISEL-NEXT: fmov w8, s0
; GISEL-NEXT: fmov w9, s1
; GISEL-NEXT: and w8, w8, w9
; GISEL-NEXT: fmov w9, s2
; GISEL-NEXT: fmov w10, s3
; GISEL-NEXT: and w9, w9, w10
; GISEL-NEXT: and w0, w8, w9
; GISEL-NEXT: ret
%and_result = call i8 @llvm.vector.reduce.and.v4i8(<4 x i8> %a)
ret i8 %and_result
}
@ -148,6 +287,33 @@ define i8 @test_redand_v8i8(<8 x i8> %a) {
; CHECK-NEXT: and w9, w10, w9
; CHECK-NEXT: and w0, w9, w8
; CHECK-NEXT: ret
;
; GISEL-LABEL: test_redand_v8i8:
; GISEL: // %bb.0:
; GISEL-NEXT: // kill: def $d0 killed $d0 def $q0
; GISEL-NEXT: mov b1, v0.b[1]
; GISEL-NEXT: mov b2, v0.b[2]
; GISEL-NEXT: mov b3, v0.b[3]
; GISEL-NEXT: fmov w8, s0
; GISEL-NEXT: fmov w9, s1
; GISEL-NEXT: mov b4, v0.b[4]
; GISEL-NEXT: mov b5, v0.b[5]
; GISEL-NEXT: and w8, w8, w9
; GISEL-NEXT: fmov w9, s2
; GISEL-NEXT: fmov w10, s3
; GISEL-NEXT: mov b6, v0.b[6]
; GISEL-NEXT: mov b7, v0.b[7]
; GISEL-NEXT: and w9, w9, w10
; GISEL-NEXT: fmov w10, s4
; GISEL-NEXT: fmov w11, s5
; GISEL-NEXT: and w10, w10, w11
; GISEL-NEXT: fmov w11, s6
; GISEL-NEXT: fmov w12, s7
; GISEL-NEXT: and w11, w11, w12
; GISEL-NEXT: and w8, w8, w9
; GISEL-NEXT: and w9, w10, w11
; GISEL-NEXT: and w0, w8, w9
; GISEL-NEXT: ret
%and_result = call i8 @llvm.vector.reduce.and.v8i8(<8 x i8> %a)
ret i8 %and_result
}
@ -173,6 +339,34 @@ define i8 @test_redand_v16i8(<16 x i8> %a) {
; CHECK-NEXT: umov w9, v0.b[7]
; CHECK-NEXT: and w0, w8, w9
; CHECK-NEXT: ret
;
; GISEL-LABEL: test_redand_v16i8:
; GISEL: // %bb.0:
; GISEL-NEXT: mov d1, v0.d[1]
; GISEL-NEXT: and v0.8b, v0.8b, v1.8b
; GISEL-NEXT: mov b1, v0.b[1]
; GISEL-NEXT: mov b2, v0.b[2]
; GISEL-NEXT: mov b3, v0.b[3]
; GISEL-NEXT: fmov w8, s0
; GISEL-NEXT: fmov w9, s1
; GISEL-NEXT: mov b4, v0.b[4]
; GISEL-NEXT: mov b5, v0.b[5]
; GISEL-NEXT: and w8, w8, w9
; GISEL-NEXT: fmov w9, s2
; GISEL-NEXT: fmov w10, s3
; GISEL-NEXT: mov b6, v0.b[6]
; GISEL-NEXT: mov b7, v0.b[7]
; GISEL-NEXT: and w9, w9, w10
; GISEL-NEXT: fmov w10, s4
; GISEL-NEXT: fmov w11, s5
; GISEL-NEXT: and w10, w10, w11
; GISEL-NEXT: fmov w11, s6
; GISEL-NEXT: fmov w12, s7
; GISEL-NEXT: and w11, w11, w12
; GISEL-NEXT: and w8, w8, w9
; GISEL-NEXT: and w9, w10, w11
; GISEL-NEXT: and w0, w8, w9
; GISEL-NEXT: ret
%and_result = call i8 @llvm.vector.reduce.and.v16i8(<16 x i8> %a)
ret i8 %and_result
}
@ -199,6 +393,35 @@ define i8 @test_redand_v32i8(<32 x i8> %a) {
; CHECK-NEXT: umov w9, v0.b[7]
; CHECK-NEXT: and w0, w8, w9
; CHECK-NEXT: ret
;
; GISEL-LABEL: test_redand_v32i8:
; GISEL: // %bb.0:
; GISEL-NEXT: and v0.16b, v0.16b, v1.16b
; GISEL-NEXT: mov d1, v0.d[1]
; GISEL-NEXT: and v0.8b, v0.8b, v1.8b
; GISEL-NEXT: mov b1, v0.b[1]
; GISEL-NEXT: mov b2, v0.b[2]
; GISEL-NEXT: mov b3, v0.b[3]
; GISEL-NEXT: fmov w8, s0
; GISEL-NEXT: fmov w9, s1
; GISEL-NEXT: mov b4, v0.b[4]
; GISEL-NEXT: mov b5, v0.b[5]
; GISEL-NEXT: and w8, w8, w9
; GISEL-NEXT: fmov w9, s2
; GISEL-NEXT: fmov w10, s3
; GISEL-NEXT: mov b6, v0.b[6]
; GISEL-NEXT: mov b7, v0.b[7]
; GISEL-NEXT: and w9, w9, w10
; GISEL-NEXT: fmov w10, s4
; GISEL-NEXT: fmov w11, s5
; GISEL-NEXT: and w10, w10, w11
; GISEL-NEXT: fmov w11, s6
; GISEL-NEXT: fmov w12, s7
; GISEL-NEXT: and w11, w11, w12
; GISEL-NEXT: and w8, w8, w9
; GISEL-NEXT: and w9, w10, w11
; GISEL-NEXT: and w0, w8, w9
; GISEL-NEXT: ret
%and_result = call i8 @llvm.vector.reduce.and.v32i8(<32 x i8> %a)
ret i8 %and_result
}
@ -215,6 +438,21 @@ define i16 @test_redand_v4i16(<4 x i16> %a) {
; CHECK-NEXT: and w9, w10, w9
; CHECK-NEXT: and w0, w9, w8
; CHECK-NEXT: ret
;
; GISEL-LABEL: test_redand_v4i16:
; GISEL: // %bb.0:
; GISEL-NEXT: // kill: def $d0 killed $d0 def $q0
; GISEL-NEXT: mov h1, v0.h[1]
; GISEL-NEXT: mov h2, v0.h[2]
; GISEL-NEXT: mov h3, v0.h[3]
; GISEL-NEXT: fmov w8, s0
; GISEL-NEXT: fmov w9, s1
; GISEL-NEXT: and w8, w8, w9
; GISEL-NEXT: fmov w9, s2
; GISEL-NEXT: fmov w10, s3
; GISEL-NEXT: and w9, w9, w10
; GISEL-NEXT: and w0, w8, w9
; GISEL-NEXT: ret
%and_result = call i16 @llvm.vector.reduce.and.v4i16(<4 x i16> %a)
ret i16 %and_result
}
@ -232,6 +470,22 @@ define i16 @test_redand_v8i16(<8 x i16> %a) {
; CHECK-NEXT: umov w9, v0.h[3]
; CHECK-NEXT: and w0, w8, w9
; CHECK-NEXT: ret
;
; GISEL-LABEL: test_redand_v8i16:
; GISEL: // %bb.0:
; GISEL-NEXT: mov d1, v0.d[1]
; GISEL-NEXT: and v0.8b, v0.8b, v1.8b
; GISEL-NEXT: mov h1, v0.h[1]
; GISEL-NEXT: mov h2, v0.h[2]
; GISEL-NEXT: mov h3, v0.h[3]
; GISEL-NEXT: fmov w8, s0
; GISEL-NEXT: fmov w9, s1
; GISEL-NEXT: and w8, w8, w9
; GISEL-NEXT: fmov w9, s2
; GISEL-NEXT: fmov w10, s3
; GISEL-NEXT: and w9, w9, w10
; GISEL-NEXT: and w0, w8, w9
; GISEL-NEXT: ret
%and_result = call i16 @llvm.vector.reduce.and.v8i16(<8 x i16> %a)
ret i16 %and_result
}
@ -250,6 +504,23 @@ define i16 @test_redand_v16i16(<16 x i16> %a) {
; CHECK-NEXT: umov w9, v0.h[3]
; CHECK-NEXT: and w0, w8, w9
; CHECK-NEXT: ret
;
; GISEL-LABEL: test_redand_v16i16:
; GISEL: // %bb.0:
; GISEL-NEXT: and v0.16b, v0.16b, v1.16b
; GISEL-NEXT: mov d1, v0.d[1]
; GISEL-NEXT: and v0.8b, v0.8b, v1.8b
; GISEL-NEXT: mov h1, v0.h[1]
; GISEL-NEXT: mov h2, v0.h[2]
; GISEL-NEXT: mov h3, v0.h[3]
; GISEL-NEXT: fmov w8, s0
; GISEL-NEXT: fmov w9, s1
; GISEL-NEXT: and w8, w8, w9
; GISEL-NEXT: fmov w9, s2
; GISEL-NEXT: fmov w10, s3
; GISEL-NEXT: and w9, w9, w10
; GISEL-NEXT: and w0, w8, w9
; GISEL-NEXT: ret
%and_result = call i16 @llvm.vector.reduce.and.v16i16(<16 x i16> %a)
ret i16 %and_result
}
@ -262,6 +533,15 @@ define i32 @test_redand_v2i32(<2 x i32> %a) {
; CHECK-NEXT: fmov w9, s0
; CHECK-NEXT: and w0, w9, w8
; CHECK-NEXT: ret
;
; GISEL-LABEL: test_redand_v2i32:
; GISEL: // %bb.0:
; GISEL-NEXT: // kill: def $d0 killed $d0 def $q0
; GISEL-NEXT: mov s1, v0.s[1]
; GISEL-NEXT: fmov w8, s0
; GISEL-NEXT: fmov w9, s1
; GISEL-NEXT: and w0, w8, w9
; GISEL-NEXT: ret
%and_result = call i32 @llvm.vector.reduce.and.v2i32(<2 x i32> %a)
ret i32 %and_result
}
@ -275,6 +555,16 @@ define i32 @test_redand_v4i32(<4 x i32> %a) {
; CHECK-NEXT: fmov w9, s0
; CHECK-NEXT: and w0, w9, w8
; CHECK-NEXT: ret
;
; GISEL-LABEL: test_redand_v4i32:
; GISEL: // %bb.0:
; GISEL-NEXT: mov d1, v0.d[1]
; GISEL-NEXT: and v0.8b, v0.8b, v1.8b
; GISEL-NEXT: mov s1, v0.s[1]
; GISEL-NEXT: fmov w8, s0
; GISEL-NEXT: fmov w9, s1
; GISEL-NEXT: and w0, w8, w9
; GISEL-NEXT: ret
%and_result = call i32 @llvm.vector.reduce.and.v4i32(<4 x i32> %a)
ret i32 %and_result
}
@ -289,6 +579,17 @@ define i32 @test_redand_v8i32(<8 x i32> %a) {
; CHECK-NEXT: fmov w9, s0
; CHECK-NEXT: and w0, w9, w8
; CHECK-NEXT: ret
;
; GISEL-LABEL: test_redand_v8i32:
; GISEL: // %bb.0:
; GISEL-NEXT: and v0.16b, v0.16b, v1.16b
; GISEL-NEXT: mov d1, v0.d[1]
; GISEL-NEXT: and v0.8b, v0.8b, v1.8b
; GISEL-NEXT: mov s1, v0.s[1]
; GISEL-NEXT: fmov w8, s0
; GISEL-NEXT: fmov w9, s1
; GISEL-NEXT: and w0, w8, w9
; GISEL-NEXT: ret
%and_result = call i32 @llvm.vector.reduce.and.v8i32(<8 x i32> %a)
ret i32 %and_result
}
@ -300,6 +601,14 @@ define i64 @test_redand_v2i64(<2 x i64> %a) {
; CHECK-NEXT: and v0.8b, v0.8b, v1.8b
; CHECK-NEXT: fmov x0, d0
; CHECK-NEXT: ret
;
; GISEL-LABEL: test_redand_v2i64:
; GISEL: // %bb.0:
; GISEL-NEXT: mov d1, v0.d[1]
; GISEL-NEXT: fmov x8, d0
; GISEL-NEXT: fmov x9, d1
; GISEL-NEXT: and x0, x8, x9
; GISEL-NEXT: ret
%and_result = call i64 @llvm.vector.reduce.and.v2i64(<2 x i64> %a)
ret i64 %and_result
}
@ -312,6 +621,15 @@ define i64 @test_redand_v4i64(<4 x i64> %a) {
; CHECK-NEXT: and v0.8b, v0.8b, v1.8b
; CHECK-NEXT: fmov x0, d0
; CHECK-NEXT: ret
;
; GISEL-LABEL: test_redand_v4i64:
; GISEL: // %bb.0:
; GISEL-NEXT: and v0.16b, v0.16b, v1.16b
; GISEL-NEXT: mov d1, v0.d[1]
; GISEL-NEXT: fmov x8, d0
; GISEL-NEXT: fmov x9, d1
; GISEL-NEXT: and x0, x8, x9
; GISEL-NEXT: ret
%and_result = call i64 @llvm.vector.reduce.and.v4i64(<4 x i64> %a)
ret i64 %and_result
}