Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

[CIR][CIRGen] Support __builtin_isinf_sign #1142

Merged
merged 1 commit into from
Feb 11, 2025

Conversation

PikachuHyA
Copy link
Collaborator

@PikachuHyA PikachuHyA commented Nov 19, 2024

No description provided.

@bcardosolopes
Copy link
Member

Firstly, it uses IsFPClass to determine if a value is infinite, whereas the original CGBuiltin implementation used direct comparisons with infinity constants.

I'm assuming IsFPClass will lead to the same final LLVM? If so LGTM

@orbiri
Copy link
Collaborator

orbiri commented Nov 28, 2024

Can you explain why can’t signbit return a Boolean? What is its other usages? (I don’t have full context so that would help me to understand better this patch 😇)

Looking around, it seems even that C++ is exposing this API with a Boolean. https://en.cppreference.com/w/cpp/numeric/math/signbit

Perhaps it is time to convert this op to Boolean as well? :)

@PikachuHyA
Copy link
Collaborator Author

Can you explain why can’t signbit return a Boolean? What is its other usages?

please see the error in #1187

@PikachuHyA
Copy link
Collaborator Author

Firstly, it uses IsFPClass to determine if a value is infinite, whereas the original CGBuiltin implementation used direct comparisons with infinity constants.

I'm assuming IsFPClass will lead to the same final LLVM?

If you are inquiring whether their semantics are equivalent, the answer is yes.

@orbiri
Copy link
Collaborator

orbiri commented Nov 29, 2024

Can you explain why can’t signbit return a Boolean? What is its other usages?

please see the error in #1187

This error indicates that there’s either an error in your codegen or in the lowering code. In either way, I would not recommend increasing the tech debt with this change.

I would recommend using the -debug flag of cir-opt and inspect the lowering step by step!

@bcardosolopes
Copy link
Member

In either way, I would not recommend increasing the tech debt with this change.

Thanks @orbiri, way to go. Reviewed and landed #1187, @PikachuHyA let me know when this PR is ready again

@PikachuHyA
Copy link
Collaborator Author

@orbiri After updating SignBitOp to return bool, this patch still leads to two unnecessary type conversions: from i1 to i8 and then back to i1. I think it is related to #480 , please feel free to share your thoughts on this.

I left a comment in clang/lib/CIR/CodeGen/CIRGenBuiltin.cpp:

// FIXME: CIR currently converts cir::BoolType to i8 type unconditionally.
// See https://github.com/llvm/clangir/issues/480
// Fixing this issue will eliminate redundant cast instructions
// for IsInf and IsNeg: i1 -> i8 -> i1

The LLVM IR generated by running:

./bin/clang ../clang/test/CIR/CodeGen/builtin-isinf-sign.c -Xclang -emit-llvm -o t.ll -c -fclangir

is as follows:

define dso_local i32 @test_float_isinf_sign(float %0) #0 {
  %2 = alloca float, i64 1, align 4
  %3 = alloca i32, i64 1, align 4
  store float %0, ptr %2, align 4
  %4 = load float, ptr %2, align 4
  %5 = call float @llvm.fabs.f32(float %4)
  %6 = call i1 @llvm.is.fpclass.f32(float %5, i32 516)
  %7 = zext i1 %6 to i8
  %8 = bitcast float %4 to i32
  %9 = icmp slt i32 %8, 0
  %10 = zext i1 %9 to i8
  %11 = trunc i8 %10 to i1
  %12 = select i1 %11, i32 -1, i32 1
  %13 = trunc i8 %7 to i1
  %14 = select i1 %13, i32 %12, i32 0
  store i32 %14, ptr %3, align 4
  %15 = load i32, ptr %3, align 4
  ret i32 %15
}

As shown, there are unnecessary conversions: %6 -> %7 -> %13 and %9 -> %10 -> %11.

Additionally, the LLVM IR generated by running:

./bin/clang ../clang/test/CIR/CodeGen/builtin-isinf-sign.c -Xclang -emit-llvm -o t.orig.ll -c

is:

define dso_local i32 @test_float_isinf_sign(float noundef %x) #0 {
entry:
  %x.addr = alloca float, align 4
  store float %x, ptr %x.addr, align 4
  %0 = load float, ptr %x.addr, align 4
  %1 = call float @llvm.fabs.f32(float %0) #2
  %isinf = fcmp oeq float %1, 0x7FF0000000000000
  %2 = bitcast float %0 to i32
  %3 = icmp slt i32 %2, 0
  %4 = select i1 %3, i32 -1, i32 1
  %5 = select i1 %isinf, i32 %4, i32 0
  ret i32 %5
}

@PikachuHyA
Copy link
Collaborator Author

@orbiri ping

@orbiri
Copy link
Collaborator

orbiri commented Dec 21, 2024

It will be sorted out very soon! Don’t optimize on the llvm output but rather on the CIR output :)

@PikachuHyA
Copy link
Collaborator Author

After the landing of #1158, the patch is now ready.
Thanks to @orbiri for your contributions!

@bcardosolopes bcardosolopes merged commit e1a9263 into llvm:main Feb 11, 2025
6 checks passed
@PikachuHyA PikachuHyA deleted the support_isinf_sign branch February 12, 2025 01:38
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

3 participants