From: Matt Arsenault Date: Mon, 11 Feb 2019 22:12:43 +0000 (+0000) Subject: GlobalISel: Verify G_EXTRACT X-Git-Url: https://granicus.if.org/sourcecode?a=commitdiff_plain;h=45f5ca3e2d402f72fe29084929eaad4652a6362d;p=llvm GlobalISel: Verify G_EXTRACT git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@353759 91177308-0d34-0410-b5e6-96231b3b80d8 --- diff --git a/lib/CodeGen/MachineVerifier.cpp b/lib/CodeGen/MachineVerifier.cpp index 45fe64e45ba..280283f939f 100644 --- a/lib/CodeGen/MachineVerifier.cpp +++ b/lib/CodeGen/MachineVerifier.cpp @@ -1261,6 +1261,28 @@ void MachineVerifier::verifyPreISelGenericInstruction(const MachineInstr *MI) { break; } + case TargetOpcode::G_EXTRACT: { + const MachineOperand &SrcOp = MI->getOperand(1); + if (!SrcOp.isReg()) { + report("extract source must be a register", MI); + break; + } + + const MachineOperand &OffsetOp = MI->getOperand(2); + if (!OffsetOp.isImm()) { + report("extract offset must be a constant", MI); + break; + } + + unsigned DstSize = MRI->getType(MI->getOperand(0).getReg()).getSizeInBits(); + unsigned SrcSize = MRI->getType(SrcOp.getReg()).getSizeInBits(); + if (SrcSize == DstSize) + report("extract source must be larger than result", MI); + + if (DstSize + OffsetOp.getImm() > SrcSize) + report("extract reads past end of register", MI); + break; + } default: break; } diff --git a/test/CodeGen/AMDGPU/GlobalISel/legalize-extract.mir b/test/CodeGen/AMDGPU/GlobalISel/legalize-extract.mir index f93fb899211..3425ecb4c4d 100644 --- a/test/CodeGen/AMDGPU/GlobalISel/legalize-extract.mir +++ b/test/CodeGen/AMDGPU/GlobalISel/legalize-extract.mir @@ -216,12 +216,12 @@ body: | ; CHECK: [[TRUNC:%[0-9]+]]:_(<6 x s1>) = G_TRUNC [[DEF]](<6 x s32>) ; CHECK: [[EXTRACT:%[0-9]+]]:_(<5 x s1>) = G_EXTRACT [[TRUNC]](<6 x s1>), 0 ; CHECK: [[ANYEXT:%[0-9]+]]:_(<5 x s16>) = G_ANYEXT [[EXTRACT]](<5 x s1>) - ; CHECK: [[EXTRACT1:%[0-9]+]]:_(s16) = G_EXTRACT [[ANYEXT]](<5 x s16>), 80 + ; CHECK: [[EXTRACT1:%[0-9]+]]:_(s16) = G_EXTRACT [[ANYEXT]](<5 x s16>), 64 ; CHECK: [[TRUNC1:%[0-9]+]]:_(s1) = G_TRUNC [[EXTRACT1]](s16) ; CHECK: [[ANYEXT1:%[0-9]+]]:_(s32) = G_ANYEXT [[TRUNC1]](s1) ; CHECK: $vgpr0 = COPY [[ANYEXT1]](s32) %0:_(<5 x s1>) = G_IMPLICIT_DEF - %1:_(s1) = G_EXTRACT %0, 5 + %1:_(s1) = G_EXTRACT %0, 4 %2:_(s32) = G_ANYEXT %1 $vgpr0 = COPY %2 ... diff --git a/test/Verifier/test_g_extract.mir b/test/Verifier/test_g_extract.mir new file mode 100644 index 00000000000..62064ae8021 --- /dev/null +++ b/test/Verifier/test_g_extract.mir @@ -0,0 +1,35 @@ +# RUN: not llc -march=aarch64 -o /dev/null -run-pass=none -verify-machineinstrs %s 2>&1 | FileCheck %s +# REQUIRES: global-isel, aarch64-registered-target + +--- +name: test_extract +legalized: true +regBankSelected: false +selected: false +tracksRegLiveness: true +liveins: +body: | + bb.0: + + ; CHECK: Bad machine code: Too few operands + %0:_(s32) = G_EXTRACT + + ; CHECK: Bad machine code: Too few operands + %1:_(s32) = G_EXTRACT 0 + + ; CHECK: Bad machine code: extract source must be a register + %2:_(s32) = G_EXTRACT 0, 1 + + ; CHECK: Bad machine code: extract offset must be a constant + %3:_(s32) = G_IMPLICIT_DEF + %4:_(s32) = G_CONSTANT i32 0 + %5:_(s16) = G_EXTRACT %3, %4 + + ; CHECK: Bad machine code: extract source must be larger than result + %6:_(s32) = G_IMPLICIT_DEF + %7:_(s32) = G_EXTRACT %6, 0 + + ; CHECK: Bad machine code: extract reads past end of register + %8:_(s1) = G_EXTRACT %6, 32 + +...