[llvm] [InstCombine] Optimize unneeded float to int cast when icmp (PR #155501)
Artem Trokhymchuk via llvm-commits
llvm-commits at lists.llvm.org
Tue Sep 2 09:51:45 PDT 2025
================
@@ -6054,3 +6054,255 @@ define i1 @icmp_samesign_logical_or(i32 %In) {
%V = select i1 %c1, i1 true, i1 %c2
ret i1 %V
}
+
+; https://alive2.llvm.org/ce/z/XtQS6H
+define i1 @float_to_int_comparing_constant1_positive1(float %arg0) {
+; CHECK-LABEL: define i1 @float_to_int_comparing_constant1_positive1(
+; CHECK-SAME: float [[ARG0:%.*]]) {
+; CHECK-NEXT: [[V1:%.*]] = fcmp ogt float [[ARG0]], -1.000000e+00
+; CHECK-NEXT: ret i1 [[V1]]
+;
+ %v0 = fptosi float %arg0 to i32
+ %v1 = icmp sgt i32 %v0, -1
+ ret i1 %v1
+}
+
+; https://alive2.llvm.org/ce/z/ZycBgc
+define i1 @float_to_int_comparing_constant1_positive2(float %arg0) {
+; CHECK-LABEL: define i1 @float_to_int_comparing_constant1_positive2(
+; CHECK-SAME: float [[ARG0:%.*]]) {
+; CHECK-NEXT: [[V1:%.*]] = fcmp oge float [[ARG0]], 2.000000e+00
+; CHECK-NEXT: ret i1 [[V1]]
+;
+ %v0 = fptosi float %arg0 to i32
+ %v1 = icmp sgt i32 %v0, 1
+ ret i1 %v1
+}
+
+; https://alive2.llvm.org/ce/z/5VRWXi
+define i1 @float_to_int_comparing_constant2_positive1(float %arg0) {
+; CHECK-LABEL: define i1 @float_to_int_comparing_constant2_positive1(
+; CHECK-SAME: float [[ARG0:%.*]]) {
+; CHECK-NEXT: [[V1:%.*]] = fcmp ole float [[ARG0]], 1.000000e+00
+; CHECK-NEXT: ret i1 [[V1]]
+;
+ %v0 = fptosi float %arg0 to i32
+ %v1 = icmp slt i32 %v0, 1
+ ret i1 %v1
+}
+
+; https://alive2.llvm.org/ce/z/9bejWa
+define i1 @float_to_int_comparing_constant2_positive2(float %arg0) {
+; CHECK-LABEL: define i1 @float_to_int_comparing_constant2_positive2(
+; CHECK-SAME: float [[ARG0:%.*]]) {
+; CHECK-NEXT: [[V1:%.*]] = fcmp olt float [[ARG0]], -1.000000e+00
+; CHECK-NEXT: ret i1 [[V1]]
+;
+ %v0 = fptosi float %arg0 to i32
+ %v1 = icmp slt i32 %v0, 0
+ ret i1 %v1
+}
+
+define i1 @double_to_int_comparing_constant1_positive1(double %arg0) {
+; CHECK-LABEL: define i1 @double_to_int_comparing_constant1_positive1(
+; CHECK-SAME: double [[ARG0:%.*]]) {
+; CHECK-NEXT: [[V1:%.*]] = fcmp ogt double [[ARG0]], -1.000000e+00
+; CHECK-NEXT: ret i1 [[V1]]
+;
+ %v0 = fptosi double %arg0 to i32
+ %v1 = icmp sgt i32 %v0, -1
+ ret i1 %v1
+}
+
+define i1 @double_to_int_comparing_constant1_positive2(double %arg0) {
+; CHECK-LABEL: define i1 @double_to_int_comparing_constant1_positive2(
+; CHECK-SAME: double [[ARG0:%.*]]) {
+; CHECK-NEXT: [[V1:%.*]] = fcmp oge double [[ARG0]], 2.000000e+00
+; CHECK-NEXT: ret i1 [[V1]]
+;
+ %v0 = fptosi double %arg0 to i32
+ %v1 = icmp sgt i32 %v0, 1
+ ret i1 %v1
+}
+
+define i1 @fp16_to_int_comparing_constant2_positive1(i16 %arg0) {
+; CHECK-LABEL: define i1 @fp16_to_int_comparing_constant2_positive1(
+; CHECK-SAME: i16 [[ARG0:%.*]]) {
+; CHECK-NEXT: [[V0:%.*]] = call float @llvm.convert.from.fp16.f32(i16 [[ARG0]])
+; CHECK-NEXT: [[V2:%.*]] = fcmp ole float [[V0]], 1.000000e+00
+; CHECK-NEXT: ret i1 [[V2]]
+;
+ %v0 = call float @llvm.convert.from.fp16(i16 %arg0)
+ %v1 = fptosi float %v0 to i32
+ %v2 = icmp slt i32 %v1, 1
+ ret i1 %v2
+}
+
+define i1 @fp16_to_int_comparing_constant2_positive2(i16 %arg0) {
+; CHECK-LABEL: define i1 @fp16_to_int_comparing_constant2_positive2(
+; CHECK-SAME: i16 [[ARG0:%.*]]) {
+; CHECK-NEXT: [[V0:%.*]] = call float @llvm.convert.from.fp16.f32(i16 [[ARG0]])
+; CHECK-NEXT: [[V2:%.*]] = fcmp olt float [[V0]], -1.000000e+00
+; CHECK-NEXT: ret i1 [[V2]]
+;
+ %v0 = call float @llvm.convert.from.fp16(i16 %arg0)
----------------
trokhymchuk wrote:
sorry, looks like I was confused with the [IR reference](https://llvm.org/docs/LangRef.html#llvm-convert-to-fp16-intrinsic) :(
I updated the code to use `half` type and added vector tests forthe half-floats
https://github.com/llvm/llvm-project/pull/155501
More information about the llvm-commits
mailing list