[llvm] [ValueTracking] Add missing operand checks in `computeKnownFPClassFromCond` (PR #119579)
Yingwei Zheng via llvm-commits
llvm-commits at lists.llvm.org
Wed Dec 11 08:19:36 PST 2024
https://github.com/dtcxzyw created https://github.com/llvm/llvm-project/pull/119579
After https://github.com/llvm/llvm-project/pull/118257, we may call `computeKnownFPClassFromCond` with unrelated conditions. Then miscompilations may occur due to a lack of operand checks.
This bug was introduced by https://github.com/llvm/llvm-project/commit/d2404ea6ced5fce9442260bde08a02d607fdd50d and https://github.com/llvm/llvm-project/pull/80740. However, the miscompilation never occurs since we only add related conditions to `DomConditionCache/AssumptionCache`.
Fix the miscompilation reported in https://github.com/llvm/llvm-project/pull/118257#issuecomment-2536182166.
>From 64fcb7fdc89855aa5893669fb7e6581f11e70094 Mon Sep 17 00:00:00 2001
From: Yingwei Zheng <dtcxzyw2333 at gmail.com>
Date: Wed, 11 Dec 2024 23:59:59 +0800
Subject: [PATCH 1/2] [InstCombine] Add pre-commit tests. NFC.
---
.../InstCombine/fpclass-from-dom-cond.ll | 58 +++++++++++++++++++
1 file changed, 58 insertions(+)
diff --git a/llvm/test/Transforms/InstCombine/fpclass-from-dom-cond.ll b/llvm/test/Transforms/InstCombine/fpclass-from-dom-cond.ll
index 141b44cbbb7a1f..ea26bfbc3eb08e 100644
--- a/llvm/test/Transforms/InstCombine/fpclass-from-dom-cond.ll
+++ b/llvm/test/Transforms/InstCombine/fpclass-from-dom-cond.ll
@@ -456,3 +456,61 @@ if.end:
%ret = call <2 x float> @llvm.fabs.v2f32(<2 x float> %value)
ret <2 x float> %ret
}
+
+define i1 @pr118257(half %v0, half %v1) {
+; CHECK-LABEL: define i1 @pr118257(
+; CHECK-SAME: half [[V0:%.*]], half [[V1:%.*]]) {
+; CHECK-NEXT: entry:
+; CHECK-NEXT: [[CMP1:%.*]] = fcmp une half [[V1]], 0xH0000
+; CHECK-NEXT: [[CAST0:%.*]] = bitcast half [[V0]] to i16
+; CHECK-NEXT: [[CMP2:%.*]] = icmp slt i16 [[CAST0]], 0
+; CHECK-NEXT: [[OR_COND:%.*]] = or i1 [[CMP1]], [[CMP2]]
+; CHECK-NEXT: br i1 [[OR_COND]], label [[IF_END:%.*]], label [[IF_ELSE:%.*]]
+; CHECK: if.else:
+; CHECK-NEXT: ret i1 false
+; CHECK: if.end:
+; CHECK-NEXT: ret i1 false
+;
+entry:
+ %cmp1 = fcmp une half %v1, 0.000000e+00
+ %cast0 = bitcast half %v0 to i16
+ %cmp2 = icmp slt i16 %cast0, 0
+ %or.cond = or i1 %cmp1, %cmp2
+ br i1 %or.cond, label %if.end, label %if.else
+
+if.else:
+ %cast1 = bitcast half %v1 to i16
+ %cmp3 = icmp slt i16 %cast1, 0
+ ret i1 %cmp3
+
+if.end:
+ ret i1 false
+}
+
+define i1 @pr118257_is_fpclass(half %v0, half %v1) {
+; CHECK-LABEL: define i1 @pr118257_is_fpclass(
+; CHECK-SAME: half [[V0:%.*]], half [[V1:%.*]]) {
+; CHECK-NEXT: entry:
+; CHECK-NEXT: [[CMP1:%.*]] = fcmp une half [[V1]], 0xH0000
+; CHECK-NEXT: [[CMP2:%.*]] = call i1 @llvm.is.fpclass.f16(half [[V0]], i32 35)
+; CHECK-NEXT: [[OR_COND:%.*]] = or i1 [[CMP1]], [[CMP2]]
+; CHECK-NEXT: br i1 [[OR_COND]], label [[IF_END:%.*]], label [[IF_ELSE:%.*]]
+; CHECK: if.else:
+; CHECK-NEXT: ret i1 false
+; CHECK: if.end:
+; CHECK-NEXT: ret i1 false
+;
+entry:
+ %cmp1 = fcmp une half %v1, 0.000000e+00
+ %cmp2 = call i1 @llvm.is.fpclass.half(half %v0, i32 35)
+ %or.cond = or i1 %cmp1, %cmp2
+ br i1 %or.cond, label %if.end, label %if.else
+
+if.else:
+ %cast1 = bitcast half %v1 to i16
+ %cmp3 = icmp slt i16 %cast1, 0
+ ret i1 %cmp3
+
+if.end:
+ ret i1 false
+}
>From 03c0ee0551404f85782cd167262720d2dda6a651 Mon Sep 17 00:00:00 2001
From: Yingwei Zheng <dtcxzyw2333 at gmail.com>
Date: Thu, 12 Dec 2024 00:09:45 +0800
Subject: [PATCH 2/2] [ValueTracking] Add missing op checks in
`computeKnownFPClassFromCond`
---
llvm/lib/Analysis/ValueTracking.cpp | 4 ++--
llvm/test/Transforms/InstCombine/fpclass-from-dom-cond.ll | 8 ++++++--
2 files changed, 8 insertions(+), 4 deletions(-)
diff --git a/llvm/lib/Analysis/ValueTracking.cpp b/llvm/lib/Analysis/ValueTracking.cpp
index f2c6949e535d2a..c148dbce92d1af 100644
--- a/llvm/lib/Analysis/ValueTracking.cpp
+++ b/llvm/lib/Analysis/ValueTracking.cpp
@@ -4906,10 +4906,10 @@ static void computeKnownFPClassFromCond(const Value *V, Value *Cond,
if (CmpVal == V)
KnownFromContext.knownNot(~(CondIsTrue ? MaskIfTrue : MaskIfFalse));
} else if (match(Cond, m_Intrinsic<Intrinsic::is_fpclass>(
- m_Value(LHS), m_ConstantInt(ClassVal)))) {
+ m_Specific(V), m_ConstantInt(ClassVal)))) {
FPClassTest Mask = static_cast<FPClassTest>(ClassVal);
KnownFromContext.knownNot(CondIsTrue ? ~Mask : Mask);
- } else if (match(Cond, m_ICmp(Pred, m_ElementWiseBitCast(m_Value(LHS)),
+ } else if (match(Cond, m_ICmp(Pred, m_ElementWiseBitCast(m_Specific(V)),
m_APInt(RHS)))) {
bool TrueIfSigned;
if (!isSignBitCheck(Pred, *RHS, TrueIfSigned))
diff --git a/llvm/test/Transforms/InstCombine/fpclass-from-dom-cond.ll b/llvm/test/Transforms/InstCombine/fpclass-from-dom-cond.ll
index ea26bfbc3eb08e..78329faf341727 100644
--- a/llvm/test/Transforms/InstCombine/fpclass-from-dom-cond.ll
+++ b/llvm/test/Transforms/InstCombine/fpclass-from-dom-cond.ll
@@ -467,7 +467,9 @@ define i1 @pr118257(half %v0, half %v1) {
; CHECK-NEXT: [[OR_COND:%.*]] = or i1 [[CMP1]], [[CMP2]]
; CHECK-NEXT: br i1 [[OR_COND]], label [[IF_END:%.*]], label [[IF_ELSE:%.*]]
; CHECK: if.else:
-; CHECK-NEXT: ret i1 false
+; CHECK-NEXT: [[CAST1:%.*]] = bitcast half [[V1]] to i16
+; CHECK-NEXT: [[CMP3:%.*]] = icmp slt i16 [[CAST1]], 0
+; CHECK-NEXT: ret i1 [[CMP3]]
; CHECK: if.end:
; CHECK-NEXT: ret i1 false
;
@@ -496,7 +498,9 @@ define i1 @pr118257_is_fpclass(half %v0, half %v1) {
; CHECK-NEXT: [[OR_COND:%.*]] = or i1 [[CMP1]], [[CMP2]]
; CHECK-NEXT: br i1 [[OR_COND]], label [[IF_END:%.*]], label [[IF_ELSE:%.*]]
; CHECK: if.else:
-; CHECK-NEXT: ret i1 false
+; CHECK-NEXT: [[CAST1:%.*]] = bitcast half [[V1]] to i16
+; CHECK-NEXT: [[CMP3:%.*]] = icmp slt i16 [[CAST1]], 0
+; CHECK-NEXT: ret i1 [[CMP3]]
; CHECK: if.end:
; CHECK-NEXT: ret i1 false
;
More information about the llvm-commits
mailing list