From df39678c0aad0a58e7e9cd237be011dd6281d445 Mon Sep 17 00:00:00 2001 From: Jim Blandy Date: Tue, 29 Apr 2025 12:43:10 -0700 Subject: [PATCH] Fix `asuint` operator when applied to `int` values. Bother to mark the APSInt result as unsigned, to avoid tripping IntExprEvaluator::Success's assertion that SI.isSigned() matches E's type. Fixes #7395. --- tools/clang/lib/AST/ExprConstant.cpp | 4 +++- tools/clang/test/DXC/asuint-constant-eval.hlsl | 15 +++++++++++++++ 2 files changed, 18 insertions(+), 1 deletion(-) create mode 100644 tools/clang/test/DXC/asuint-constant-eval.hlsl diff --git a/tools/clang/lib/AST/ExprConstant.cpp b/tools/clang/lib/AST/ExprConstant.cpp index 69e0760bce..aa1ce67194 100644 --- a/tools/clang/lib/AST/ExprConstant.cpp +++ b/tools/clang/lib/AST/ExprConstant.cpp @@ -3786,7 +3786,9 @@ static bool HandleIntrinsicCall(SourceLocation CallLoc, unsigned opcode, case hlsl::IntrinsicOp::IOP_asuint: assert(Args.size() == 1 && "else call should be invalid"); if (ArgValues[0].isInt()) { - Result = ArgValues[0]; + APSInt value = ArgValues[0].getInt(); + value.setIsUnsigned(true); + Result = APValue(value); } else if (ArgValues[0].isFloat()) { const bool isUnsignedTrue = true; diff --git a/tools/clang/test/DXC/asuint-constant-eval.hlsl b/tools/clang/test/DXC/asuint-constant-eval.hlsl new file mode 100644 index 0000000000..2030dccb47 --- /dev/null +++ b/tools/clang/test/DXC/asuint-constant-eval.hlsl @@ -0,0 +1,15 @@ +// RUN: %dxc /T ps_6_9 -fcgl %s | FileCheck %s + +// Compiling this HLSL would fail this assertion in IntExprEvaluator::Success: +// +// assert(SI.isSigned() == E->getType()->isSignedIntegerOrEnumerationType() && +// "Invalid evaluation result."); +// +// Bug was fixed in HandleIntrinsicCall by updating the APSInt's signednes. + +// CHECK: %{{.*}} = call i32 @"dx.hl.op.rn.i32 (i32, i32)"(i32 {{.*}}, i32 1) + +void main() +{ + int i = asuint(int(1)); +}