[llvm] [InstCombine] Optimize unneeded float to int cast when icmp (PR #155501)

Nikita Popov via llvm-commits llvm-commits at lists.llvm.org
Sun Aug 31 14:41:49 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)
----------------
nikic wrote:

Do not use these intrinsics, this should just be `fptosi half %v0 to i32`.

https://github.com/llvm/llvm-project/pull/155501


More information about the llvm-commits mailing list