Skip to content

Commit

Permalink
[CIR][DirectToLLVM] Lower cir.bool to i1
Browse files Browse the repository at this point in the history
  • Loading branch information
orbiri committed Dec 21, 2024
1 parent 8c4c3ca commit 8fe8f86
Show file tree
Hide file tree
Showing 20 changed files with 272 additions and 204 deletions.
253 changes: 155 additions & 98 deletions clang/lib/CIR/Lowering/DirectToLLVM/LowerToLLVM.cpp

Large diffs are not rendered by default.

35 changes: 34 additions & 1 deletion clang/lib/CIR/Lowering/DirectToLLVM/LowerToLLVM.h
Original file line number Diff line number Diff line change
Expand Up @@ -14,13 +14,15 @@
#include "mlir/Dialect/LLVMIR/LLVMDialect.h"
#include "mlir/Dialect/LLVMIR/LLVMTypes.h"
#include "mlir/IR/MLIRContext.h"
#include "mlir/Interfaces/DataLayoutInterfaces.h"
#include "mlir/Transforms/DialectConversion.h"

namespace cir {
namespace direct {
mlir::Value lowerCirAttrAsValue(mlir::Operation *parentOp, mlir::Attribute attr,
mlir::ConversionPatternRewriter &rewriter,
const mlir::TypeConverter *converter);
const mlir::TypeConverter *converter,
mlir::DataLayout const &dataLayout);

mlir::LLVM::Linkage convertLinkage(cir::GlobalLinkageKind linkage);

Expand Down Expand Up @@ -271,7 +273,15 @@ class CIRToLLVMAllocaOpLowering
};

