[llvm] [Float2Int] Fix miscompile with floats that can be converted to large values (PR #85996)

Craig Topper via llvm-commits llvm-commits at lists.llvm.org
Wed Mar 20 15:38:32 PDT 2024


================
@@ -349,3 +349,55 @@ bogusBB:                                          ; preds = %bogusBB
   %tobool = fcmp une double %inc, 0.000000e+00
   br label %bogusBB
 }
+
+define i32 @pr79158() {
+; CHECK-LABEL: @pr79158(
+; CHECK-NEXT:  entry:
+; CHECK-NEXT:    [[X_I:%.*]] = alloca i32, align 4
+; CHECK-NEXT:    call void @llvm.lifetime.start.p0(i64 4, ptr nonnull [[X_I]])
+; CHECK-NEXT:    store volatile i32 1, ptr [[X_I]], align 4
+; CHECK-NEXT:    [[X_I_0_X_I_0_X_0_X_0_X_0__I:%.*]] = load volatile i32, ptr [[X_I]], align 4
+; CHECK-NEXT:    [[CMP_I:%.*]] = icmp sgt i32 [[X_I_0_X_I_0_X_0_X_0_X_0__I]], 0
+; CHECK-NEXT:    [[TMP0:%.*]] = zext i1 [[CMP_I]] to i32
+; CHECK-NEXT:    [[MUL_I1:%.*]] = mul i32 [[TMP0]], -1
+; CHECK-NEXT:    call void @llvm.lifetime.end.p0(i64 4, ptr nonnull [[X_I]])
+; CHECK-NEXT:    ret i32 0
+;
+entry:
+  %x.i = alloca i32, align 4
+  call void @llvm.lifetime.start.p0(i64 4, ptr nonnull %x.i)
+  store volatile i32 1, ptr %x.i, align 4
+  %x.i.0.x.i.0.x.0.x.0.x.0..i = load volatile i32, ptr %x.i, align 4
+  %cmp.i = icmp sgt i32 %x.i.0.x.i.0.x.0.x.0.x.0..i, 0
+  %conv.i = uitofp i1 %cmp.i to double
----------------
topperc wrote:

With that change, the minimum bitwidth is calculate as 35 so we pick i64 as the type. Which produces this

```
Args: ./bin/opt test.ll -passes=float2int -S -o - -debug 
F2I: Looking at function pr79158
F2I:   %conv1.i = fptoui double %mul.i to i32:empty-set
F2I:   %mul.i = fmul double %conv.i, 0x41EFFFFFFFE00000:empty-set
F2I:   %conv.i = uitofp i1 %cmp.i to double:[0,2)
F2I:   %mul.i = fmul double %conv.i, 0x41EFFFFFFFE00000:[0,4294967296)
F2I:   %conv1.i = fptoui double %mul.i to i32:[0,4294967296)
F2I: MinBitwidth=35, R: [0,4294967296)
; ModuleID = 'test.ll'
source_filename = "test.ll"

define i32 @pr79158() {
entry:
  %x.i = alloca i32, align 4
  call void @llvm.lifetime.start.p0(i64 4, ptr nonnull %x.i)
  store volatile i32 1, ptr %x.i, align 4
  %x.i.0.x.i.0.x.0.x.0.x.0..i = load volatile i32, ptr %x.i, align 4
  %cmp.i = icmp sgt i32 %x.i.0.x.i.0.x.0.x.0.x.0..i, 0
  %0 = zext i1 %cmp.i to i64
  %mul.i1 = mul i64 %0, 4294967295
  %1 = trunc i64 %mul.i1 to i32
  call void @llvm.lifetime.end.p0(i64 4, ptr nonnull %x.i)
  ret i32 0
}
```

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


More information about the llvm-commits mailing list