Skip to content

Commit

Permalink
[RISCV][GISel] IRTranslate and Legalize some instructions with scalab…
Browse files Browse the repository at this point in the history
…le vector type

* Add IRTranslate tests for ADD, SUB, AND, OR, and XOR with scalable
  vector types to show that they work as expected.
* Legalize G_ADD, G_SUB, G_AND, G_OR, and G_XOR of scalable vector
  type for the RISC-V vector extension.
  • Loading branch information
jiahanxie353 authored and michaelmaitland committed Jan 10, 2024
1 parent a9f39ff commit e42a70a
Show file tree
Hide file tree
Showing 9 changed files with 2,369 additions and 2 deletions.
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 @@ -20019,8 +20019,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
; 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

0 comments on commit e42a70a

Please sign in to comment.