class CIRToLLVMLoadOpLowering : public mlir::OpConversionPattern<cir::LoadOp> {
mlir::DataLayout const &dataLayout;

public:
CIRToLLVMLoadOpLowering(mlir::TypeConverter const &typeConverter,
mlir::DataLayout const &dataLayout,
mlir::MLIRContext *context)
: OpConversionPattern<cir::LoadOp>(typeConverter, context),
dataLayout(dataLayout) {}

using mlir::OpConversionPattern<cir::LoadOp>::OpConversionPattern;

mlir::LogicalResult
Expand All @@ -281,7 +291,15 @@ class CIRToLLVMLoadOpLowering : public mlir::OpConversionPattern<cir::LoadOp> {

class CIRToLLVMStoreOpLowering
: public mlir::OpConversionPattern<cir::StoreOp> {
mlir::DataLayout const &dataLayout;

public:
CIRToLLVMStoreOpLowering(mlir::TypeConverter const &typeConverter,
mlir::DataLayout const &dataLayout,
mlir::MLIRContext *context)
: OpConversionPattern<cir::StoreOp>(typeConverter, context),
dataLayout(dataLayout) {}

using mlir::OpConversionPattern<cir::StoreOp>::OpConversionPattern;

mlir::LogicalResult
Expand All @@ -291,7 +309,14 @@ class CIRToLLVMStoreOpLowering

class CIRToLLVMConstantOpLowering
: public mlir::OpConversionPattern<cir::ConstantOp> {
mlir::DataLayout const &dataLayout;

public:
CIRToLLVMConstantOpLowering(mlir::TypeConverter const &typeConverter,
mlir::DataLayout const &dataLayout,
mlir::MLIRContext *context)
: OpConversionPattern<cir::ConstantOp>(typeConverter, context),
dataLayout(dataLayout) {}
using mlir::OpConversionPattern<cir::ConstantOp>::OpConversionPattern;

mlir::LogicalResult
Expand Down Expand Up @@ -490,7 +515,15 @@ class CIRToLLVMSwitchFlatOpLowering

class CIRToLLVMGlobalOpLowering
: public mlir::OpConversionPattern<cir::GlobalOp> {
mlir::DataLayout const &dataLayout;

public:
CIRToLLVMGlobalOpLowering(mlir::TypeConverter const &typeConverter,
mlir::DataLayout const &dataLayout,
mlir::MLIRContext *context)
: OpConversionPattern<cir::GlobalOp>(typeConverter, context),
dataLayout(dataLayout) {}

using mlir::OpConversionPattern<cir::GlobalOp>::OpConversionPattern;

mlir::LogicalResult
Expand Down
6 changes: 2 additions & 4 deletions clang/test/CIR/CodeGen/atomic-xchg-field.c
Original file line number Diff line number Diff line change
Expand Up @@ -58,16 +58,14 @@ void structAtomicExchange(unsigned referenceCount, wPtr item) {
// LLVM: %[[RES:.*]] = cmpxchg weak ptr %9, i32 %[[EXP]], i32 %[[DES]] seq_cst seq_cst
// LLVM: %[[OLD:.*]] = extractvalue { i32, i1 } %[[RES]], 0
// LLVM: %[[CMP:.*]] = extractvalue { i32, i1 } %[[RES]], 1
// LLVM: %[[Z:.*]] = zext i1 %[[CMP]] to i8, !dbg !16
// LLVM: %[[X:.*]] = xor i8 %[[Z]], 1, !dbg !16
// LLVM: %[[FAIL:.*]] = trunc i8 %[[X]] to i1, !dbg !16

// LLVM: %[[FAIL:.*]] = xor i1 %[[CMP]], true, !dbg !16
// LLVM: br i1 %[[FAIL:.*]], label %[[STORE_OLD:.*]], label %[[CONTINUE:.*]],
// LLVM: [[STORE_OLD]]:
// LLVM: store i32 %[[OLD]], ptr
// LLVM: br label %[[CONTINUE]]

// LLVM: [[CONTINUE]]:
// LLVM: %[[Z:.*]] = zext i1 %[[CMP]] to i8
// LLVM: store i8 %[[Z]], ptr {{.*}}, align 1
// LLVM: ret void

Expand Down
10 changes: 4 additions & 6 deletions clang/test/CIR/CodeGen/bf16-ops.c
Original file line number Diff line number Diff line change
Expand Up @@ -41,14 +41,12 @@ void foo(void) {
// NATIVE-NEXT: %{{.+}} = cir.cast(integral, %[[#C]] : !s32i), !u32i

// NONATIVE-LLVM: %[[#A:]] = fcmp une bfloat %{{.+}}, 0xR0000
// NONATIVE-LLVM-NEXT: %[[#B:]] = zext i1 %[[#A]] to i8
// NONATIVE-LLVM-NEXT: %[[#C:]] = xor i8 %[[#B]], 1
// NONATIVE-LLVM-NEXT: %{{.+}} = zext i8 %[[#C]] to i32
// NONATIVE-LLVM-NEXT: %[[#C:]] = xor i1 %[[#A]], true
// NONATIVE-LLVM-NEXT: %{{.+}} = zext i1 %[[#C]] to i32

// NATIVE-LLVM: %[[#A:]] = fcmp une bfloat %{{.+}}, 0xR0000
// NATIVE-LLVM-NEXT: %[[#B:]] = zext i1 %[[#A]] to i8
// NATIVE-LLVM-NEXT: %[[#C:]] = xor i8 %[[#B]], 1
// NATIVE-LLVM-NEXT: %{{.+}} = zext i8 %[[#C]] to i32
// NATIVE-LLVM-NEXT: %[[#C:]] = xor i1 %[[#A]], true
// NATIVE-LLVM-NEXT: %{{.+}} = zext i1 %[[#C]] to i32

h1 = -h1;
// NONATIVE: %[[#A:]] = cir.cast(floating, %{{.+}} : !cir.bf16), !cir.float
Expand Down
2 changes: 1 addition & 1 deletion clang/test/CIR/CodeGen/builtin-assume.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -16,7 +16,7 @@ int test_assume(int x) {
// CIR: }

// LLVM: @_Z11test_assumei
// LLVM: %[[#cond:]] = trunc i8 %{{.+}} to i1
// LLVM: %[[#cond:]] = icmp sgt i32 %{{.+}}, 0
// LLVM-NEXT: call void @llvm.assume(i1 %[[#cond]])

int test_assume_aligned(int *ptr) {
Expand Down
3 changes: 1 addition & 2 deletions clang/test/CIR/CodeGen/builtin-constant-p.c
Original file line number Diff line number Diff line change
Expand Up @@ -20,8 +20,7 @@ int foo() {
// LLVM: [[TMP1:%.*]] = alloca i32, i64 1
// LLVM: [[TMP2:%.*]] = load i32, ptr @a
// LLVM: [[TMP3:%.*]] = call i1 @llvm.is.constant.i32(i32 [[TMP2]])
// LLVM: [[TMP4:%.*]] = zext i1 [[TMP3]] to i8
// LLVM: [[TMP5:%.*]] = zext i8 [[TMP4]] to i32
// LLVM: [[TMP5:%.*]] = zext i1 [[TMP3]] to i32
// LLVM: store i32 [[TMP5]], ptr [[TMP1]]
// LLVM: [[TMP6:%.*]] = load i32, ptr [[TMP1]]
// LLVM: ret i32 [[TMP6]]
Expand Down
9 changes: 3 additions & 6 deletions clang/test/CIR/CodeGen/complex-arithmetic.c
Original file line number Diff line number Diff line change
Expand Up @@ -303,12 +303,9 @@ void mul() {
// LLVM-FULL-NEXT: %[[#F:]] = fadd double %[[#C]], %[[#D]]
// LLVM-FULL-NEXT: %[[#G:]] = insertvalue { double, double } undef, double %[[#E]], 0
// LLVM-FULL-NEXT: %[[#RES:]] = insertvalue { double, double } %[[#G]], double %[[#F]], 1
// LLVM-FULL-NEXT: %[[#H:]] = fcmp une double %[[#E]], %[[#E]]
// LLVM-FULL-NEXT: %[[#COND:]] = zext i1 %[[#H]] to i8
// LLVM-FULL-NEXT: %[[#I:]] = fcmp une double %[[#F]], %[[#F]]
// LLVM-FULL-NEXT: %[[#COND2:]] = zext i1 %[[#I]] to i8
// LLVM-FULL-NEXT: %[[#J:]] = and i8 %[[#COND]], %[[#COND2]]
// LLVM-FULL-NEXT: %[[#COND3:]] = trunc i8 %[[#J]] to i1
// LLVM-FULL-NEXT: %[[#COND:]] = fcmp une double %[[#E]], %[[#E]]
// LLVM-FULL-NEXT: %[[#COND2:]] = fcmp une double %[[#F]], %[[#F]]
// LLVM-FULL-NEXT: %[[#COND3:]] = and i1 %[[#COND]], %[[#COND2]]
// LLVM-FULL: {{.+}}:
// LLVM-FULL-NEXT: %{{.+}} = call { double, double } @__muldc3(double %[[#LHSR]], double %[[#LHSI]], double %[[#RHSR]], double %[[#RHSI]])
// LLVM-FULL-NEXT: br label %{{.+}}
Expand Down
8 changes: 2 additions & 6 deletions clang/test/CIR/CodeGen/complex-cast.c
Original file line number Diff line number Diff line change
Expand Up @@ -179,10 +179,8 @@ void complex_to_bool() {
// LLVM: %[[#REAL:]] = extractvalue { double, double } %{{.+}}, 0
// LLVM-NEXT: %[[#IMAG:]] = extractvalue { double, double } %{{.+}}, 1
// LLVM-NEXT: %[[#RB:]] = fcmp une double %[[#REAL]], 0.000000e+00
// LLVM-NEXT: %[[#RB2:]] = zext i1 %[[#RB]] to i8
// LLVM-NEXT: %[[#IB:]] = fcmp une double %[[#IMAG]], 0.000000e+00
// LLVM-NEXT: %[[#IB2:]] = zext i1 %[[#IB]] to i8
// LLVM-NEXT: %{{.+}} = or i8 %[[#RB2]], %[[#IB2]]
// LLVM-NEXT: %{{.+}} = or i1 %[[#RB]], %[[#IB]]

// CIR-BEFORE: %{{.+}} = cir.cast(int_complex_to_bool, %{{.+}} : !cir.complex<!s32i>), !cir.bool

Expand All @@ -196,10 +194,8 @@ void complex_to_bool() {
// LLVM: %[[#REAL:]] = extractvalue { i32, i32 } %{{.+}}, 0
// LLVM-NEXT: %[[#IMAG:]] = extractvalue { i32, i32 } %{{.+}}, 1
// LLVM-NEXT: %[[#RB:]] = icmp ne i32 %[[#REAL]], 0
// LLVM-NEXT: %[[#RB2:]] = zext i1 %[[#RB]] to i8
// LLVM-NEXT: %[[#IB:]] = icmp ne i32 %[[#IMAG]], 0
// LLVM-NEXT: %[[#IB2:]] = zext i1 %[[#IB]] to i8
// LLVM-NEXT: %{{.+}} = or i8 %[[#RB2]], %[[#IB2]]
// LLVM-NEXT: %{{.+}} = or i1 %[[#RB]], %[[#IB]]

// CHECK: }

Expand Down
2 changes: 1 addition & 1 deletion clang/test/CIR/CodeGen/new-null.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -66,7 +66,7 @@ namespace test15 {
// LLVM: %[[VAL_0:.*]] = alloca ptr, i64 1, align 8
// LLVM: store ptr %[[VAL_1:.*]], ptr %[[VAL_0]], align 8
// LLVM: %[[VAL_2:.*]] = load ptr, ptr %[[VAL_0]], align 8
// LLVM: %[[VAL_3:.*]] = call ptr @_ZnwmPvb(i64 1, ptr %[[VAL_2]], i8 1)
// LLVM: %[[VAL_3:.*]] = call ptr @_ZnwmPvb(i64 1, ptr %[[VAL_2]], i1 true)
// LLVM: %[[VAL_4:.*]] = icmp ne ptr %[[VAL_3]], null
// LLVM: br i1 %[[VAL_4]], label %[[VAL_5:.*]], label %[[VAL_6:.*]],
// LLVM: [[VAL_5]]: ; preds = %[[VAL_7:.*]]
Expand Down
4 changes: 2 additions & 2 deletions clang/test/CIR/CodeGen/static.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -77,11 +77,11 @@ static Init __ioinit2(false);
// LLVM: @_ZL9__ioinit2 = internal global %class.Init zeroinitializer
// LLVM: @llvm.global_ctors = appending constant [2 x { i32, ptr, ptr }] [{ i32, ptr, ptr } { i32 65536, ptr @__cxx_global_var_init, ptr null }, { i32, ptr, ptr } { i32 65536, ptr @__cxx_global_var_init.1, ptr null }]
// LLVM: define internal void @__cxx_global_var_init()
// LLVM-NEXT: call void @_ZN4InitC1Eb(ptr @_ZL8__ioinit, i8 1)
// LLVM-NEXT: call void @_ZN4InitC1Eb(ptr @_ZL8__ioinit, i1 true)
// LLVM-NEXT: call void @__cxa_atexit(ptr @_ZN4InitD1Ev, ptr @_ZL8__ioinit, ptr @__dso_handle)
// LLVM-NEXT: ret void
// LLVM: define internal void @__cxx_global_var_init.1()
// LLVM-NEXT: call void @_ZN4InitC1Eb(ptr @_ZL9__ioinit2, i8 0)
// LLVM-NEXT: call void @_ZN4InitC1Eb(ptr @_ZL9__ioinit2, i1 false)
// LLVM-NEXT: call void @__cxa_atexit(ptr @_ZN4InitD1Ev, ptr @_ZL9__ioinit2, ptr @__dso_handle)
// LLVM-NEXT: ret void
// LLVM: define void @_GLOBAL__sub_I_static.cpp()
Expand Down
6 changes: 3 additions & 3 deletions clang/test/CIR/IR/invalid.cir
Original file line number Diff line number Diff line change
Expand Up @@ -1106,8 +1106,8 @@ module {
!s8i = !cir.int<s, 8>
cir.func @no_reference_global() {
// expected-error @below {{'cir.get_global' op 'str' does not reference a valid cir.global or cir.func}}
%0 = cir.get_global @str : !cir.ptr<!s8i>
cir.return
%0 = cir.get_global @str : !cir.ptr<!s8i>
cir.return
}

// -----
Expand Down Expand Up @@ -1424,7 +1424,7 @@ cir.global external @f = #cir.fp<0x7FC0000007FC0000007FC000000> : !cir.long_doub

// -----

// Long double with `double` semnatics should have a value that fits in a double.
// Long double with `double` semantics should have a value that fits in a double.

// CHECK: cir.global external @f = #cir.fp<0x7FC000007FC000000000> : !cir.long_double<!cir.f80>
cir.global external @f = #cir.fp<0x7FC000007FC000000000> : !cir.long_double<!cir.f80>
Expand Down
20 changes: 8 additions & 12 deletions clang/test/CIR/Lowering/binop-overflow.cir
Original file line number Diff line number Diff line change
Expand Up @@ -11,22 +11,20 @@ module {
cir.return %overflow : !cir.bool
}

// MLIR: llvm.func @test_add_u32_u32_u32(%[[LHS:.+]]: i32, %[[RHS:.+]]: i32, %[[RES_PTR:.+]]: !llvm.ptr) -> i8
// MLIR: llvm.func @test_add_u32_u32_u32(%[[LHS:.+]]: i32, %[[RHS:.+]]: i32, %[[RES_PTR:.+]]: !llvm.ptr) -> i1
// MLIR-NEXT: %[[#INTRIN_RET:]] = llvm.call_intrinsic "llvm.uadd.with.overflow.i32"(%[[LHS]], %[[RHS]]) : (i32, i32) -> !llvm.struct<(i32, i1)>
// MLIR-NEXT: %[[#RES:]] = llvm.extractvalue %[[#INTRIN_RET]][0] : !llvm.struct<(i32, i1)>
// MLIR-NEXT: %[[#OVFL:]] = llvm.extractvalue %[[#INTRIN_RET]][1] : !llvm.struct<(i32, i1)>
// MLIR-NEXT: %[[#OVFL_EXT:]] = llvm.zext %[[#OVFL]] : i1 to i8
// MLIR-NEXT: llvm.store %[[#RES]], %[[RES_PTR]] {{.*}} : i32, !llvm.ptr
// MLIR-NEXT: llvm.return %[[#OVFL_EXT]] : i8
// MLIR-NEXT: llvm.return %[[#OVFL]] : i1
// MLIR-NEXT: }

// LLVM: define i8 @test_add_u32_u32_u32(i32 %[[#LHS:]], i32 %[[#RHS:]], ptr %[[#RES_PTR:]])
// LLVM: define i1 @test_add_u32_u32_u32(i32 %[[#LHS:]], i32 %[[#RHS:]], ptr %[[#RES_PTR:]])
// LLVM-NEXT: %[[#INTRIN_RET:]] = call { i32, i1 } @llvm.uadd.with.overflow.i32(i32 %[[#LHS]], i32 %[[#RHS]])
// LLVM-NEXT: %[[#RES:]] = extractvalue { i32, i1 } %[[#INTRIN_RET]], 0
// LLVM-NEXT: %[[#OVFL:]] = extractvalue { i32, i1 } %[[#INTRIN_RET]], 1
// LLVM-NEXT: %[[#OVFL_EXT:]] = zext i1 %[[#OVFL]] to i8
// LLVM-NEXT: store i32 %[[#RES]], ptr %[[#RES_PTR]], align 4
// LLVM-NEXT: ret i8 %[[#OVFL_EXT]]
// LLVM-NEXT: ret i1 %[[#OVFL]]
// LLVM-NEXT: }

cir.func @test_add_u32_u32_i32(%lhs: !u32i, %rhs: !u32i, %res: !cir.ptr<!s32i>) -> !cir.bool {
Expand All @@ -35,7 +33,7 @@ module {
cir.return %overflow : !cir.bool
}

// MLIR: llvm.func @test_add_u32_u32_i32(%[[LHS:.+]]: i32, %[[RHS:.+]]: i32, %[[RES_PTR:.+]]: !llvm.ptr) -> i8
// MLIR: llvm.func @test_add_u32_u32_i32(%[[LHS:.+]]: i32, %[[RHS:.+]]: i32, %[[RES_PTR:.+]]: !llvm.ptr) -> i1
// MLIR-NEXT: %[[#LHS_EXT:]] = llvm.zext %[[LHS]] : i32 to i33
// MLIR-NEXT: %[[#RHS_EXT:]] = llvm.zext %[[RHS]] : i32 to i33
// MLIR-NEXT: %[[#INTRIN_RET:]] = llvm.call_intrinsic "llvm.sadd.with.overflow.i33"(%[[#LHS_EXT]], %[[#RHS_EXT]]) : (i33, i33) -> !llvm.struct<(i33, i1)>
Expand All @@ -45,12 +43,11 @@ module {
// MLIR-NEXT: %[[#RES_EXT_2:]] = llvm.sext %[[#RES]] : i32 to i33
// MLIR-NEXT: %[[#TRUNC_OVFL:]] = llvm.icmp "ne" %[[#RES_EXT_2]], %[[#RES_EXT]] : i33
// MLIR-NEXT: %[[#OVFL:]] = llvm.or %[[#ARITH_OVFL]], %[[#TRUNC_OVFL]] : i1
// MLIR-NEXT: %[[#OVFL_EXT:]] = llvm.zext %[[#OVFL]] : i1 to i8
// MLIR-NEXT: llvm.store %[[#RES]], %[[RES_PTR]] {{.*}} : i32, !llvm.ptr
// MLIR-NEXT: llvm.return %[[#OVFL_EXT]] : i8
// MLIR-NEXT: llvm.return %[[#OVFL]] : i1
// MLIR-NEXT: }

// LLVM: define i8 @test_add_u32_u32_i32(i32 %[[#LHS:]], i32 %[[#RHS:]], ptr %[[#RES_PTR:]])
// LLVM: define i1 @test_add_u32_u32_i32(i32 %[[#LHS:]], i32 %[[#RHS:]], ptr %[[#RES_PTR:]])
// LLVM-NEXT: %[[#LHS_EXT:]] = zext i32 %[[#LHS]] to i33
// LLVM-NEXT: %[[#RHS_EXT:]] = zext i32 %[[#RHS]] to i33
// LLVM-NEXT: %[[#INTRIN_RET:]] = call { i33, i1 } @llvm.sadd.with.overflow.i33(i33 %[[#LHS_EXT]], i33 %[[#RHS_EXT]])
Expand All @@ -60,8 +57,7 @@ module {
// LLVM-NEXT: %[[#RES_EXT_2:]] = sext i32 %[[#RES]] to i33
// LLVM-NEXT: %[[#TRUNC_OVFL:]] = icmp ne i33 %[[#RES_EXT_2]], %[[#RES_EXT]]
// LLVM-NEXT: %[[#OVFL:]] = or i1 %[[#ARITH_OVFL]], %[[#TRUNC_OVFL]]
// LLVM-NEXT: %[[#OVFL_EXT:]] = zext i1 %[[#OVFL]] to i8
// LLVM-NEXT: store i32 %[[#RES]], ptr %[[#RES_PTR]], align 4
// LLVM-NEXT: ret i8 %[[#OVFL_EXT]]
// LLVM-NEXT: ret i1 %[[#OVFL]]
// LLVM-NEXT: }
}
9 changes: 5 additions & 4 deletions clang/test/CIR/Lowering/bool.cir
Original file line number Diff line number Diff line change
Expand Up @@ -16,10 +16,11 @@ module {
cir.return
}
// MLIR: llvm.func @foo()
// MLIR-DAG: = llvm.mlir.constant(1 : i8) : i8
// MLIR-DAG: [[Value:%[a-z0-9]+]] = llvm.mlir.constant(1 : index) : i64
// MLIR-DAG: = llvm.alloca [[Value]] x i8 {alignment = 1 : i64} : (i64) -> !llvm.ptr
// MLIR-DAG: llvm.store %0, %2 {{.*}} : i8, !llvm.ptr
// MLIR-DAG: %[[TRUE:.*]] = llvm.mlir.constant(true) : i1
// MLIR-DAG: %[[VALUE:.*]] = llvm.mlir.constant(1 : index) : i64
// MLIR-DAG: %[[ADDR:.*]] = llvm.alloca %[[VALUE]] x i8 {alignment = 1 : i64} : (i64) -> !llvm.ptr
// MLIR-DAG: %[[TRUE_EXT:.*]] = llvm.zext %[[TRUE]] : i1 to i8
// MLIR-DAG: llvm.store %[[TRUE_EXT]], %[[ADDR]] {{.*}} : i8, !llvm.ptr
// MLIR-NEXT: llvm.return

// LLVM: define void @foo()
Expand Down
22 changes: 10 additions & 12 deletions clang/test/CIR/Lowering/branch.cir
Original file line number Diff line number Diff line change
Expand Up @@ -13,25 +13,23 @@ cir.func @foo(%arg0: !cir.bool) -> !s32i {
}

// MLIR: module {
// MLIR-NEXT: llvm.func @foo(%arg0: i8) -> i32
// MLIR-NEXT: %0 = llvm.trunc %arg0 : i8 to i1
// MLIR-NEXT: llvm.cond_br %0, ^bb1, ^bb2
// MLIR-NEXT: llvm.func @foo(%arg0: i1) -> i32
// MLIR-NEXT: llvm.cond_br %arg0, ^bb1, ^bb2
// MLIR-NEXT: ^bb1: // pred: ^bb0
// MLIR-NEXT: %1 = llvm.mlir.constant(1 : i32) : i32
// MLIR-NEXT: llvm.return %1 : i32
// MLIR-NEXT: %0 = llvm.mlir.constant(1 : i32) : i32
// MLIR-NEXT: llvm.return %0 : i32
// MLIR-NEXT: ^bb2: // pred: ^bb0
// MLIR-NEXT: %2 = llvm.mlir.constant(0 : i32) : i32
// MLIR-NEXT: llvm.return %2 : i32
// MLIR-NEXT: %1 = llvm.mlir.constant(0 : i32) : i32
// MLIR-NEXT: llvm.return %1 : i32
// MLIR-NEXT: }
// MLIR-NEXT: }

// LLVM: define i32 @foo(i8 %0)
// LLVM-NEXT: %2 = trunc i8 %0 to i1
// LLVM-NEXT: br i1 %2, label %3, label %4
// LLVM: define i32 @foo(i1 %0)
// LLVM-NEXT: br i1 %0, label %2, label %3
// LLVM-EMPTY:
// LLVM-NEXT: 3: ; preds = %1
// LLVM-NEXT: 2: ; preds = %1
// LLVM-NEXT: ret i32 1
// LLVM-EMPTY:
// LLVM-NEXT: 4: ; preds = %1
// LLVM-NEXT: 3: ; preds = %1
// LLVM-NEXT: ret i32 0
// LLVM-NEXT: }
25 changes: 12 additions & 13 deletions clang/test/CIR/Lowering/brcond.cir
Original file line number Diff line number Diff line change
Expand Up @@ -4,40 +4,39 @@
!s32i = !cir.int<s, 32>
#fn_attr = #cir<extra({inline = #cir.inline<no>, nothrow = #cir.nothrow, optnone = #cir.optnone})>
module { cir.func no_proto @test() -> !cir.bool extra(#fn_attr) {
%0 = cir.const #cir.int<0> : !s32i
%1 = cir.cast(int_to_bool, %0 : !s32i), !cir.bool
cir.br ^bb1
%0 = cir.const #cir.int<0> : !s32i
%1 = cir.cast(int_to_bool, %0 : !s32i), !cir.bool
cir.br ^bb1
^bb1:
cir.brcond %1 ^bb2, ^bb3
cir.brcond %1 ^bb2, ^bb3
^bb2:
cir.return %1 : !cir.bool
cir.return %1 : !cir.bool
^bb3:
cir.br ^bb4
cir.br ^bb4
^bb4:
cir.return %1 : !cir.bool
}
cir.return %1 : !cir.bool
}
}

// MLIR: {{.*}} = llvm.mlir.constant(0 : i32) : i32
// MLIR-NEXT: {{.*}} = llvm.mlir.constant(0 : i32) : i32
// MLIR-NEXT: {{.*}} = llvm.icmp "ne" {{.*}}, {{.*}} : i32
// MLIR-NEXT: {{.*}} = llvm.zext {{.*}} : i1 to i8
// MLIR-NEXT: llvm.br ^bb1
// MLIR-NEXT: ^bb1:
// MLIR-NEXT: llvm.cond_br {{.*}}, ^bb2, ^bb3
// MLIR-NEXT: ^bb2:
// MLIR-NEXT: llvm.return {{.*}} : i8
// MLIR-NEXT: llvm.return {{.*}} : i1
// MLIR-NEXT: ^bb3:
// MLIR-NEXT: llvm.br ^bb4
// MLIR-NEXT: ^bb4:
// MLIR-NEXT: llvm.return {{.*}} : i8
// MLIR-NEXT: llvm.return {{.*}} : i1

// LLVM: br label {{.*}}
// LLVM: 1:
// LLVM: br i1 false, label {{.*}}, label {{.*}}
// LLVM: 2:
// LLVM: ret i8 0
// LLVM: ret i1 false
// LLVM: 3:
// LLVM: br label {{.*}}
// LLVM: 4:
// LLVM: ret i8 0
// LLVM: ret i1 false
Loading

0 comments on commit 8fe8f86

Please sign in to comment.