Index: lib/CodeGen/MachineVerifier.cpp =================================================================== --- lib/CodeGen/MachineVerifier.cpp +++ lib/CodeGen/MachineVerifier.cpp @@ -1038,6 +1038,50 @@ report("bitcast sizes must match", MI); break; } + case TargetOpcode::G_INTTOPTR: + case TargetOpcode::G_PTRTOINT: + case TargetOpcode::G_ADDRSPACE_CAST: { + LLT DstTy = MRI->getType(MI->getOperand(0).getReg()); + LLT SrcTy = MRI->getType(MI->getOperand(1).getReg()); + if (!DstTy.isValid() || !SrcTy.isValid()) + break; + + if (DstTy.isVector() != SrcTy.isVector()) + report("pointer casts must be all-vector or all-scalar", MI); + else { + if (DstTy.isVector() ) { + if (DstTy.getNumElements() != SrcTy.getNumElements()) { + report("pointer casts must preserve number of elements", MI); + break; + } + } + } + + DstTy = DstTy.getScalarType(); + SrcTy = SrcTy.getScalarType(); + + if (MI->getOpcode() == TargetOpcode::G_INTTOPTR) { + if (!DstTy.isPointer()) + report("inttoptr result type must be a pointer", MI); + if (SrcTy.isPointer()) + report("inttoptr source type must not be a pointer", MI); + } else if (MI->getOpcode() == TargetOpcode::G_PTRTOINT) { + if (!SrcTy.isPointer()) + report("ptrtoint source type must be a pointer", MI); + if (DstTy.isPointer()) + report("ptrtoint result type must not be a pointer", MI); + } else { + assert(MI->getOpcode() == TargetOpcode::G_ADDRSPACE_CAST); + if (!SrcTy.isPointer() || !DstTy.isPointer()) + report("addrspacecast types must be pointers", MI); + else { + if (SrcTy.getAddressSpace() == DstTy.getAddressSpace()) + report("addrspacecast must convert different address spaces", MI); + } + } + + break; + } case TargetOpcode::G_SEXT: case TargetOpcode::G_ZEXT: case TargetOpcode::G_ANYEXT: Index: test/CodeGen/AArch64/GlobalISel/legalize-inttoptr-xfail-1.mir =================================================================== --- test/CodeGen/AArch64/GlobalISel/legalize-inttoptr-xfail-1.mir +++ test/CodeGen/AArch64/GlobalISel/legalize-inttoptr-xfail-1.mir @@ -15,9 +15,9 @@ # and fix the mistake: check that type index 0 is p0 and type index 1 # is s64 (in that order). -# CHECK: LLVM ERROR: unable to legalize instruction: -# CHECK-SAME: %{{[0-9]+}}:_(s64) = G_INTTOPTR %{{[0-9]+}}:_(p0) -# CHECK-SAME: (in function: broken) +# CHECK: Bad machine code: inttoptr result type must be a pointer +# CHECK: Bad machine code: inttoptr source type must not be a pointer +# CHECK: LLVM ERROR: Found 2 machine code errors. --- name: broken Index: test/CodeGen/AArch64/GlobalISel/legalize-inttoptr-xfail-2.mir =================================================================== --- test/CodeGen/AArch64/GlobalISel/legalize-inttoptr-xfail-2.mir +++ test/CodeGen/AArch64/GlobalISel/legalize-inttoptr-xfail-2.mir @@ -19,9 +19,8 @@ # and fix the mistake: check that type index 0 is p0 and type index 1 # is s64. -# CHECK: LLVM ERROR: unable to legalize instruction: -# CHECK-SAME: %{{[0-9]+}}:_(p0) = G_INTTOPTR %{{[0-9]+}}:_(<4 x s16>) -# CHECK-SAME: (in function: broken) +# CHECK: Bad machine code: pointer casts must be all-vector or all-scalar +# CHECK: LLVM ERROR: Found 1 machine code errors. --- name: broken Index: test/CodeGen/AMDGPU/GlobalISel/regbankselect-ptrtoint.mir =================================================================== --- test/CodeGen/AMDGPU/GlobalISel/regbankselect-ptrtoint.mir +++ test/CodeGen/AMDGPU/GlobalISel/regbankselect-ptrtoint.mir @@ -10,10 +10,10 @@ bb.0: liveins: $sgpr0_sgpr1 ; CHECK-LABEL: name: ptrtoint_s - ; CHECK: [[COPY:%[0-9]+]]:sgpr(s64) = COPY $sgpr0_sgpr1 - ; CHECK: [[PTRTOINT:%[0-9]+]]:sgpr(p4) = G_PTRTOINT [[COPY]](s64) - %0:_(s64) = COPY $sgpr0_sgpr1 - %1:_(p4) = G_PTRTOINT %0 + ; CHECK: [[COPY:%[0-9]+]]:sgpr(p1) = COPY $sgpr0_sgpr1 + ; CHECK: [[PTRTOINT:%[0-9]+]]:sgpr(s64) = G_PTRTOINT [[COPY]](p1) + %0:_(p1) = COPY $sgpr0_sgpr1 + %1:_(s64) = G_PTRTOINT %0 ... --- @@ -24,8 +24,8 @@ bb.0: liveins: $vgpr0_vgpr1 ; CHECK-LABEL: name: ptrtoint_v - ; CHECK: [[COPY:%[0-9]+]]:vgpr(s64) = COPY $vgpr0_vgpr1 - ; CHECK: [[PTRTOINT:%[0-9]+]]:vgpr(p0) = G_PTRTOINT [[COPY]](s64) - %0:_(s64) = COPY $vgpr0_vgpr1 - %1:_(p0) = G_PTRTOINT %0 + ; CHECK: [[COPY:%[0-9]+]]:vgpr(p1) = COPY $vgpr0_vgpr1 + ; CHECK: [[PTRTOINT:%[0-9]+]]:vgpr(s64) = G_PTRTOINT [[COPY]](p1) + %0:_(p1) = COPY $vgpr0_vgpr1 + %1:_(s64) = G_PTRTOINT %0 ... Index: test/Verifier/test_g_addrspacecast.mir =================================================================== --- /dev/null +++ test/Verifier/test_g_addrspacecast.mir @@ -0,0 +1,57 @@ +#RUN: not llc -o - -run-pass=none -verify-machineinstrs %s 2>&1 | FileCheck %s +# REQUIRES: global-isel, aarch64-registered-target + +--- +name: test_addrspacecast +legalized: true +regBankSelected: false +selected: false +tracksRegLiveness: true +liveins: +body: | + bb.0: + + %0:_(s64) = G_IMPLICIT_DEF + %1:_(p0) = G_IMPLICIT_DEF + %2:_(<2 x s64>) = G_IMPLICIT_DEF + %3:_(<2 x p0>) = G_IMPLICIT_DEF + + ; CHECK: Bad machine code: Too few operands + %4:_(s64) = G_ADDRSPACE_CAST + + ; CHECK: Bad machine code: Too few operands + ; CHECK: Bad machine code: Explicit definition marked as use + G_ADDRSPACE_CAST %1 + + ; CHECK: Bad machine code: addrspacecast types must be pointers + %5:_(p0) = G_ADDRSPACE_CAST %0 + + ; CHECK: Bad machine code: addrspacecast types must be pointers + %6:_(s64) = G_ADDRSPACE_CAST %1 + + ; CHECK: Bad machine code: addrspacecast types must be pointers + %7:_(<2 x s64>) = G_ADDRSPACE_CAST %1 + + ; CHECK: Bad machine code: addrspacecast types must be pointers + %8:_(<2 x p0>) = G_ADDRSPACE_CAST %2 + + ; CHECK: Bad machine code: pointer casts must be all-vector or all-scalar + %9:_(<2 x p1>) = G_ADDRSPACE_CAST %1 + + ; CHECK: Bad machine code: pointer casts must be all-vector or all-scalar + %10:_(p1) = G_ADDRSPACE_CAST %3 + + ; CHECK: Bad machine code: pointer casts must preserve number of elements + %11:_(<4 x p1>) = G_ADDRSPACE_CAST %3 + + ; CHECK: Bad machine code: pointer casts must preserve number of elements + %12:_(<4 x p1>) = G_IMPLICIT_DEF + %13:_(<2 x p0>) = G_ADDRSPACE_CAST %12 + + ; CHECK: Bad machine code: addrspacecast must convert different address spaces + %14:_(p0) = G_ADDRSPACE_CAST %1 + + ; CHECK: Bad machine code: addrspacecast must convert different address spaces + %15:_(<2 x p0>) = G_ADDRSPACE_CAST %3 + +... Index: test/Verifier/test_g_inttoptr.mir =================================================================== --- /dev/null +++ test/Verifier/test_g_inttoptr.mir @@ -0,0 +1,45 @@ +#RUN: not llc -o - -run-pass=none -verify-machineinstrs %s 2>&1 | FileCheck %s +# REQUIRES: global-isel, aarch64-registered-target + +--- +name: test_inttoptr +legalized: true +regBankSelected: false +selected: false +tracksRegLiveness: true +liveins: +body: | + bb.0: + + %0:_(s64) = G_IMPLICIT_DEF + %1:_(p0) = G_IMPLICIT_DEF + %2:_(<2 x s64>) = G_IMPLICIT_DEF + %3:_(<2 x p0>) = G_IMPLICIT_DEF + + ; CHECK: Bad machine code: Too few operands + %4:_(p0) = G_INTTOPTR + + ; CHECK: Bad machine code: Too few operands + ; CHECK: Bad machine code: Explicit definition marked as use + G_INTTOPTR %0 + + ; CHECK: Bad machine code: inttoptr result type must be a pointer + %5:_(s64) = G_INTTOPTR %0 + + ; CHECK: Bad machine code: inttoptr result type must be a pointer + %6:_(<2 x s64>) = G_INTTOPTR %2 + + ; CHECK: Bad machine code: pointer casts must be all-vector or all-scalar + %7:_(<2 x p0>) = G_INTTOPTR %0 + + ; CHECK: Bad machine code: pointer casts must be all-vector or all-scalar + %8:_(p0) = G_INTTOPTR %2 + + ; CHECK: Bad machine code: pointer casts must preserve number of elements + %9:_(<4 x p0>) = G_INTTOPTR %2 + + ; CHECK: Bad machine code: pointer casts must preserve number of elements + %10:_(<4 x s64>) = G_IMPLICIT_DEF + %11:_(<2 x p0>) = G_INTTOPTR %10 + +... Index: test/Verifier/test_g_ptrtoint.mir =================================================================== --- /dev/null +++ test/Verifier/test_g_ptrtoint.mir @@ -0,0 +1,45 @@ +#RUN: not llc -o - -run-pass=none -verify-machineinstrs %s 2>&1 | FileCheck %s +# REQUIRES: global-isel, aarch64-registered-target + +--- +name: test_ptrtoint +legalized: true +regBankSelected: false +selected: false +tracksRegLiveness: true +liveins: +body: | + bb.0: + + %0:_(s64) = G_IMPLICIT_DEF + %1:_(p0) = G_IMPLICIT_DEF + %2:_(<2 x s64>) = G_IMPLICIT_DEF + %3:_(<2 x p0>) = G_IMPLICIT_DEF + + ; CHECK: Bad machine code: Too few operands + %4:_(s64) = G_PTRTOINT + + ; CHECK: Bad machine code: Too few operands + ; CHECK: Bad machine code: Explicit definition marked as use + G_PTRTOINT %1 + + ; CHECK: Bad machine code: ptrtoint result type must not be a pointer + %5:_(p0) = G_PTRTOINT %1 + + ; CHECK: Bad machine code: ptrtoint result type must not be a pointer + %6:_(<2 x p0>) = G_PTRTOINT %0 + + ; CHECK: Bad machine code: ptrtoint source type must be a pointer + %7:_(<2 x s64>) = G_PTRTOINT %2 + + ; CHECK: Bad machine code: pointer casts must be all-vector or all-scalar + %8:_(s64) = G_PTRTOINT %3 + + ; CHECK: Bad machine code: pointer casts must preserve number of elements + %9:_(<4 x s64>) = G_INTTOPTR %3 + + ; CHECK: Bad machine code: pointer casts must preserve number of elements + %10:_(<4 x p0>) = G_IMPLICIT_DEF + %11:_(<2 x s64>) = G_PTRTOINT %10 + +...