From fdbd04a4913ff864d454dfdd3a294271a57dbc12 Mon Sep 17 00:00:00 2001 From: Chris B Date: Mon, 5 Oct 2026 13:34:27 -0600 Subject: [PATCH 1/3] [SM6.9] Prevent GVN from generating illegal integers This change is a more complete set of checks to avoid GVN generating invalid integer sizes. We've had a few cases of this previously, but I think this covers the remaining cases in GVN. Fixes #9040 --- docs/ReleaseNotes.md | 3 + lib/Transforms/Scalar/GVN.cpp | 41 +++- .../Passes/GVN/dxil_illegal_integer_size.ll | 210 ++++++++++++++++++ .../GVN/dxil_illegal_narrow_integer_size.ll | 205 +++++++++++++++++ 4 files changed, 453 insertions(+), 6 deletions(-) create mode 100644 tools/clang/test/DXC/Passes/GVN/dxil_illegal_integer_size.ll create mode 100644 tools/clang/test/DXC/Passes/GVN/dxil_illegal_narrow_integer_size.ll diff --git a/docs/ReleaseNotes.md b/docs/ReleaseNotes.md index 02b1755bf8..e38c8f4c72 100644 --- a/docs/ReleaseNotes.md +++ b/docs/ReleaseNotes.md @@ -80,6 +80,9 @@ line upon naming the release. Refer to previous for appropriate section names. #### Bug Fixes +- Fixed GVN load forwarding generating unsupported integer types when optimizing + native vectors + [#8940](https://github.com/microsoft/DirectXShaderCompiler/issues/9040). - Fixed shader reflection dropping leading characters from user-defined struct type names. - Fixed an optimizer crash when scalarizing an out-of-bounds vector access [#8940](https://github.com/microsoft/DirectXShaderCompiler/issues/8940). diff --git a/lib/Transforms/Scalar/GVN.cpp b/lib/Transforms/Scalar/GVN.cpp index 2a170795bb..88fa8f90d3 100644 --- a/lib/Transforms/Scalar/GVN.cpp +++ b/lib/Transforms/Scalar/GVN.cpp @@ -842,6 +842,21 @@ static bool IsValueFullyAvailableInBlock(BasicBlock *BB, } +// HLSL Change Begin - DXIL only supports these integer widths. +static bool IsValidDxilIntegerWidth(uint64_t Width) { + switch (Width) { + case 1: + case 8: + case 16: + case 32: + case 64: + return true; + default: + return false; + } +} +// HLSL Change End + /// Return true if CoerceAvailableValueToLoadType will succeed. static bool CanCoerceMustAliasedValueToLoad(Value *StoredVal, Type *LoadTy, @@ -863,14 +878,16 @@ static bool CanCoerceMustAliasedValueToLoad(Value *StoredVal, if (LoadPrimBits && DL.getTypeSizeInBits(LoadTy) != LoadPrimBits) return false; - // Reject coercions that require bitcasting a non-integer value (e.g. a native - // vector) to an integer wider than 64 bits. DXIL does not support integer - // types wider than 64 bits, so such coercions would produce invalid DXIL. + // Reject coercions that would create an integer type unsupported by DXIL. uint64_t StoredValBits = DL.getTypeSizeInBits(StoredValTy); uint64_t LoadBits = DL.getTypeSizeInBits(LoadTy); - if (StoredValBits > 64 && !StoredValTy->isIntegerTy() && - (StoredValBits != LoadBits || LoadTy->isIntegerTy())) - return false; + if (StoredValBits != LoadBits) { + if (!StoredValTy->isIntegerTy() && + !IsValidDxilIntegerWidth(StoredValBits)) + return false; + if (!IsValidDxilIntegerWidth(LoadBits)) + return false; + } // HLSL Change End // The store has to be at least as big as the load. @@ -1159,12 +1176,24 @@ static int AnalyzeLoadFromClobberingMemInst(Type *LoadTy, Value *LoadPtr, static Value *GetStoreValueForLoad(Value *SrcVal, unsigned Offset, Type *LoadTy, Instruction *InsertPt, const DataLayout &DL){ + // HLSL Change Begin - Reject unsupported coercions before extracting bits. + if (!CanCoerceMustAliasedValueToLoad(SrcVal, LoadTy, DL)) + return nullptr; + // HLSL Change End. + LLVMContext &Ctx = SrcVal->getType()->getContext(); uint64_t StoreSize = (DL.getTypeSizeInBits(SrcVal->getType()) + 7) / 8; uint64_t LoadSize = (DL.getTypeSizeInBits(LoadTy) + 7) / 8; IRBuilder<> Builder(InsertPt); + // HLSL Change Begin - Equal-sized values need no integer extraction. In + // particular, directly bitcast native vectors rather than routing them + // through an illegal integer type. + if (Offset == 0 && StoreSize == LoadSize) + return CoerceAvailableValueToLoadType(SrcVal, LoadTy, Builder, DL); + + // HLSL Change End. // Compute which bits of the stored value are being used by the load. Convert // to an integer type to start with. diff --git a/tools/clang/test/DXC/Passes/GVN/dxil_illegal_integer_size.ll b/tools/clang/test/DXC/Passes/GVN/dxil_illegal_integer_size.ll new file mode 100644 index 0000000000..1a4b6e1152 --- /dev/null +++ b/tools/clang/test/DXC/Passes/GVN/dxil_illegal_integer_size.ll @@ -0,0 +1,210 @@ +; RUN: opt -S -basicaa -gvn -verify %s -o %t +; RUN: FileCheck %s < %t +; RUN: FileCheck %s --check-prefix=WIDTH < %t + +; Check the whole output, including instructions between the per-function checks. +; WIDTH: target triple = "dxil-ms-dx" +; WIDTH-NOT: {{i(24|48|96|128|192|256)}} + +target datalayout = "e-m:e-p:32:32-i1:32-i8:32-i16:32-i32:32-i64:64-f16:32-f32:32-f64:64-n8:16:32:64" +target triple = "dxil-ms-dx" + +; GVN must not coerce the dynamically indexed store through i96, which is not +; a legal integer type in DXIL. +; +; CHECK-LABEL: @dynamic_index( +; CHECK-NOT: i96 +; CHECK: %[[INITIAL:.*]] = bitcast <3 x i32> %initial to <3 x float> +; CHECK: %result = phi <3 x float> [ %result.pre, %store ], [ %[[INITIAL]], %entry ] +; CHECK: ret <3 x float> %result +define <3 x float> @dynamic_index(<3 x i32> %initial, + <3 x i32> %conditional, i32 %index) { +entry: + %values = alloca [2 x <3 x float>], align 4 + %first = getelementptr inbounds [2 x <3 x float>], + [2 x <3 x float>]* %values, i32 0, i32 0 + %first.i32 = bitcast <3 x float>* %first to <3 x i32>* + store <3 x i32> %initial, <3 x i32>* %first.i32, align 4 + %cmp = icmp ugt i32 %index, 1 + br i1 %cmp, label %store, label %exit + +store: + %array.index = and i32 %index, 1 + %element = getelementptr inbounds [2 x <3 x float>], + [2 x <3 x float>]* %values, i32 0, + i32 %array.index + %element.i32 = bitcast <3 x float>* %element to <3 x i32>* + store <3 x i32> %conditional, <3 x i32>* %element.i32, align 4 + br label %exit + +exit: + %reload = getelementptr inbounds [2 x <3 x float>], + [2 x <3 x float>]* %values, i32 0, i32 0 + %result = load <3 x float>, <3 x float>* %reload, align 4 + ret <3 x float> %result +} + +; GVN cannot extract this load at a nonzero offset without creating illegal +; i128 and i96 intermediates, so it must leave the load in place. +; +; CHECK-LABEL: @nonzero_offset( +; CHECK-NOT: i128 +; CHECK-NOT: i96 +; CHECK: %result = load <3 x float>, <3 x float>* %vector, align 4 +; CHECK: ret <3 x float> %result +define <3 x float> @nonzero_offset(<4 x float> %value, <4 x float>* %ptr) { +entry: + store <4 x float> %value, <4 x float>* %ptr, align 4 + %bytes = bitcast <4 x float>* %ptr to i8* + %offset = getelementptr inbounds i8, i8* %bytes, i32 4 + %vector = bitcast i8* %offset to <3 x float>* + %result = load <3 x float>, <3 x float>* %vector, align 4 + ret <3 x float> %result +} + +; Equal-sized wide vectors can be forwarded without a scalar integer +; intermediate, both locally and when available values are merged with a phi. +; +; CHECK-LABEL: @equal_size_local( +; CHECK: %[[CAST:.*]] = bitcast <3 x i32> %value to <3 x float> +; CHECK-NOT: load +; CHECK: ret <3 x float> %[[CAST]] +define <3 x float> @equal_size_local(<3 x i32> %value, <3 x i32>* %ptr) { +entry: + store <3 x i32> %value, <3 x i32>* %ptr, align 4 + %cast = bitcast <3 x i32>* %ptr to <3 x float>* + %result = load <3 x float>, <3 x float>* %cast, align 4 + ret <3 x float> %result +} + +; CHECK-LABEL: @equal_size_nonlocal( +; CHECK: left: +; CHECK: %[[LEFT:.*]] = bitcast <3 x i32> %a to <3 x float> +; CHECK: right: +; CHECK: %[[RIGHT:.*]] = bitcast <3 x i32> %b to <3 x float> +; CHECK: exit: +; CHECK: %result = phi <3 x float> [ %[[RIGHT]], %right ], [ %[[LEFT]], %left ] +; CHECK-NEXT: ret <3 x float> %result +define <3 x float> @equal_size_nonlocal(<3 x i32> %a, <3 x i32> %b, + <3 x i32>* %ptr, i1 %condition) { +entry: + %cast = bitcast <3 x i32>* %ptr to <3 x float>* + br i1 %condition, label %left, label %right + +left: + store <3 x i32> %a, <3 x i32>* %ptr, align 4 + br label %exit + +right: + store <3 x i32> %b, <3 x i32>* %ptr, align 4 + br label %exit + +exit: + %result = load <3 x float>, <3 x float>* %cast, align 4 + ret <3 x float> %result +} + +; Load-to-load forwarding also supports equal-sized vectors wider than 64 bits. +; Use 192 bits here to avoid only testing the original 96-bit size. +; +; CHECK-LABEL: @equal_size_load( +; CHECK: %value = load <3 x double>, <3 x double>* %ptr, align 8 +; CHECK-NOT: load +; CHECK: %[[CAST:.*]] = bitcast <3 x double> %value to <6 x i32> +; CHECK-NEXT: %result = insertvalue { <3 x double>, <6 x i32> } undef, <3 x double> %value, 0 +; CHECK-NEXT: %pair = insertvalue { <3 x double>, <6 x i32> } %result, <6 x i32> %[[CAST]], 1 +; CHECK-NEXT: ret { <3 x double>, <6 x i32> } %pair +define { <3 x double>, <6 x i32> } @equal_size_load(<3 x double>* %ptr) { +entry: + %value = load <3 x double>, <3 x double>* %ptr, align 8 + %cast = bitcast <3 x double>* %ptr to <6 x i32>* + %reload = load <6 x i32>, <6 x i32>* %cast, align 8 + %result = insertvalue { <3 x double>, <6 x i32> } undef, <3 x double> %value, 0 + %pair = insertvalue { <3 x double>, <6 x i32> } %result, <6 x i32> %reload, 1 + ret { <3 x double>, <6 x i32> } %pair +} + +; Even when the result is a legal i32, extracting it from a wide vector must +; not create an i96 intermediate. Cover both store and load definitions. +; +; CHECK-LABEL: @wide_store_to_scalar( +; CHECK: store <3 x i32> %value, <3 x i32>* %ptr, align 4 +; CHECK: %result = load i32, i32* %cast, align 4 +; CHECK-NEXT: ret i32 %result +define i32 @wide_store_to_scalar(<3 x i32> %value, <3 x i32>* %ptr) { +entry: + store <3 x i32> %value, <3 x i32>* %ptr, align 4 + %cast = bitcast <3 x i32>* %ptr to i32* + %result = load i32, i32* %cast, align 4 + ret i32 %result +} + +; CHECK-LABEL: @wide_load_to_scalar( +; CHECK: %value = load <3 x i32>, <3 x i32>* %ptr, align 4 +; CHECK: %reload = load i32, i32* %cast, align 4 +; CHECK-NEXT: %result = insertelement <3 x i32> %value, i32 %reload, i32 2 +; CHECK-NEXT: ret <3 x i32> %result +define <3 x i32> @wide_load_to_scalar(<3 x i32>* %ptr) { +entry: + %value = load <3 x i32>, <3 x i32>* %ptr, align 4 + %cast = bitcast <3 x i32>* %ptr to i32* + %reload = load i32, i32* %cast, align 4 + %result = insertelement <3 x i32> %value, i32 %reload, i32 2 + ret <3 x i32> %result +} + +; The destination width matters too: extracting a three-lane vector from a +; four-lane vector would create both i128 and i96, even at offset zero. +; +; CHECK-LABEL: @wide_store_to_vector( +; CHECK: %result = load <3 x float>, <3 x float>* %cast, align 4 +; CHECK-NEXT: ret <3 x float> %result +define <3 x float> @wide_store_to_vector(<4 x float> %value, <4 x float>* %ptr) { +entry: + store <4 x float> %value, <4 x float>* %ptr, align 4 + %cast = bitcast <4 x float>* %ptr to <3 x float>* + %result = load <3 x float>, <3 x float>* %cast, align 4 + ret <3 x float> %result +} + +; Nonlocal availability analysis must reject unsafe coercions before trying to +; materialize the incoming values for a phi. +; +; CHECK-LABEL: @wide_store_nonlocal( +; CHECK: exit: +; CHECK-NEXT: %result = load i32, i32* %cast, align 4 +; CHECK-NEXT: ret i32 %result +define i32 @wide_store_nonlocal(<3 x i32> %a, <3 x i32> %b, + <3 x i32>* %ptr, i1 %condition) { +entry: + %cast = bitcast <3 x i32>* %ptr to i32* + br i1 %condition, label %left, label %right + +left: + store <3 x i32> %a, <3 x i32>* %ptr, align 4 + br label %exit + +right: + store <3 x i32> %b, <3 x i32>* %ptr, align 4 + br label %exit + +exit: + %result = load i32, i32* %cast, align 4 + ret i32 %result +} + +; A 64-bit source and a 32-bit destination need only legal integer types, so +; the width checks must not disable this optimization. +; +; CHECK-LABEL: @legal_partial_store( +; CHECK: %[[BITS:.*]] = bitcast <2 x i32> %value to i64 +; CHECK-NEXT: %[[LOW:.*]] = trunc i64 %[[BITS]] to i32 +; CHECK-NEXT: %[[CAST:.*]] = bitcast i32 %[[LOW]] to float +; CHECK-NEXT: ret float %[[CAST]] +define float @legal_partial_store(<2 x i32> %value, <2 x i32>* %ptr) { +entry: + store <2 x i32> %value, <2 x i32>* %ptr, align 4 + %cast = bitcast <2 x i32>* %ptr to float* + %result = load float, float* %cast, align 4 + ret float %result +} diff --git a/tools/clang/test/DXC/Passes/GVN/dxil_illegal_narrow_integer_size.ll b/tools/clang/test/DXC/Passes/GVN/dxil_illegal_narrow_integer_size.ll new file mode 100644 index 0000000000..3a22af3bea --- /dev/null +++ b/tools/clang/test/DXC/Passes/GVN/dxil_illegal_narrow_integer_size.ll @@ -0,0 +1,205 @@ +; RUN: opt -S -basicaa -gvn -verify %s -o %t +; RUN: FileCheck %s < %t +; RUN: FileCheck %s --check-prefix=WIDTH < %t + +; Use natural i8/i16 alignment so padding checks do not mask illegal integer +; widths below 64 bits. A maximum-width check alone would allow i24 and i48. +; +; WIDTH: target triple = "dxil-ms-dx" +; WIDTH-NOT: {{i(24|48|96|128|192|256)}} + +target datalayout = "e-m:e-p:32:32-i1:32-i8:8-i16:16-i32:32-i64:64-f16:16-f32:32-f64:64-n8:16:32:64" +target triple = "dxil-ms-dx" + +; Reject an illegal source-width intermediate even with a legal result width. +; +; CHECK-LABEL: @store_24_to_8( +; CHECK: %result = load i8, i8* %cast, align 1 +; CHECK-NEXT: ret i8 %result +define i8 @store_24_to_8(<3 x i8> %value, <3 x i8>* %ptr) { +entry: + store <3 x i8> %value, <3 x i8>* %ptr, align 1 + %cast = bitcast <3 x i8>* %ptr to i8* + %result = load i8, i8* %cast, align 1 + ret i8 %result +} + +; CHECK-LABEL: @load_48_to_16( +; CHECK: %value = load <3 x i16>, <3 x i16>* %ptr, align 2 +; CHECK: %reload = load i16, i16* %cast, align 2 +; CHECK-NEXT: %result = insertelement <3 x i16> %value, i16 %reload, i32 2 +; CHECK-NEXT: ret <3 x i16> %result +define <3 x i16> @load_48_to_16(<3 x i16>* %ptr) { +entry: + %value = load <3 x i16>, <3 x i16>* %ptr, align 2 + %cast = bitcast <3 x i16>* %ptr to i16* + %reload = load i16, i16* %cast, align 2 + %result = insertelement <3 x i16> %value, i16 %reload, i32 2 + ret <3 x i16> %result +} + +; Legal scalar integer sources must not be truncated to illegal widths either. +; +; CHECK-LABEL: @store_32_to_24( +; CHECK: %result = load <3 x i8>, <3 x i8>* %cast, align 1 +; CHECK-NEXT: ret <3 x i8> %result +define <3 x i8> @store_32_to_24(i32 %value, i32* %ptr) { +entry: + store i32 %value, i32* %ptr, align 4 + %cast = bitcast i32* %ptr to <3 x i8>* + %result = load <3 x i8>, <3 x i8>* %cast, align 1 + ret <3 x i8> %result +} + +; CHECK-LABEL: @store_64_to_48( +; CHECK: %result = load <3 x i16>, <3 x i16>* %cast, align 2 +; CHECK-NEXT: ret <3 x i16> %result +define <3 x i16> @store_64_to_48(i64 %value, i64* %ptr) { +entry: + store i64 %value, i64* %ptr, align 8 + %cast = bitcast i64* %ptr to <3 x i16>* + %result = load <3 x i16>, <3 x i16>* %cast, align 2 + ret <3 x i16> %result +} + +; Nonlocal availability must reject an illegal destination-width intermediate. +; +; CHECK-LABEL: @store_64_to_48_nonlocal( +; CHECK: exit: +; CHECK-NEXT: %result = load <3 x i16>, <3 x i16>* %cast, align 2 +; CHECK-NEXT: ret <3 x i16> %result +define <3 x i16> @store_64_to_48_nonlocal(i64 %a, i64 %b, i64* %ptr, + i1 %condition) { +entry: + %cast = bitcast i64* %ptr to <3 x i16>* + br i1 %condition, label %left, label %right + +left: + store i64 %a, i64* %ptr, align 8 + br label %exit + +right: + store i64 %b, i64* %ptr, align 8 + br label %exit + +exit: + %result = load <3 x i16>, <3 x i16>* %cast, align 2 + ret <3 x i16> %result +} + +; An equal-sized 48-bit vector-to-vector bitcast needs no scalar integer. +; +; CHECK-LABEL: @equal_size_48( +; CHECK: %[[CAST:.*]] = bitcast <3 x i16> %value to <6 x i8> +; CHECK-NOT: load +; CHECK: ret <6 x i8> %[[CAST]] +define <6 x i8> @equal_size_48(<3 x i16> %value, <3 x i16>* %ptr) { +entry: + store <3 x i16> %value, <3 x i16>* %ptr, align 2 + %cast = bitcast <3 x i16>* %ptr to <6 x i8>* + %result = load <6 x i8>, <6 x i8>* %cast, align 2 + ret <6 x i8> %result +} + +; Legal small-width extraction must still be optimized. +; +; CHECK-LABEL: @legal_16_to_8( +; CHECK: %[[LOW:.*]] = trunc i16 %value to i8 +; CHECK-NEXT: ret i8 %[[LOW]] +define i8 @legal_16_to_8(i16 %value, i16* %ptr) { +entry: + store i16 %value, i16* %ptr, align 2 + %cast = bitcast i16* %ptr to i8* + %result = load i8, i8* %cast, align 1 + ret i8 %result +} + +; Nonlocal load forwarding uses the same legality checks as store forwarding. +; +; CHECK-LABEL: @load_64_to_48_nonlocal( +; CHECK: exit: +; CHECK: %result = load <3 x i16>, <3 x i16>* %cast, align 2 +; CHECK: %pair = insertvalue { i64, <3 x i16> } %with.source, <3 x i16> %result, 1 +; CHECK-NEXT: ret { i64, <3 x i16> } %pair +define { i64, <3 x i16> } @load_64_to_48_nonlocal(i64* %ptr, i1 %condition) { +entry: + %cast = bitcast i64* %ptr to <3 x i16>* + br i1 %condition, label %left, label %right + +left: + %a = load i64, i64* %ptr, align 8 + br label %exit + +right: + %b = load i64, i64* %ptr, align 8 + br label %exit + +exit: + %source = phi i64 [ %a, %left ], [ %b, %right ] + %result = load <3 x i16>, <3 x i16>* %cast, align 2 + %with.source = insertvalue { i64, <3 x i16> } undef, i64 %source, 0 + %pair = insertvalue { i64, <3 x i16> } %with.source, <3 x i16> %result, 1 + ret { i64, <3 x i16> } %pair +} + +; Equal-sized nonlocal loads still need only a vector bitcast. +; +; CHECK-LABEL: @equal_size_48_load_nonlocal( +; CHECK: left: +; CHECK: %[[LEFT:.*]] = bitcast <3 x i16> %a to <6 x i8> +; CHECK: right: +; CHECK: %[[RIGHT:.*]] = bitcast <3 x i16> %b to <6 x i8> +; CHECK: exit: +; CHECK: %result = phi <6 x i8> [ %[[LEFT]], %left ], [ %[[RIGHT]], %right ] +; CHECK-NOT: load +; CHECK: %pair = insertvalue { <3 x i16>, <6 x i8> } %with.source, <6 x i8> %result, 1 +; CHECK-NEXT: ret { <3 x i16>, <6 x i8> } %pair +define { <3 x i16>, <6 x i8> } @equal_size_48_load_nonlocal( + <3 x i16>* %ptr, i1 %condition) { +entry: + %cast = bitcast <3 x i16>* %ptr to <6 x i8>* + br i1 %condition, label %left, label %right + +left: + %a = load <3 x i16>, <3 x i16>* %ptr, align 2 + br label %exit + +right: + %b = load <3 x i16>, <3 x i16>* %ptr, align 2 + br label %exit + +exit: + %source = phi <3 x i16> [ %a, %left ], [ %b, %right ] + %result = load <6 x i8>, <6 x i8>* %cast, align 2 + %with.source = insertvalue { <3 x i16>, <6 x i8> } undef, <3 x i16> %source, 0 + %pair = insertvalue { <3 x i16>, <6 x i8> } %with.source, <6 x i8> %result, 1 + ret { <3 x i16>, <6 x i8> } %pair +} + +; Equal byte sizes do not imply equal bit sizes: i8 to i1 still needs a trunc. +; +; CHECK-LABEL: @legal_8_to_1_nonlocal( +; CHECK: left: +; CHECK: %[[LEFT:.*]] = trunc i8 %a to i1 +; CHECK: right: +; CHECK: %[[RIGHT:.*]] = trunc i8 %b to i1 +; CHECK: exit: +; CHECK-NEXT: %result = phi i1 [ %[[RIGHT]], %right ], [ %[[LEFT]], %left ] +; CHECK-NEXT: ret i1 %result +define i1 @legal_8_to_1_nonlocal(i8 %a, i8 %b, i8* %ptr, i1 %condition) { +entry: + %cast = bitcast i8* %ptr to i1* + br i1 %condition, label %left, label %right + +left: + store i8 %a, i8* %ptr, align 1 + br label %exit + +right: + store i8 %b, i8* %ptr, align 1 + br label %exit + +exit: + %result = load i1, i1* %cast, align 1 + ret i1 %result +} From dae1031031abd05f0ce51f1402ee740865a67560 Mon Sep 17 00:00:00 2001 From: Chris B Date: Sun, 18 Oct 2026 11:41:21 -0500 Subject: [PATCH 2/3] Fix various issues in ReleaseNotes Fixed issues related to GVN load forwarding, shader reflection, and optimizer crashes. Co-authored-by: Copilot Autofix powered by AI <175728472+Copilot@users.noreply.github.com> --- docs/ReleaseNotes.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/docs/ReleaseNotes.md b/docs/ReleaseNotes.md index e38c8f4c72..cdb070d492 100644 --- a/docs/ReleaseNotes.md +++ b/docs/ReleaseNotes.md @@ -82,7 +82,7 @@ line upon naming the release. Refer to previous for appropriate section names. - Fixed GVN load forwarding generating unsupported integer types when optimizing native vectors - [#8940](https://github.com/microsoft/DirectXShaderCompiler/issues/9040). + [#9040](https://github.com/microsoft/DirectXShaderCompiler/issues/9040). - Fixed shader reflection dropping leading characters from user-defined struct type names. - Fixed an optimizer crash when scalarizing an out-of-bounds vector access [#8940](https://github.com/microsoft/DirectXShaderCompiler/issues/8940). From 5f9ab598c3b685b1ce200e5fe67c68c98af6d84b Mon Sep 17 00:00:00 2001 From: Chris Bieneman Date: Mon, 19 Oct 2026 16:22:12 -0500 Subject: [PATCH 3/3] clang-format --- lib/Transforms/Scalar/GVN.cpp | 4 +--- 1 file changed, 1 insertion(+), 3 deletions(-) diff --git a/lib/Transforms/Scalar/GVN.cpp b/lib/Transforms/Scalar/GVN.cpp index 88fa8f90d3..12e848fb58 100644 --- a/lib/Transforms/Scalar/GVN.cpp +++ b/lib/Transforms/Scalar/GVN.cpp @@ -841,7 +841,6 @@ static bool IsValueFullyAvailableInBlock(BasicBlock *BB, return false; } - // HLSL Change Begin - DXIL only supports these integer widths. static bool IsValidDxilIntegerWidth(uint64_t Width) { switch (Width) { @@ -882,8 +881,7 @@ static bool CanCoerceMustAliasedValueToLoad(Value *StoredVal, uint64_t StoredValBits = DL.getTypeSizeInBits(StoredValTy); uint64_t LoadBits = DL.getTypeSizeInBits(LoadTy); if (StoredValBits != LoadBits) { - if (!StoredValTy->isIntegerTy() && - !IsValidDxilIntegerWidth(StoredValBits)) + if (!StoredValTy->isIntegerTy() && !IsValidDxilIntegerWidth(StoredValBits)) return false; if (!IsValidDxilIntegerWidth(LoadBits)) return false;