Skip to content

Commit

Permalink
[CIR][Lowering][Bugfix] Fix lowering of bool_to_int cast (llvm#450)
Browse files Browse the repository at this point in the history
The minimal bug repro:
```
#include <stdbool.h>
#include <stdint.h>
void bar() {
  bool x = true;
  uint8_t y = (uint8_t)x;
}
```
Fails on verification stage:
```
loc("repro.c":5:24): error: integer width of the output type is smaller or equal to the integer width of the input type
fatal error: error in backend: The pass manager failed to lower CIR to LLVMIR dialect!
```
The problem is that in some cases lowering from CIR emits the invalid
zext operation. PR fixes this issue by emitting the llvm.bitcast instead
of llvm.zext in such cases.
  • Loading branch information
YazZz1k authored and lanza committed Apr 17, 2024
1 parent 45e2c65 commit 079e46b
Show file tree
Hide file tree
Showing 2 changed files with 24 additions and 3 deletions.
12 changes: 9 additions & 3 deletions clang/lib/CIR/Lowering/DirectToLLVM/LowerToLLVM.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -664,9 +664,15 @@ class CIRCastOpLowering : public mlir::OpConversionPattern<mlir::cir::CastOp> {
case mlir::cir::CastKind::bool_to_int: {
auto dstTy = castOp.getType().cast<mlir::cir::IntType>();
auto llvmSrcVal = adaptor.getOperands().front();
auto llvmDstTy = getTypeConverter()->convertType(dstTy);
rewriter.replaceOpWithNewOp<mlir::LLVM::ZExtOp>(castOp, llvmDstTy,
llvmSrcVal);
auto llvmSrcTy = llvmSrcVal.getType().cast<mlir::IntegerType>();
auto llvmDstTy =
getTypeConverter()->convertType(dstTy).cast<mlir::IntegerType>();
if (llvmSrcTy.getWidth() == llvmDstTy.getWidth())
rewriter.replaceOpWithNewOp<mlir::LLVM::BitcastOp>(castOp, llvmDstTy,
llvmSrcVal);
else
rewriter.replaceOpWithNewOp<mlir::LLVM::ZExtOp>(castOp, llvmDstTy,
llvmSrcVal);
return mlir::success();
}
case mlir::cir::CastKind::bool_to_float: {
Expand Down
15 changes: 15 additions & 0 deletions clang/test/CIR/Lowering/cast.cir
Original file line number Diff line number Diff line change
Expand Up @@ -81,4 +81,19 @@ module {
%19 = cir.load %2 : cir.ptr <!s32i>, !s32i
cir.return %19 : !s32i
}

cir.func @testBoolToIntCast(%arg0: !cir.bool) {
// CHECK: llvm.func @testBoolToIntCast
%0 = cir.alloca !cir.bool, cir.ptr <!cir.bool>, ["bl", init] {alignment = 1 : i64}
%1 = cir.alloca !u8i, cir.ptr <!u8i>, ["y", init] {alignment = 1 : i64}
cir.store %arg0, %0 : !cir.bool, cir.ptr <!cir.bool>

%2 = cir.load %0 : cir.ptr <!cir.bool>, !cir.bool
%3 = cir.cast(bool_to_int, %2 : !cir.bool), !u8i
// CHECK: %[[LOAD_BOOL:.*]] = llvm.load %{{.*}} : !llvm.ptr -> i8
// CHECK: %{{.*}} = llvm.bitcast %[[LOAD_BOOL]] : i8 to i8

cir.store %3, %1 : !u8i, cir.ptr <!u8i>
cir.return
}
}

0 comments on commit 079e46b

Please sign in to comment.