Skip to content

!cir.bool lowering differs from original clang CodeGen. #480

Open
@bcardosolopes

Description

@bcardosolopes

I believe the root problem here is that CIR lowers !cir.bool in a different way than the original clang CodeGen.

In the original CodeGen, bool glvalues are lowered to LLVM i8 values, and bool prvalues are lowered to LLVM i1 values, as illustrated in the following example:

bool test(int x) {
  bool ret = x > 42;
  return ret;
}
; @test returns a bool prvalue so its return type is `i1`
define dso_local noundef zeroext i1 @test()() {
entry:
  %ret = alloca i8, align 1  ; %ret is a bool glvalue so its type is `i8`
  tail call void @llvm.dbg.declare(metadata ptr %ret, metadata !16, metadata !DIExpression())
  store i8 1, ptr %ret, align 1
  %0 = load i8, ptr %ret, align 1
  %tobool = trunc i8 %0 to i1
  ret i1 %tobool
}

However, in CIRGen, all !cir.bool values are lowered to LLVM i8 values. The example above would be lowered to LLVMIR through CIR as:

; Note that the return value of @test is `i8` rather than `i1`
define i8 @test()() #0 !dbg !3 {
  %1 = alloca i8, i64 1, align 1, !dbg !6
  %2 = alloca i8, i64 1, align 1, !dbg !7
  store i8 1, ptr %2, align 1, !dbg !7
  %3 = load i8, ptr %2, align 1, !dbg !8
  store i8 %3, ptr %1, align 1, !dbg !9
  %4 = load i8, ptr %1, align 1, !dbg !9
  ret i8 %4, !dbg !9
}

This divergence leads to the redundancy illustrated in the PR description. The result of a cir.cmp operation is currently expected to be lowered to an i8 value although it's a prvalue. After emitting an llvm.icmp operation, you have to insert an llvm.zext operation to extend the i1 to i8. Thus the redundancy.

Originally posted by @Lancern in #478 (comment)

Metadata

Metadata

Assignees

Labels

IR differenceA difference in ClangIR-generated LLVM IR that could complicate reusing original CodeGen tests

Type

No type

Projects

No projects

Milestone

No milestone

Relationships

None yet

Development

No branches or pull requests

Issue actions