Skip to content

Commit

Permalink
[CIR][Dialect] Verify bitcast does not contain address space conversi…
Browse files Browse the repository at this point in the history
…on (#813)

Currently some bitcasts would silently change the address space of
source pointer type, which hides some miscompilations of pointer type in
CIR.

#812 is an example. The address space in result pointer type is dropped,
but the bitcast later keep the type consistency no matter what the
result type is. Such bitcast is commonly emitted in CodeGen.

CIR bitcasts are lowered to LLVM bitcasts, which also don't allow
mismatch between address spaces. This PR adds this verification.
  • Loading branch information
seven-mile authored Sep 10, 2024
1 parent c329de7 commit 4780fb7
Show file tree
Hide file tree
Showing 2 changed files with 28 additions and 3 deletions.
16 changes: 13 additions & 3 deletions clang/lib/CIR/Dialect/IR/CIRDialect.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -510,11 +510,21 @@ LogicalResult CastOp::verify() {
if (isa<StructType>(srcType) || isa<StructType>(resType))
return success();

// Handle the pointer types first.
auto srcPtrTy = mlir::dyn_cast<mlir::cir::PointerType>(srcType);
auto resPtrTy = mlir::dyn_cast<mlir::cir::PointerType>(resType);

if (srcPtrTy && resPtrTy) {
if (srcPtrTy.getAddrSpace() != resPtrTy.getAddrSpace()) {
return emitOpError() << "result type address space does not match the "
"address space of the operand";
}
return success();
}

// This is the only cast kind where we don't want vector types to decay
// into the element type.
if ((!mlir::isa<mlir::cir::PointerType>(getSrc().getType()) ||
!mlir::isa<mlir::cir::PointerType>(getResult().getType())) &&
(!mlir::isa<mlir::cir::VectorType>(getSrc().getType()) ||
if ((!mlir::isa<mlir::cir::VectorType>(getSrc().getType()) ||
!mlir::isa<mlir::cir::VectorType>(getResult().getType())))
return emitOpError()
<< "requires !cir.ptr or !cir.vector type for source and result";
Expand Down
15 changes: 15 additions & 0 deletions clang/test/CIR/IR/invalid.cir
Original file line number Diff line number Diff line change
Expand Up @@ -1298,3 +1298,18 @@ module {
cir.return
}
}

// -----

!s32i = !cir.int<s, 32>

module {

cir.func @test_bitcast_addrspace() {
%0 = cir.alloca !s32i, !cir.ptr<!s32i>, ["tmp"] {alignment = 4 : i64}
// expected-error@+1 {{'cir.cast' op result type address space does not match the address space of the operand}}
%1 = cir.cast(bitcast, %0 : !cir.ptr<!s32i>), !cir.ptr<!s32i, addrspace(offload_local)>
}

}

0 comments on commit 4780fb7

Please sign in to comment.