diff --git a/llvm/lib/Analysis/ValueTracking.cpp b/llvm/lib/Analysis/ValueTracking.cpp index f2c6949e535d2..c148dbce92d1a 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( - m_Value(LHS), m_ConstantInt(ClassVal)))) { + m_Specific(V), m_ConstantInt(ClassVal)))) { FPClassTest Mask = static_cast(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 141b44cbbb7a1..78329faf34172 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 +}