Skip to content

MachineVerifier should catch inconsistencies in load memory, result, and range metadata type. #97290

Closed
@arsenm

Description

@arsenm

The MachineVerifier does not catch cases where G_LOAD range metadata is applied to scalar memory types, with vector results and vice versa. The verifier should reject cases like this:

# RUN: llc -mtriple=amdgcn-mesa-mesa3d -mcpu=tahiti -run-pass=amdgpu-prelegalizer-combiner -verify-machineinstrs %s -o -

--- |
  define void @range_metadata_sext_i8_signed_range_i64_load_as_v2i32() {
   ret void
  }

  define void @range_metadata_sext_i8_signed_range_i64_load_as_v2i32_extractlo() {
   ret void
  }

  define void @range_metadata_sext_i33_signed_range_i64_load_as_v2i32() {
    ret void
  }

  !0 = !{i64 -4294967295, i64 4294967296}
  !1 = !{i64 -8589934591, i64 8589934592}

...
---
name:            range_metadata_sext_i8_signed_range_i64_load_as_v2i32
tracksRegLiveness: true
body:             |
  bb.0:
    liveins: $vgpr0, $vgpr1

    %1:_(s32) = COPY $vgpr0
    %2:_(s32) = COPY $vgpr1
    %0:_(p1) = G_MERGE_VALUES %1(s32), %2(s32)
    %3:_(<2 x s32>) = G_LOAD %0(p1) :: (volatile load (s64), align 4, !range !0, addrspace 1)
    %6:_(<2 x s32>) = G_SEXT_INREG %3, 9
    $vgpr0_vgpr1 = COPY %6
    SI_RETURN implicit $vgpr0_vgpr1

...

---
name:            range_metadata_sext_i8_signed_range_i64_load_as_v2i32_extractlo
tracksRegLiveness: true
body:             |
  bb.0:
    liveins: $vgpr0, $vgpr1

    %1:_(s32) = COPY $vgpr0
    %2:_(s32) = COPY $vgpr1
    %0:_(p1) = G_MERGE_VALUES %1(s32), %2(s32)
    %3:_(<2 x s32>) = G_LOAD %0(p1) :: (volatile load (s64), align 4, !range !0, addrspace 1)
    %zero:_(s32) = G_CONSTANT i32 0
    %extract:_(s32) = G_EXTRACT_VECTOR_ELT %3, %zero
    %6:_(s32) = G_SEXT_INREG %zero, 9
    $vgpr0 = COPY %6
    SI_RETURN implicit $vgpr0, implicit $vgpr1

...

---
name:            range_metadata_sext_i33_signed_range_i64_load_as_v2i32
tracksRegLiveness: true
body:             |
  bb.0:
    liveins: $vgpr0, $vgpr1

    %1:_(s32) = COPY $vgpr0
    %2:_(s32) = COPY $vgpr1
    %0:_(p1) = G_MERGE_VALUES %1(s32), %2(s32)
    %3:_(<2 x s32>) = G_LOAD %0(p1) :: (volatile load (s64), align 4, !range !1, addrspace 1)
    $vgpr0_vgpr1 = COPY %3
    SI_RETURN implicit $vgpr0_vgpr1

...

Here we have an i64 range value applied to a <2 x i32> result, which should be invalid.
%3:_(<2 x s32>) = G_LOAD %0(p1) :: (volatile load (s64), align 4, !range !0, addrspace 1)

We also are not clean about ensuring we have vector element matches between the result and memory type, but I think that's a more difficult issue to fix than verifying the range metadata.

Metadata

Metadata

Assignees

Labels

Type

No type

Projects

No projects

Milestone

No milestone

Relationships

None yet

Development

No branches or pull requests

Issue actions