Skip to content

[RISCV][GlobalISel] Legalize scalable vectorized G_ADD, G_SUB, G_AND, G_OR, and G_XOR #71400

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Closed
wants to merge 14 commits into from
Closed
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
40 changes: 40 additions & 0 deletions llvm/lib/Target/RISCV/GISel/RISCVLegalizerInfo.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -47,10 +47,50 @@ RISCVLegalizerInfo::RISCVLegalizerInfo(const RISCVSubtarget &ST)
const LLT s32 = LLT::scalar(32);
const LLT s64 = LLT::scalar(64);

const LLT nxv1s8 = LLT::scalable_vector(1, s8);
const LLT nxv2s8 = LLT::scalable_vector(2, s8);
const LLT nxv4s8 = LLT::scalable_vector(4, s8);
const LLT nxv8s8 = LLT::scalable_vector(8, s8);
const LLT nxv16s8 = LLT::scalable_vector(16, s8);
const LLT nxv32s8 = LLT::scalable_vector(32, s8);
const LLT nxv64s8 = LLT::scalable_vector(64, s8);

const LLT nxv1s16 = LLT::scalable_vector(1, s16);
const LLT nxv2s16 = LLT::scalable_vector(2, s16);
const LLT nxv4s16 = LLT::scalable_vector(4, s16);
const LLT nxv8s16 = LLT::scalable_vector(8, s16);
const LLT nxv16s16 = LLT::scalable_vector(16, s16);
const LLT nxv32s16 = LLT::scalable_vector(32, s16);

const LLT nxv1s32 = LLT::scalable_vector(1, s32);
const LLT nxv2s32 = LLT::scalable_vector(2, s32);
const LLT nxv4s32 = LLT::scalable_vector(4, s32);
const LLT nxv8s32 = LLT::scalable_vector(8, s32);
const LLT nxv16s32 = LLT::scalable_vector(16, s32);

const LLT nxv1s64 = LLT::scalable_vector(1, s64);
const LLT nxv2s64 = LLT::scalable_vector(2, s64);
const LLT nxv4s64 = LLT::scalable_vector(4, s64);
const LLT nxv8s64 = LLT::scalable_vector(8, s64);

using namespace TargetOpcode;

auto AllVecTys = {nxv1s8, nxv2s8, nxv4s8, nxv8s8, nxv16s8, nxv32s8,
nxv64s8, nxv1s16, nxv2s16, nxv4s16, nxv8s16, nxv16s16,
nxv32s16, nxv1s32, nxv2s32, nxv4s32, nxv8s32, nxv16s32,
nxv1s64, nxv2s64, nxv4s64, nxv8s64};

getActionDefinitionsBuilder({G_ADD, G_SUB, G_AND, G_OR, G_XOR})
.legalFor({s32, sXLen})
.legalIf(all(
typeInSet(0, AllVecTys),
LegalityPredicate([=, &ST](const LegalityQuery &Query) {
return ST.hasVInstructions() &&
(Query.Types[0].getScalarSizeInBits() != 64 ||
ST.hasVInstructionsI64()) &&
(Query.Types[0].getElementCount().getKnownMinValue() != 1 ||
ST.getELen() == 64);
})))
.widenScalarToNextPow2(0)
.clampScalar(0, s32, sXLen);

Expand Down
9 changes: 7 additions & 2 deletions llvm/lib/Target/RISCV/RISCVISelLowering.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -19874,8 +19874,13 @@ unsigned RISCVTargetLowering::getCustomCtpopCost(EVT VT,
}

