From af4356c9a0ac8c7c1bf8a869b9320d64497e6b30 Mon Sep 17 00:00:00 2001 From: Icohedron Date: Wed, 30 Apr 2025 22:27:37 +0000 Subject: [PATCH 1/5] Implement llvm.is.fpclass lowering --- llvm/lib/Target/DirectX/DXIL.td | 27 +++ .../Target/DirectX/DXILIntrinsicExpansion.cpp | 58 +++++++ llvm/lib/Target/DirectX/DXILOpLowering.cpp | 44 +++++ llvm/test/CodeGen/DirectX/is_fpclass.ll | 154 ++++++++++++++++++ 4 files changed, 283 insertions(+) create mode 100644 llvm/test/CodeGen/DirectX/is_fpclass.ll diff --git a/llvm/lib/Target/DirectX/DXIL.td b/llvm/lib/Target/DirectX/DXIL.td index 645105ade72b6..b3b3bcdba491a 100644 --- a/llvm/lib/Target/DirectX/DXIL.td +++ b/llvm/lib/Target/DirectX/DXIL.td @@ -422,6 +422,15 @@ def Saturate : DXILOp<7, unary> { let attributes = [Attributes]; } +def IsNaN : DXILOp<8, isSpecialFloat> { + let Doc = "Determines if the specified value is NaN."; + let arguments = [OverloadTy]; + let result = Int1Ty; + let overloads = [Overloads]; + let stages = [Stages]; + let attributes = [Attributes]; +} + def IsInf : DXILOp<9, isSpecialFloat> { let Doc = "Determines if the specified value is infinite."; let intrinsics = [IntrinSelect]; @@ -432,6 +441,24 @@ def IsInf : DXILOp<9, isSpecialFloat> { let attributes = [Attributes]; } +def IsFinite : DXILOp<10, isSpecialFloat> { + let Doc = "Determines if the specified value is finite."; + let arguments = [OverloadTy]; + let result = Int1Ty; + let overloads = [Overloads]; + let stages = [Stages]; + let attributes = [Attributes]; +} + +def IsNormal : DXILOp<11, isSpecialFloat> { + let Doc = "Determines if the specified value is normal."; + let arguments = [OverloadTy]; + let result = Int1Ty; + let overloads = [Overloads]; + let stages = [Stages]; + let attributes = [Attributes]; +} + def Cos : DXILOp<12, unary> { let Doc = "Returns cosine(theta) for theta in radians."; let intrinsics = [IntrinSelect]; diff --git a/llvm/lib/Target/DirectX/DXILIntrinsicExpansion.cpp b/llvm/lib/Target/DirectX/DXILIntrinsicExpansion.cpp index 8ec5ed0e22974..d6b73c25f2453 100644 --- a/llvm/lib/Target/DirectX/DXILIntrinsicExpansion.cpp +++ b/llvm/lib/Target/DirectX/DXILIntrinsicExpansion.cpp @@ -46,6 +46,7 @@ static bool isIntrinsicExpansion(Function &F) { case Intrinsic::abs: case Intrinsic::atan2: case Intrinsic::exp: + case Intrinsic::is_fpclass: case Intrinsic::log: case Intrinsic::log10: case Intrinsic::pow: @@ -273,6 +274,60 @@ static Value *expandExpIntrinsic(CallInst *Orig) { return Exp2Call; } +static Value *expandIsFPClass(CallInst *Orig) { + Value *T = Orig->getArgOperand(1); + auto *TCI = dyn_cast(T); + + // These FPClassTest cases have DXIL opcodes, so they will be handled in + // DXIL Op Lowering instead. + switch (TCI->getZExtValue()) { + case FPClassTest::fcInf: + case FPClassTest::fcNan: + case FPClassTest::fcNormal: + case FPClassTest::fcFinite: + return nullptr; + } + + IRBuilder<> Builder(Orig); + + Value *F = Orig->getArgOperand(0); + Type *FTy = F->getType(); + unsigned FNumElem = 0; // 0 => F is not a vector + + unsigned BitWidth; // Bit width of F or the ElemTy of F + Type *BitCastTy; // An IntNTy of the same bitwidth as F or ElemTy of F + + if (auto *FVecTy = dyn_cast(FTy)) { + Type* ElemTy = FVecTy->getElementType(); + FNumElem = FVecTy->getNumElements(); + BitWidth = ElemTy->getPrimitiveSizeInBits(); + BitCastTy = FixedVectorType::get(Builder.getIntNTy(BitWidth), FNumElem); + } else { + BitWidth = FTy->getPrimitiveSizeInBits(); + BitCastTy = Builder.getIntNTy(BitWidth); + } + + Value *FBitCast = Builder.CreateBitCast(F, BitCastTy); + switch (TCI->getZExtValue()) { + case FPClassTest::fcNegZero: { + Value *NegZero = + ConstantInt::get(Builder.getIntNTy(BitWidth), 1 << (BitWidth - 1)); + Value *RetVal; + if (FNumElem) { + Value *NegZeroSplat = Builder.CreateVectorSplat(FNumElem, NegZero); + RetVal = + Builder.CreateICmpEQ(FBitCast, NegZeroSplat, "is.fpclass.negzero"); + } else + RetVal = Builder.CreateICmpEQ(FBitCast, NegZero, "is.fpclass.negzero"); + return RetVal; + } + default: + // Deliberately falling through to the unreachable below. + break; + } + llvm_unreachable("Unsupported FPClassTest"); +} + static Value *expandAnyOrAllIntrinsic(CallInst *Orig, Intrinsic::ID IntrinsicId) { Value *X = Orig->getOperand(0); @@ -561,6 +616,9 @@ static bool expandIntrinsic(Function &F, CallInst *Orig) { case Intrinsic::exp: Result = expandExpIntrinsic(Orig); break; + case Intrinsic::is_fpclass: + Result = expandIsFPClass(Orig); + break; case Intrinsic::log: Result = expandLogIntrinsic(Orig); break; diff --git a/llvm/lib/Target/DirectX/DXILOpLowering.cpp b/llvm/lib/Target/DirectX/DXILOpLowering.cpp index fdaffb6b5e49e..ac2f6a53a26f9 100644 --- a/llvm/lib/Target/DirectX/DXILOpLowering.cpp +++ b/llvm/lib/Target/DirectX/DXILOpLowering.cpp @@ -739,6 +739,47 @@ class OpLowerer { }); } + bool lowerIsFPClass(Function &F) { + IRBuilder<> &IRB = OpBuilder.getIRB(); + Type *RetTy = IRB.getInt1Ty(); + + return replaceFunction(F, [&](CallInst *CI) -> Error { + IRB.SetInsertPoint(CI); + SmallVector Args; + Value *Fl = CI->getArgOperand(0); + Args.push_back(Fl); + + dxil::OpCode OpCode; + Value *T = CI->getArgOperand(1); + auto *TCI = dyn_cast(T); + switch (TCI->getZExtValue()) { + case FPClassTest::fcInf: + OpCode = dxil::OpCode::IsInf; + break; + case FPClassTest::fcNan: + OpCode = dxil::OpCode::IsNaN; + break; + case FPClassTest::fcNormal: + OpCode = dxil::OpCode::IsNormal; + break; + case FPClassTest::fcFinite: + OpCode = dxil::OpCode::IsFinite; + break; + default: + llvm_unreachable("Unsupported FPClassTest for DXILOpLowering"); + } + + Expected OpCall = OpBuilder.tryCreateOp( + OpCode, Args, CI->getName(), RetTy); + if (Error E = OpCall.takeError()) + return E; + + CI->replaceAllUsesWith(*OpCall); + CI->eraseFromParent(); + return Error::success(); + }); + } + bool lowerIntrinsics() { bool Updated = false; bool HasErrors = false; @@ -799,6 +840,9 @@ class OpLowerer { case Intrinsic::ctpop: HasErrors |= lowerCtpopToCountBits(F); break; + case Intrinsic::is_fpclass: + HasErrors |= lowerIsFPClass(F); + break; } Updated = true; } diff --git a/llvm/test/CodeGen/DirectX/is_fpclass.ll b/llvm/test/CodeGen/DirectX/is_fpclass.ll new file mode 100644 index 0000000000000..a628096aacd7d --- /dev/null +++ b/llvm/test/CodeGen/DirectX/is_fpclass.ll @@ -0,0 +1,154 @@ +; NOTE: Assertions have been autogenerated by utils/update_test_checks.py UTC_ARGS: --version 5 +; RUN: opt -S -dxil-intrinsic-expansion -scalarizer -dxil-op-lower -mtriple=dxil-pc-shadermodel6.3-library %s | FileCheck %s + + +define noundef i1 @isnegzero(float noundef %a) { +; CHECK-LABEL: define noundef i1 @isnegzero( +; CHECK-SAME: float noundef [[A:%.*]]) { +; CHECK-NEXT: [[ENTRY:.*:]] +; CHECK-NEXT: [[TMP0:%.*]] = bitcast float [[A]] to i32 +; CHECK-NEXT: [[IS_FPCLASS_NEGZERO:%.*]] = icmp eq i32 [[TMP0]], -2147483648 +; CHECK-NEXT: ret i1 [[IS_FPCLASS_NEGZERO]] +; +entry: + %0 = call i1 @llvm.is.fpclass.f32(float %a, i32 32) + ret i1 %0 +} + +define noundef <2 x i1> @isnegzerov2(<2 x float> noundef %a) { +; CHECK-LABEL: define noundef <2 x i1> @isnegzerov2( +; CHECK-SAME: <2 x float> noundef [[A:%.*]]) { +; CHECK-NEXT: [[ENTRY:.*:]] +; CHECK-NEXT: [[A_I0:%.*]] = extractelement <2 x float> [[A]], i64 0 +; CHECK-NEXT: [[DOTI0:%.*]] = bitcast float [[A_I0]] to i32 +; CHECK-NEXT: [[A_I1:%.*]] = extractelement <2 x float> [[A]], i64 1 +; CHECK-NEXT: [[DOTI1:%.*]] = bitcast float [[A_I1]] to i32 +; CHECK-NEXT: [[IS_FPCLASS_NEGZERO_I0:%.*]] = icmp eq i32 [[DOTI0]], -2147483648 +; CHECK-NEXT: [[IS_FPCLASS_NEGZERO_I1:%.*]] = icmp eq i32 [[DOTI1]], -2147483648 +; CHECK-NEXT: [[IS_FPCLASS_NEGZERO_UPTO0:%.*]] = insertelement <2 x i1> poison, i1 [[IS_FPCLASS_NEGZERO_I0]], i64 0 +; CHECK-NEXT: [[IS_FPCLASS_NEGZERO:%.*]] = insertelement <2 x i1> [[IS_FPCLASS_NEGZERO_UPTO0]], i1 [[IS_FPCLASS_NEGZERO_I1]], i64 1 +; CHECK-NEXT: ret <2 x i1> [[IS_FPCLASS_NEGZERO]] +; +entry: + %0 = call <2 x i1> @llvm.is.fpclass.v2f32(<2 x float> %a, i32 32) + ret <2 x i1> %0 +} + +define noundef i1 @isnan(float noundef %a) { +; CHECK-LABEL: define noundef i1 @isnan( +; CHECK-SAME: float noundef [[A:%.*]]) { +; CHECK-NEXT: [[ENTRY:.*:]] +; CHECK-NEXT: [[TMP0:%.*]] = call i1 @dx.op.isSpecialFloat.f32(i32 8, float [[A]]) #[[ATTR0:[0-9]+]] +; CHECK-NEXT: ret i1 [[TMP0]] +; +entry: + %0 = call i1 @llvm.is.fpclass.f32(float %a, i32 3) + ret i1 %0 +} + +define noundef <2 x i1> @isnanv2(<2 x float> noundef %a) { +; CHECK-LABEL: define noundef <2 x i1> @isnanv2( +; CHECK-SAME: <2 x float> noundef [[A:%.*]]) { +; CHECK-NEXT: [[ENTRY:.*:]] +; CHECK-NEXT: [[A_I0:%.*]] = extractelement <2 x float> [[A]], i64 0 +; CHECK-NEXT: [[DOTI02:%.*]] = call i1 @dx.op.isSpecialFloat.f32(i32 8, float [[A_I0]]) #[[ATTR0]] +; CHECK-NEXT: [[A_I1:%.*]] = extractelement <2 x float> [[A]], i64 1 +; CHECK-NEXT: [[DOTI11:%.*]] = call i1 @dx.op.isSpecialFloat.f32(i32 8, float [[A_I1]]) #[[ATTR0]] +; CHECK-NEXT: [[DOTUPTO0:%.*]] = insertelement <2 x i1> poison, i1 [[DOTI02]], i64 0 +; CHECK-NEXT: [[TMP0:%.*]] = insertelement <2 x i1> [[DOTUPTO0]], i1 [[DOTI11]], i64 1 +; CHECK-NEXT: ret <2 x i1> [[TMP0]] +; +entry: + %0 = call <2 x i1> @llvm.is.fpclass.v2f32(<2 x float> %a, i32 3) + ret <2 x i1> %0 +} + +define noundef i1 @isinf(float noundef %a) { +; CHECK-LABEL: define noundef i1 @isinf( +; CHECK-SAME: float noundef [[A:%.*]]) { +; CHECK-NEXT: [[ENTRY:.*:]] +; CHECK-NEXT: [[TMP0:%.*]] = call i1 @dx.op.isSpecialFloat.f32(i32 9, float [[A]]) #[[ATTR0]] +; CHECK-NEXT: ret i1 [[TMP0]] +; +entry: + %0 = call i1 @llvm.is.fpclass.f32(float %a, i32 516) + ret i1 %0 +} + +define noundef <2 x i1> @isinfv2(<2 x float> noundef %a) { +; CHECK-LABEL: define noundef <2 x i1> @isinfv2( +; CHECK-SAME: <2 x float> noundef [[A:%.*]]) { +; CHECK-NEXT: [[ENTRY:.*:]] +; CHECK-NEXT: [[A_I0:%.*]] = extractelement <2 x float> [[A]], i64 0 +; CHECK-NEXT: [[DOTI02:%.*]] = call i1 @dx.op.isSpecialFloat.f32(i32 9, float [[A_I0]]) #[[ATTR0]] +; CHECK-NEXT: [[A_I1:%.*]] = extractelement <2 x float> [[A]], i64 1 +; CHECK-NEXT: [[DOTI11:%.*]] = call i1 @dx.op.isSpecialFloat.f32(i32 9, float [[A_I1]]) #[[ATTR0]] +; CHECK-NEXT: [[DOTUPTO0:%.*]] = insertelement <2 x i1> poison, i1 [[DOTI02]], i64 0 +; CHECK-NEXT: [[TMP0:%.*]] = insertelement <2 x i1> [[DOTUPTO0]], i1 [[DOTI11]], i64 1 +; CHECK-NEXT: ret <2 x i1> [[TMP0]] +; +entry: + %0 = call <2 x i1> @llvm.is.fpclass.v2f32(<2 x float> %a, i32 516) + ret <2 x i1> %0 +} + +define noundef i1 @isfinite(float noundef %a) { +; CHECK-LABEL: define noundef i1 @isfinite( +; CHECK-SAME: float noundef [[A:%.*]]) { +; CHECK-NEXT: [[ENTRY:.*:]] +; CHECK-NEXT: [[TMP0:%.*]] = call i1 @dx.op.isSpecialFloat.f32(i32 10, float [[A]]) #[[ATTR0]] +; CHECK-NEXT: ret i1 [[TMP0]] +; +entry: + %0 = call i1 @llvm.is.fpclass.f32(float %a, i32 504) + ret i1 %0 +} + +define noundef <2 x i1> @isfinitev2(<2 x float> noundef %a) { +; CHECK-LABEL: define noundef <2 x i1> @isfinitev2( +; CHECK-SAME: <2 x float> noundef [[A:%.*]]) { +; CHECK-NEXT: [[ENTRY:.*:]] +; CHECK-NEXT: [[A_I0:%.*]] = extractelement <2 x float> [[A]], i64 0 +; CHECK-NEXT: [[DOTI02:%.*]] = call i1 @dx.op.isSpecialFloat.f32(i32 10, float [[A_I0]]) #[[ATTR0]] +; CHECK-NEXT: [[A_I1:%.*]] = extractelement <2 x float> [[A]], i64 1 +; CHECK-NEXT: [[DOTI11:%.*]] = call i1 @dx.op.isSpecialFloat.f32(i32 10, float [[A_I1]]) #[[ATTR0]] +; CHECK-NEXT: [[DOTUPTO0:%.*]] = insertelement <2 x i1> poison, i1 [[DOTI02]], i64 0 +; CHECK-NEXT: [[TMP0:%.*]] = insertelement <2 x i1> [[DOTUPTO0]], i1 [[DOTI11]], i64 1 +; CHECK-NEXT: ret <2 x i1> [[TMP0]] +; +entry: + %0 = call <2 x i1> @llvm.is.fpclass.v2f32(<2 x float> %a, i32 504) + ret <2 x i1> %0 +} + +define noundef i1 @isnormal(float noundef %a) { +; CHECK-LABEL: define noundef i1 @isnormal( +; CHECK-SAME: float noundef [[A:%.*]]) { +; CHECK-NEXT: [[ENTRY:.*:]] +; CHECK-NEXT: [[TMP0:%.*]] = call i1 @dx.op.isSpecialFloat.f32(i32 11, float [[A]]) #[[ATTR0]] +; CHECK-NEXT: ret i1 [[TMP0]] +; +entry: + %0 = call i1 @llvm.is.fpclass.f32(float %a, i32 264) + ret i1 %0 +} + +define noundef <2 x i1> @isnormalv2(<2 x float> noundef %a) { +; CHECK-LABEL: define noundef <2 x i1> @isnormalv2( +; CHECK-SAME: <2 x float> noundef [[A:%.*]]) { +; CHECK-NEXT: [[ENTRY:.*:]] +; CHECK-NEXT: [[A_I0:%.*]] = extractelement <2 x float> [[A]], i64 0 +; CHECK-NEXT: [[DOTI02:%.*]] = call i1 @dx.op.isSpecialFloat.f32(i32 11, float [[A_I0]]) #[[ATTR0]] +; CHECK-NEXT: [[A_I1:%.*]] = extractelement <2 x float> [[A]], i64 1 +; CHECK-NEXT: [[DOTI11:%.*]] = call i1 @dx.op.isSpecialFloat.f32(i32 11, float [[A_I1]]) #[[ATTR0]] +; CHECK-NEXT: [[DOTUPTO0:%.*]] = insertelement <2 x i1> poison, i1 [[DOTI02]], i64 0 +; CHECK-NEXT: [[TMP0:%.*]] = insertelement <2 x i1> [[DOTUPTO0]], i1 [[DOTI11]], i64 1 +; CHECK-NEXT: ret <2 x i1> [[TMP0]] +; +entry: + %0 = call <2 x i1> @llvm.is.fpclass.v2f32(<2 x float> %a, i32 264) + ret <2 x i1> %0 +} + +declare i1 @llvm.is.fpclass.f32(float, i32 immarg) +declare <2 x i1> @llvm.is.fpclass.v2f32(<2 x float>, i32 immarg) From 4a4284d95462de7de6f4a73f7d67a7416ba80218 Mon Sep 17 00:00:00 2001 From: Icohedron Date: Wed, 30 Apr 2025 23:10:06 +0000 Subject: [PATCH 2/5] Apply clang-format --- llvm/lib/Target/DirectX/DXILIntrinsicExpansion.cpp | 4 ++-- llvm/lib/Target/DirectX/DXILOpLowering.cpp | 4 ++-- 2 files changed, 4 insertions(+), 4 deletions(-) diff --git a/llvm/lib/Target/DirectX/DXILIntrinsicExpansion.cpp b/llvm/lib/Target/DirectX/DXILIntrinsicExpansion.cpp index d6b73c25f2453..5a13bf98e027f 100644 --- a/llvm/lib/Target/DirectX/DXILIntrinsicExpansion.cpp +++ b/llvm/lib/Target/DirectX/DXILIntrinsicExpansion.cpp @@ -295,10 +295,10 @@ static Value *expandIsFPClass(CallInst *Orig) { unsigned FNumElem = 0; // 0 => F is not a vector unsigned BitWidth; // Bit width of F or the ElemTy of F - Type *BitCastTy; // An IntNTy of the same bitwidth as F or ElemTy of F + Type *BitCastTy; // An IntNTy of the same bitwidth as F or ElemTy of F if (auto *FVecTy = dyn_cast(FTy)) { - Type* ElemTy = FVecTy->getElementType(); + Type *ElemTy = FVecTy->getElementType(); FNumElem = FVecTy->getNumElements(); BitWidth = ElemTy->getPrimitiveSizeInBits(); BitCastTy = FixedVectorType::get(Builder.getIntNTy(BitWidth), FNumElem); diff --git a/llvm/lib/Target/DirectX/DXILOpLowering.cpp b/llvm/lib/Target/DirectX/DXILOpLowering.cpp index ac2f6a53a26f9..3366f24d1da32 100644 --- a/llvm/lib/Target/DirectX/DXILOpLowering.cpp +++ b/llvm/lib/Target/DirectX/DXILOpLowering.cpp @@ -769,8 +769,8 @@ class OpLowerer { llvm_unreachable("Unsupported FPClassTest for DXILOpLowering"); } - Expected OpCall = OpBuilder.tryCreateOp( - OpCode, Args, CI->getName(), RetTy); + Expected OpCall = + OpBuilder.tryCreateOp(OpCode, Args, CI->getName(), RetTy); if (Error E = OpCall.takeError()) return E; From 0b19dcfbe53946702df956d38f6d4c95de850a31 Mon Sep 17 00:00:00 2001 From: Icohedron Date: Wed, 30 Apr 2025 23:19:51 +0000 Subject: [PATCH 3/5] Add [[nodiscard]] to lowerIsFPClass --- llvm/lib/Target/DirectX/DXILOpLowering.cpp | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/llvm/lib/Target/DirectX/DXILOpLowering.cpp b/llvm/lib/Target/DirectX/DXILOpLowering.cpp index 3366f24d1da32..098c6e79484e8 100644 --- a/llvm/lib/Target/DirectX/DXILOpLowering.cpp +++ b/llvm/lib/Target/DirectX/DXILOpLowering.cpp @@ -739,7 +739,7 @@ class OpLowerer { }); } - bool lowerIsFPClass(Function &F) { + [[nodiscard]] bool lowerIsFPClass(Function &F) { IRBuilder<> &IRB = OpBuilder.getIRB(); Type *RetTy = IRB.getInt1Ty(); @@ -769,8 +769,8 @@ class OpLowerer { llvm_unreachable("Unsupported FPClassTest for DXILOpLowering"); } - Expected OpCall = - OpBuilder.tryCreateOp(OpCode, Args, CI->getName(), RetTy); + Expected OpCall = OpBuilder.tryCreateOp( + OpCode, Args, CI->getName(), RetTy); if (Error E = OpCall.takeError()) return E; From 5a2804145f1301fdd8621928864829ab9ca5fc9d Mon Sep 17 00:00:00 2001 From: Icohedron Date: Wed, 30 Apr 2025 23:20:35 +0000 Subject: [PATCH 4/5] Re-apply clang-format --- llvm/lib/Target/DirectX/DXILOpLowering.cpp | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/llvm/lib/Target/DirectX/DXILOpLowering.cpp b/llvm/lib/Target/DirectX/DXILOpLowering.cpp index 098c6e79484e8..04344bd073ffd 100644 --- a/llvm/lib/Target/DirectX/DXILOpLowering.cpp +++ b/llvm/lib/Target/DirectX/DXILOpLowering.cpp @@ -769,8 +769,8 @@ class OpLowerer { llvm_unreachable("Unsupported FPClassTest for DXILOpLowering"); } - Expected OpCall = OpBuilder.tryCreateOp( - OpCode, Args, CI->getName(), RetTy); + Expected OpCall = + OpBuilder.tryCreateOp(OpCode, Args, CI->getName(), RetTy); if (Error E = OpCall.takeError()) return E; From 0d8ea828f238739938444e82d8bd12076a42f699 Mon Sep 17 00:00:00 2001 From: Icohedron Date: Fri, 2 May 2025 18:16:18 +0000 Subject: [PATCH 5/5] Change error handling to be consistent within each file --- llvm/lib/Target/DirectX/DXILIntrinsicExpansion.cpp | 5 ++--- llvm/lib/Target/DirectX/DXILOpLowering.cpp | 5 ++++- 2 files changed, 6 insertions(+), 4 deletions(-) diff --git a/llvm/lib/Target/DirectX/DXILIntrinsicExpansion.cpp b/llvm/lib/Target/DirectX/DXILIntrinsicExpansion.cpp index 5a13bf98e027f..db4005d80f063 100644 --- a/llvm/lib/Target/DirectX/DXILIntrinsicExpansion.cpp +++ b/llvm/lib/Target/DirectX/DXILIntrinsicExpansion.cpp @@ -322,10 +322,9 @@ static Value *expandIsFPClass(CallInst *Orig) { return RetVal; } default: - // Deliberately falling through to the unreachable below. - break; + report_fatal_error(Twine("Unsupported FPClassTest"), + /* gen_crash_diag=*/false); } - llvm_unreachable("Unsupported FPClassTest"); } static Value *expandAnyOrAllIntrinsic(CallInst *Orig, diff --git a/llvm/lib/Target/DirectX/DXILOpLowering.cpp b/llvm/lib/Target/DirectX/DXILOpLowering.cpp index 04344bd073ffd..c9427d16edb46 100644 --- a/llvm/lib/Target/DirectX/DXILOpLowering.cpp +++ b/llvm/lib/Target/DirectX/DXILOpLowering.cpp @@ -766,7 +766,10 @@ class OpLowerer { OpCode = dxil::OpCode::IsFinite; break; default: - llvm_unreachable("Unsupported FPClassTest for DXILOpLowering"); + SmallString<128> Msg = + formatv("Unsupported FPClassTest {0} for DXIL Op Lowering", + TCI->getZExtValue()); + return make_error(Msg, inconvertibleErrorCode()); } Expected OpCall =