[llvm] a67bd94 - [ValueTracking] Add missing operand checks in `computeKnownFPClassFromCond` (#119579)
via llvm-commits
llvm-commits at lists.llvm.org
Wed Dec 11 18:30:40 PST 2024
Author: Yingwei Zheng
Date: 2024-12-12T10:30:37+08:00
New Revision: a67bd94fdafce716b42e0cb5409ee451b20f1749
URL: https://github.com/llvm/llvm-project/commit/a67bd94fdafce716b42e0cb5409ee451b20f1749
DIFF: https://github.com/llvm/llvm-project/commit/a67bd94fdafce716b42e0cb5409ee451b20f1749.diff
LOG: [ValueTracking] Add missing operand checks in `computeKnownFPClassFromCond` (#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 couldn't have happened before
https://github.com/llvm/llvm-project/pull/118257, because we only added
related conditions to `DomConditionCache/AssumptionCache`.
Fix the miscompilation reported in
https://github.com/llvm/llvm-project/pull/118257#issuecomment-2536182166.
Added:
Modified:
llvm/lib/Analysis/ValueTracking.cpp
llvm/test/Transforms/InstCombine/fpclass-from-dom-cond.ll
Removed:
################################################################################
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 141b44cbbb7a1f..78329faf341727 100644
--- a/llvm/test/Transforms/InstCombine/fpclass-from-dom-cond.ll
+++ b/llvm/test/Transforms/InstCombine/fpclass-from-dom-cond.ll
@@ -456,3 +456,65 @@ 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: [[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
+;
+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: [[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
+;
+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
+}
More information about the llvm-commits
mailing list