bool RISCVTargetLowering::fallBackToDAGISel(const Instruction &Inst) const {
// At the moment, the only scalable instruction GISel knows how to lower is
// ret with scalable argument.

// GISel support is in progress or complete for G_ADD, G_SUB, G_AND, G_OR, and
// G_XOR.
unsigned Op = Inst.getOpcode();
if (Op == Instruction::Add || Op == Instruction::Sub ||
Op == Instruction::And || Op == Instruction::Or || Op == Instruction::Xor)
return false;

if (Inst.getType()->isScalableTy())
return true;
Expand Down
53 changes: 53 additions & 0 deletions llvm/test/CodeGen/RISCV/GlobalISel/irtranslator/vec-alu.ll
Original file line number Diff line number Diff line change
@@ -0,0 +1,53 @@
; NOTE: Assertions have been autogenerated by utils/update_mir_test_checks.py
; RUN: llc -mtriple=riscv32 -mattr=+v -global-isel -stop-before=legalizer -simplify-mir < %s | FileCheck %s --check-prefixes=CHECK,RV32I
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

RV32I and RV64I are unused in this test. This causes FileCheck to report an error in lit. I fixed it, but you should always run ninja check even after running the script. The script isn't perfect.

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Thanks for fixing this. The failure didn't show up in the pre commit CI checks.

; RUN: llc -mtriple=riscv64 -mattr=+v -global-isel -stop-before=legalizer -simplify-mir < %s | FileCheck %s --check-prefixes=CHECK,RV64I

define void @add_nxv2i32(<vscale x 2 x i32> %a, <vscale x 2 x i32> %b) {
; CHECK-LABEL: name: add_nxv2i32
; CHECK: bb.1 (%ir-block.0):
; CHECK-NEXT: liveins: $v8, $v9
; CHECK-NEXT: {{ $}}
; CHECK-NEXT: PseudoRET
%c = add <vscale x 2 x i32> %a, %b
ret void
}

define void @sub_nxv2i32(<vscale x 2 x i32> %a, <vscale x 2 x i32> %b) {
; CHECK-LABEL: name: sub_nxv2i32
; CHECK: bb.1 (%ir-block.0):
; CHECK-NEXT: liveins: $v8, $v9
; CHECK-NEXT: {{ $}}
; CHECK-NEXT: PseudoRET
%c = sub <vscale x 2 x i32> %a, %b
ret void
}

define void @and_nxv2i32(<vscale x 2 x i32> %a, <vscale x 2 x i32> %b) {
; CHECK-LABEL: name: and_nxv2i32
; CHECK: bb.1 (%ir-block.0):
; CHECK-NEXT: liveins: $v8, $v9
; CHECK-NEXT: {{ $}}
; CHECK-NEXT: PseudoRET
%c = and <vscale x 2 x i32> %a, %b
ret void
}

define void @or_nxv2i32(<vscale x 2 x i32> %a, <vscale x 2 x i32> %b) {
; CHECK-LABEL: name: or_nxv2i32
; CHECK: bb.1 (%ir-block.0):
; CHECK-NEXT: liveins: $v8, $v9
; CHECK-NEXT: {{ $}}
; CHECK-NEXT: PseudoRET
%c = or <vscale x 2 x i32> %a, %b
ret void
}

define void @xor_nxv2i32(<vscale x 2 x i32> %a, <vscale x 2 x i32> %b) {
; CHECK-LABEL: name: xor_nxv2i32
; CHECK: bb.1 (%ir-block.0):
; CHECK-NEXT: liveins: $v8, $v9
; CHECK-NEXT: {{ $}}
; CHECK-NEXT: PseudoRET
%c = xor <vscale x 2 x i32> %a, %b
ret void
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,274 @@
# NOTE: Assertions have been autogenerated by utils/update_mir_test_checks.py
# RUN: llc -mtriple=riscv32 -mattr=+zve32x -run-pass=legalizer %s -o - | FileCheck %s
# RUN: llc -mtriple=riscv64 -mattr=+zve32x -run-pass=legalizer %s -o - | FileCheck %s
---
name: test_nxv2i8
body: |
bb.0.entry:

; CHECK-LABEL: name: test_nxv2i8
; CHECK: [[COPY:%[0-9]+]]:_(<vscale x 2 x s8>) = COPY $v8
; CHECK-NEXT: [[COPY1:%[0-9]+]]:_(<vscale x 2 x s8>) = COPY $v9
; CHECK-NEXT: [[ADD:%[0-9]+]]:_(<vscale x 2 x s8>) = G_ADD [[COPY]], [[COPY1]]
; CHECK-NEXT: $v8 = COPY [[ADD]](<vscale x 2 x s8>)
; CHECK-NEXT: PseudoRET implicit $v8
%0:_(<vscale x 2 x s8>) = COPY $v8
%1:_(<vscale x 2 x s8>) = COPY $v9
%2:_(<vscale x 2 x s8>) = G_ADD %0, %1
$v8 = COPY %2(<vscale x 2 x s8>)
PseudoRET implicit $v8

...
---
name: test_nxv4i8
body: |
bb.0.entry:

; CHECK-LABEL: name: test_nxv4i8
; CHECK: [[COPY:%[0-9]+]]:_(<vscale x 4 x s8>) = COPY $v8
; CHECK-NEXT: [[COPY1:%[0-9]+]]:_(<vscale x 4 x s8>) = COPY $v9
; CHECK-NEXT: [[ADD:%[0-9]+]]:_(<vscale x 4 x s8>) = G_ADD [[COPY]], [[COPY1]]
; CHECK-NEXT: $v8 = COPY [[ADD]](<vscale x 4 x s8>)
; CHECK-NEXT: PseudoRET implicit $v8
%0:_(<vscale x 4 x s8>) = COPY $v8
%1:_(<vscale x 4 x s8>) = COPY $v9
%2:_(<vscale x 4 x s8>) = G_ADD %0, %1
$v8 = COPY %2(<vscale x 4 x s8>)
PseudoRET implicit $v8

...
---
name: test_nxv8i8
body: |
bb.0.entry:

; CHECK-LABEL: name: test_nxv8i8
; CHECK: [[COPY:%[0-9]+]]:_(<vscale x 8 x s8>) = COPY $v8
; CHECK-NEXT: [[COPY1:%[0-9]+]]:_(<vscale x 8 x s8>) = COPY $v9
; CHECK-NEXT: [[ADD:%[0-9]+]]:_(<vscale x 8 x s8>) = G_ADD [[COPY]], [[COPY1]]
; CHECK-NEXT: $v8 = COPY [[ADD]](<vscale x 8 x s8>)
; CHECK-NEXT: PseudoRET implicit $v8
%0:_(<vscale x 8 x s8>) = COPY $v8
%1:_(<vscale x 8 x s8>) = COPY $v9
%2:_(<vscale x 8 x s8>) = G_ADD %0, %1
$v8 = COPY %2(<vscale x 8 x s8>)
PseudoRET implicit $v8

...
---
name: test_nxv16i8
body: |
bb.0.entry:

; CHECK-LABEL: name: test_nxv16i8
; CHECK: [[COPY:%[0-9]+]]:_(<vscale x 16 x s8>) = COPY $v8m2
; CHECK-NEXT: [[COPY1:%[0-9]+]]:_(<vscale x 16 x s8>) = COPY $v10m2
; CHECK-NEXT: [[ADD:%[0-9]+]]:_(<vscale x 16 x s8>) = G_ADD [[COPY]], [[COPY1]]
; CHECK-NEXT: $v8m2 = COPY [[ADD]](<vscale x 16 x s8>)
; CHECK-NEXT: PseudoRET implicit $v8m2
%0:_(<vscale x 16 x s8>) = COPY $v8m2
%1:_(<vscale x 16 x s8>) = COPY $v10m2
%2:_(<vscale x 16 x s8>) = G_ADD %0, %1
$v8m2 = COPY %2(<vscale x 16 x s8>)
PseudoRET implicit $v8m2

...
---
name: test_nxv32i8
body: |
bb.0.entry:

; CHECK-LABEL: name: test_nxv32i8
; CHECK: [[COPY:%[0-9]+]]:_(<vscale x 32 x s8>) = COPY $v8m4
; CHECK-NEXT: [[COPY1:%[0-9]+]]:_(<vscale x 32 x s8>) = COPY $v12m4
; CHECK-NEXT: [[ADD:%[0-9]+]]:_(<vscale x 32 x s8>) = G_ADD [[COPY]], [[COPY1]]
; CHECK-NEXT: $v8m4 = COPY [[ADD]](<vscale x 32 x s8>)
; CHECK-NEXT: PseudoRET implicit $v8m4
%0:_(<vscale x 32 x s8>) = COPY $v8m4
%1:_(<vscale x 32 x s8>) = COPY $v12m4
%2:_(<vscale x 32 x s8>) = G_ADD %0, %1
$v8m4 = COPY %2(<vscale x 32 x s8>)
PseudoRET implicit $v8m4

...
---
name: test_nxv64i8
body: |
bb.0.entry:

; CHECK-LABEL: name: test_nxv64i8
; CHECK: [[COPY:%[0-9]+]]:_(<vscale x 64 x s8>) = COPY $v8m8
; CHECK-NEXT: [[COPY1:%[0-9]+]]:_(<vscale x 64 x s8>) = COPY $v16m8
; CHECK-NEXT: [[ADD:%[0-9]+]]:_(<vscale x 64 x s8>) = G_ADD [[COPY]], [[COPY1]]
; CHECK-NEXT: $v8m8 = COPY [[ADD]](<vscale x 64 x s8>)
; CHECK-NEXT: PseudoRET implicit $v8m8
%0:_(<vscale x 64 x s8>) = COPY $v8m8
%1:_(<vscale x 64 x s8>) = COPY $v16m8
%2:_(<vscale x 64 x s8>) = G_ADD %0, %1
$v8m8 = COPY %2(<vscale x 64 x s8>)
PseudoRET implicit $v8m8

...
---
name: test_nxv2i16
body: |
bb.0.entry:

; CHECK-LABEL: name: test_nxv2i16
; CHECK: [[COPY:%[0-9]+]]:_(<vscale x 2 x s16>) = COPY $v8
; CHECK-NEXT: [[COPY1:%[0-9]+]]:_(<vscale x 2 x s16>) = COPY $v9
; CHECK-NEXT: [[ADD:%[0-9]+]]:_(<vscale x 2 x s16>) = G_ADD [[COPY]], [[COPY1]]
; CHECK-NEXT: $v8 = COPY [[ADD]](<vscale x 2 x s16>)
; CHECK-NEXT: PseudoRET implicit $v8
%0:_(<vscale x 2 x s16>) = COPY $v8
%1:_(<vscale x 2 x s16>) = COPY $v9
%2:_(<vscale x 2 x s16>) = G_ADD %0, %1
$v8 = COPY %2(<vscale x 2 x s16>)
PseudoRET implicit $v8

...
---
name: test_nxv4i16
body: |
bb.0.entry:

; CHECK-LABEL: name: test_nxv4i16
; CHECK: [[COPY:%[0-9]+]]:_(<vscale x 4 x s16>) = COPY $v8
; CHECK-NEXT: [[COPY1:%[0-9]+]]:_(<vscale x 4 x s16>) = COPY $v9
; CHECK-NEXT: [[ADD:%[0-9]+]]:_(<vscale x 4 x s16>) = G_ADD [[COPY]], [[COPY1]]
; CHECK-NEXT: $v8 = COPY [[ADD]](<vscale x 4 x s16>)
; CHECK-NEXT: PseudoRET implicit $v8
%0:_(<vscale x 4 x s16>) = COPY $v8
%1:_(<vscale x 4 x s16>) = COPY $v9
%2:_(<vscale x 4 x s16>) = G_ADD %0, %1
$v8 = COPY %2(<vscale x 4 x s16>)
PseudoRET implicit $v8

...
---
name: test_nxv8i16
body: |
bb.0.entry:

; CHECK-LABEL: name: test_nxv8i16
; CHECK: [[COPY:%[0-9]+]]:_(<vscale x 8 x s16>) = COPY $v8m2
; CHECK-NEXT: [[COPY1:%[0-9]+]]:_(<vscale x 8 x s16>) = COPY $v10m2
; CHECK-NEXT: [[ADD:%[0-9]+]]:_(<vscale x 8 x s16>) = G_ADD [[COPY]], [[COPY1]]
; CHECK-NEXT: $v8m2 = COPY [[ADD]](<vscale x 8 x s16>)
; CHECK-NEXT: PseudoRET implicit $v8m2
%0:_(<vscale x 8 x s16>) = COPY $v8m2
%1:_(<vscale x 8 x s16>) = COPY $v10m2
%2:_(<vscale x 8 x s16>) = G_ADD %0, %1
$v8m2 = COPY %2(<vscale x 8 x s16>)
PseudoRET implicit $v8m2

...
---
name: test_nxv16i16
body: |
bb.0.entry:

; CHECK-LABEL: name: test_nxv16i16
; CHECK: [[COPY:%[0-9]+]]:_(<vscale x 16 x s16>) = COPY $v8m4
; CHECK-NEXT: [[COPY1:%[0-9]+]]:_(<vscale x 16 x s16>) = COPY $v12m4
; CHECK-NEXT: [[ADD:%[0-9]+]]:_(<vscale x 16 x s16>) = G_ADD [[COPY]], [[COPY1]]
; CHECK-NEXT: $v8m4 = COPY [[ADD]](<vscale x 16 x s16>)
; CHECK-NEXT: PseudoRET implicit $v8m4
%0:_(<vscale x 16 x s16>) = COPY $v8m4
%1:_(<vscale x 16 x s16>) = COPY $v12m4
%2:_(<vscale x 16 x s16>) = G_ADD %0, %1
$v8m4 = COPY %2(<vscale x 16 x s16>)
PseudoRET implicit $v8m4

...
---
name: test_nxv32i16
body: |
bb.0.entry:

; CHECK-LABEL: name: test_nxv32i16
; CHECK: [[COPY:%[0-9]+]]:_(<vscale x 32 x s16>) = COPY $v8m8
; CHECK-NEXT: [[COPY1:%[0-9]+]]:_(<vscale x 32 x s16>) = COPY $v16m8
; CHECK-NEXT: [[ADD:%[0-9]+]]:_(<vscale x 32 x s16>) = G_ADD [[COPY]], [[COPY1]]
; CHECK-NEXT: $v8m8 = COPY [[ADD]](<vscale x 32 x s16>)
; CHECK-NEXT: PseudoRET implicit $v8m8
%0:_(<vscale x 32 x s16>) = COPY $v8m8
%1:_(<vscale x 32 x s16>) = COPY $v16m8
%2:_(<vscale x 32 x s16>) = G_ADD %0, %1
$v8m8 = COPY %2(<vscale x 32 x s16>)
PseudoRET implicit $v8m8

...
---
name: test_nxv2i32
body: |
bb.0.entry:

; CHECK-LABEL: name: test_nxv2i32
; CHECK: [[COPY:%[0-9]+]]:_(<vscale x 2 x s32>) = COPY $v8
; CHECK-NEXT: [[COPY1:%[0-9]+]]:_(<vscale x 2 x s32>) = COPY $v9
; CHECK-NEXT: [[ADD:%[0-9]+]]:_(<vscale x 2 x s32>) = G_ADD [[COPY]], [[COPY1]]
; CHECK-NEXT: $v8 = COPY [[ADD]](<vscale x 2 x s32>)
; CHECK-NEXT: PseudoRET implicit $v8
%0:_(<vscale x 2 x s32>) = COPY $v8
%1:_(<vscale x 2 x s32>) = COPY $v9
%2:_(<vscale x 2 x s32>) = G_ADD %0, %1
$v8 = COPY %2(<vscale x 2 x s32>)
PseudoRET implicit $v8

...
---
name: test_nxv4i32
body: |
bb.0.entry:

; CHECK-LABEL: name: test_nxv4i32
; CHECK: [[COPY:%[0-9]+]]:_(<vscale x 4 x s32>) = COPY $v8m2
; CHECK-NEXT: [[COPY1:%[0-9]+]]:_(<vscale x 4 x s32>) = COPY $v10m2
; CHECK-NEXT: [[ADD:%[0-9]+]]:_(<vscale x 4 x s32>) = G_ADD [[COPY]], [[COPY1]]
; CHECK-NEXT: $v8m2 = COPY [[ADD]](<vscale x 4 x s32>)
; CHECK-NEXT: PseudoRET implicit $v8m2
%0:_(<vscale x 4 x s32>) = COPY $v8m2
%1:_(<vscale x 4 x s32>) = COPY $v10m2
%2:_(<vscale x 4 x s32>) = G_ADD %0, %1
$v8m2 = COPY %2(<vscale x 4 x s32>)
PseudoRET implicit $v8m2

...
---
name: test_nxv8i32
body: |
bb.0.entry:

; CHECK-LABEL: name: test_nxv8i32
; CHECK: [[COPY:%[0-9]+]]:_(<vscale x 8 x s32>) = COPY $v8m4
; CHECK-NEXT: [[COPY1:%[0-9]+]]:_(<vscale x 8 x s32>) = COPY $v12m4
; CHECK-NEXT: [[ADD:%[0-9]+]]:_(<vscale x 8 x s32>) = G_ADD [[COPY]], [[COPY1]]
; CHECK-NEXT: $v8m4 = COPY [[ADD]](<vscale x 8 x s32>)
; CHECK-NEXT: PseudoRET implicit $v8m4
%0:_(<vscale x 8 x s32>) = COPY $v8m4
%1:_(<vscale x 8 x s32>) = COPY $v12m4
%2:_(<vscale x 8 x s32>) = G_ADD %0, %1
$v8m4 = COPY %2(<vscale x 8 x s32>)
PseudoRET implicit $v8m4

...
---
name: test_nxv16i32
body: |
bb.0.entry:

; CHECK-LABEL: name: test_nxv16i32
; CHECK: [[COPY:%[0-9]+]]:_(<vscale x 16 x s32>) = COPY $v8m8
; CHECK-NEXT: [[COPY1:%[0-9]+]]:_(<vscale x 16 x s32>) = COPY $v16m8
; CHECK-NEXT: [[ADD:%[0-9]+]]:_(<vscale x 16 x s32>) = G_ADD [[COPY]], [[COPY1]]
; CHECK-NEXT: $v8m8 = COPY [[ADD]](<vscale x 16 x s32>)
; CHECK-NEXT: PseudoRET implicit $v8m8
%0:_(<vscale x 16 x s32>) = COPY $v8m8
%1:_(<vscale x 16 x s32>) = COPY $v16m8
%2:_(<vscale x 16 x s32>) = G_ADD %0, %1
$v8m8 = COPY %2(<vscale x 16 x s32>)
PseudoRET implicit $v8m8

...

Loading