Skip to content

Commit a67bd94

Browse files
authored
[ValueTracking] Add missing operand checks in computeKnownFPClassFromCond (#119579)
After #118257, we may call `computeKnownFPClassFromCond` with unrelated conditions. Then miscompilations may occur due to a lack of operand checks. This bug was introduced by d2404ea and #80740. However, the miscompilation couldn't have happened before #118257, because we only added related conditions to `DomConditionCache/AssumptionCache`. Fix the miscompilation reported in #118257 (comment).
1 parent 8420602 commit a67bd94

File tree

2 files changed

+64
-2
lines changed

2 files changed

+64
-2
lines changed

llvm/lib/Analysis/ValueTracking.cpp

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -4906,10 +4906,10 @@ static void computeKnownFPClassFromCond(const Value *V, Value *Cond,
49064906
if (CmpVal == V)
49074907
KnownFromContext.knownNot(~(CondIsTrue ? MaskIfTrue : MaskIfFalse));
49084908
} else if (match(Cond, m_Intrinsic<Intrinsic::is_fpclass>(
4909-
m_Value(LHS), m_ConstantInt(ClassVal)))) {
4909+
m_Specific(V), m_ConstantInt(ClassVal)))) {
49104910
FPClassTest Mask = static_cast<FPClassTest>(ClassVal);
49114911
KnownFromContext.knownNot(CondIsTrue ? ~Mask : Mask);
4912-
} else if (match(Cond, m_ICmp(Pred, m_ElementWiseBitCast(m_Value(LHS)),
4912+
} else if (match(Cond, m_ICmp(Pred, m_ElementWiseBitCast(m_Specific(V)),
49134913
m_APInt(RHS)))) {
49144914
bool TrueIfSigned;
49154915
if (!isSignBitCheck(Pred, *RHS, TrueIfSigned))

llvm/test/Transforms/InstCombine/fpclass-from-dom-cond.ll

Lines changed: 62 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -456,3 +456,65 @@ if.end:
456456
%ret = call <2 x float> @llvm.fabs.v2f32(<2 x float> %value)
457457
ret <2 x float> %ret
458458
}
459+
460+
define i1 @pr118257(half %v0, half %v1) {
461+
; CHECK-LABEL: define i1 @pr118257(
462+
; CHECK-SAME: half [[V0:%.*]], half [[V1:%.*]]) {
463+
; CHECK-NEXT: entry:
464+
; CHECK-NEXT: [[CMP1:%.*]] = fcmp une half [[V1]], 0xH0000
465+
; CHECK-NEXT: [[CAST0:%.*]] = bitcast half [[V0]] to i16
466+
; CHECK-NEXT: [[CMP2:%.*]] = icmp slt i16 [[CAST0]], 0
467+
; CHECK-NEXT: [[OR_COND:%.*]] = or i1 [[CMP1]], [[CMP2]]
468+
; CHECK-NEXT: br i1 [[OR_COND]], label [[IF_END:%.*]], label [[IF_ELSE:%.*]]
469+
; CHECK: if.else:
470+
; CHECK-NEXT: [[CAST1:%.*]] = bitcast half [[V1]] to i16
471+
; CHECK-NEXT: [[CMP3:%.*]] = icmp slt i16 [[CAST1]], 0
472+
; CHECK-NEXT: ret i1 [[CMP3]]
473+
; CHECK: if.end:
474+
; CHECK-NEXT: ret i1 false
475+
;
476+
entry:
477+
%cmp1 = fcmp une half %v1, 0.000000e+00
478+
%cast0 = bitcast half %v0 to i16
479+
%cmp2 = icmp slt i16 %cast0, 0
480+
%or.cond = or i1 %cmp1, %cmp2
481+
br i1 %or.cond, label %if.end, label %if.else
482+
483+
if.else:
484+
%cast1 = bitcast half %v1 to i16
485+
%cmp3 = icmp slt i16 %cast1, 0
486+
ret i1 %cmp3
487+
488+
if.end:
489+
ret i1 false
490+
}
491+
492+
define i1 @pr118257_is_fpclass(half %v0, half %v1) {
493+
; CHECK-LABEL: define i1 @pr118257_is_fpclass(
494+
; CHECK-SAME: half [[V0:%.*]], half [[V1:%.*]]) {
495+
; CHECK-NEXT: entry:
496+
; CHECK-NEXT: [[CMP1:%.*]] = fcmp une half [[V1]], 0xH0000
497+
; CHECK-NEXT: [[CMP2:%.*]] = call i1 @llvm.is.fpclass.f16(half [[V0]], i32 35)
498+
; CHECK-NEXT: [[OR_COND:%.*]] = or i1 [[CMP1]], [[CMP2]]
499+
; CHECK-NEXT: br i1 [[OR_COND]], label [[IF_END:%.*]], label [[IF_ELSE:%.*]]
500+
; CHECK: if.else:
501+
; CHECK-NEXT: [[CAST1:%.*]] = bitcast half [[V1]] to i16
502+
; CHECK-NEXT: [[CMP3:%.*]] = icmp slt i16 [[CAST1]], 0
503+
; CHECK-NEXT: ret i1 [[CMP3]]
504+
; CHECK: if.end:
505+
; CHECK-NEXT: ret i1 false
506+
;
507+
entry:
508+
%cmp1 = fcmp une half %v1, 0.000000e+00
509+
%cmp2 = call i1 @llvm.is.fpclass.half(half %v0, i32 35)
510+
%or.cond = or i1 %cmp1, %cmp2
511+
br i1 %or.cond, label %if.end, label %if.else
512+
513+
if.else:
514+
%cast1 = bitcast half %v1 to i16
515+
%cmp3 = icmp slt i16 %cast1, 0
516+
ret i1 %cmp3
517+
518+
if.end:
519+
ret i1 false
520+
}

0 commit comments

Comments
 (0)