mirror of
https://github.com/electron/electron.git
synced 2026-04-10 03:01:51 -04:00
chore: [29-x-y] cherry-pick 7 changes from 3-M125 (#42589)
This commit is contained in:
@@ -3,3 +3,5 @@ cherry-pick-bc18aec94c82.patch
|
||||
cherry-pick-bd7aa9779873.patch
|
||||
cherry-pick-2a434fd0af6b.patch
|
||||
cherry-pick-867c1001637e.patch
|
||||
cherry-pick-0b785e88fefa.patch
|
||||
cherry-pick-511cfef8e050.patch
|
||||
|
||||
523
patches/DirectXShaderCompiler/cherry-pick-0b785e88fefa.patch
Normal file
523
patches/DirectXShaderCompiler/cherry-pick-0b785e88fefa.patch
Normal file
@@ -0,0 +1,523 @@
|
||||
From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001
|
||||
From: Antonio Maiorano <amaiorano@google.com>
|
||||
Date: Fri, 24 May 2024 15:51:26 -0400
|
||||
Subject: Fix dxil-remove-dead-blocks removing switch with multiple same
|
||||
successor (#6610)
|
||||
|
||||
Given a switch with a constant condition and all cases the same
|
||||
(branching to the same successor), dxil-remove-dead-blocks would
|
||||
incorrectly remove the switch when replacing it with a branch, by
|
||||
forgetting to remove the N-1 incoming values to the PHIs in the
|
||||
successor block.
|
||||
|
||||
Bug: chromium:338071106
|
||||
Change-Id: Iaa2c42642f3e370afd19d88c96c81056c16349b6
|
||||
Reviewed-on: https://chromium-review.googlesource.com/c/external/github.com/microsoft/DirectXShaderCompiler/+/5570270
|
||||
Reviewed-by: Ben Clayton <bclayton@chromium.org>
|
||||
Reviewed-by: James Price <jrprice@google.com>
|
||||
|
||||
diff --git a/lib/Transforms/Scalar/DxilRemoveDeadBlocks.cpp b/lib/Transforms/Scalar/DxilRemoveDeadBlocks.cpp
|
||||
index 54308eed2e018903e518be4a5ff809e080be78c0..9a87f4e6740c8da0522c6bf00f2a365f838cb3c0 100644
|
||||
--- a/lib/Transforms/Scalar/DxilRemoveDeadBlocks.cpp
|
||||
+++ b/lib/Transforms/Scalar/DxilRemoveDeadBlocks.cpp
|
||||
@@ -35,6 +35,7 @@
|
||||
using namespace llvm;
|
||||
using namespace hlsl;
|
||||
|
||||
+// Removes BB from PHI nodes in SuccBB, deleting the PHI nodes if empty.
|
||||
static void RemoveIncomingValueFrom(BasicBlock *SuccBB, BasicBlock *BB) {
|
||||
for (auto inst_it = SuccBB->begin(); inst_it != SuccBB->end();) {
|
||||
Instruction *I = &*(inst_it++);
|
||||
@@ -105,6 +106,8 @@ bool DeadBlockDeleter::Run(Function &F, DxilValueCache *DVC) {
|
||||
} else if (SwitchInst *Switch = dyn_cast<SwitchInst>(BB->getTerminator())) {
|
||||
Value *Cond = Switch->getCondition();
|
||||
BasicBlock *Succ = nullptr;
|
||||
+ // If the condition to Switch is constant, replace Switch with a branch
|
||||
+ // to the current case successor.
|
||||
if (ConstantInt *ConstCond = DVC->GetConstInt(Cond)) {
|
||||
Succ = hlsl::dxilutil::GetSwitchSuccessorForCond(Switch, ConstCond);
|
||||
}
|
||||
@@ -112,16 +115,32 @@ bool DeadBlockDeleter::Run(Function &F, DxilValueCache *DVC) {
|
||||
if (Succ) {
|
||||
Add(Succ);
|
||||
|
||||
+ // Create branch from BB to Succ that will replace Switch.
|
||||
+ // This adds BB to preds of Succ.
|
||||
BranchInst *NewBr = BranchInst::Create(Succ, BB);
|
||||
hlsl::DxilMDHelper::CopyMetadata(*NewBr, *Switch);
|
||||
|
||||
+ // For any successors we're not going to, remove incoming block BB from
|
||||
+ // PHI nodes in those successors.
|
||||
+ unsigned numSucc = 0;
|
||||
for (unsigned i = 0; i < Switch->getNumSuccessors(); i++) {
|
||||
BasicBlock *NotSucc = Switch->getSuccessor(i);
|
||||
- if (NotSucc != Succ) {
|
||||
+ if (NotSucc != Succ)
|
||||
RemoveIncomingValueFrom(NotSucc, BB);
|
||||
- }
|
||||
+ else
|
||||
+ ++numSucc;
|
||||
+ }
|
||||
+
|
||||
+ // We're replacing Switch with a single unconditional branch. If Switch
|
||||
+ // has N cases with the same Succ, we need to remove N-1 incoming values
|
||||
+ // of BB from the PHI nodes in Succ. This ensures that the preds of Succ
|
||||
+ // match the ones in its PHIs.
|
||||
+ for (unsigned i = 1; i < numSucc; i++) {
|
||||
+ RemoveIncomingValueFrom(Succ, BB);
|
||||
}
|
||||
|
||||
+ // Finally, erase Switch, which will remove BB as pred from all
|
||||
+ // successors.
|
||||
Switch->eraseFromParent();
|
||||
Switch = nullptr;
|
||||
Changed = true;
|
||||
diff --git a/tools/clang/test/DXC/Passes/DxilRemoveDeadBlocks/switch-with-multiple-same-successor.hlsl b/tools/clang/test/DXC/Passes/DxilRemoveDeadBlocks/switch-with-multiple-same-successor.hlsl
|
||||
new file mode 100644
|
||||
index 0000000000000000000000000000000000000000..43c3510b2ce18b15ff74a0db4697898da807f49f
|
||||
--- /dev/null
|
||||
+++ b/tools/clang/test/DXC/Passes/DxilRemoveDeadBlocks/switch-with-multiple-same-successor.hlsl
|
||||
@@ -0,0 +1,68 @@
|
||||
+// Test switch with multiple same successors
|
||||
+// RUN: %dxc -T ps_6_6 %s | FileCheck %s
|
||||
+
|
||||
+// This test used to fail with validation errors:
|
||||
+//
|
||||
+// error: validation errors
|
||||
+// error: Module bitcode is invalid.
|
||||
+// error: PHINode should have one entry for each predecessor of its parent basic block!
|
||||
+// %22 = phi i32 [ 1, %20 ], [ 1, %20 ], [ 1, %20 ], [ 1, %20 ], [ %11, %13 ]
|
||||
+// PHINode should have one entry for each predecessor of its parent basic block!
|
||||
+// %28 = phi i32 [ 1, %26 ], [ 1, %26 ], [ 1, %26 ], [ 1, %26 ], [ %22, %24 ]
|
||||
+// PHINode should have one entry for each predecessor of its parent basic block!
|
||||
+// %34 = phi i32 [ 1, %32 ], [ 1, %32 ], [ 1, %32 ], [ 1, %32 ], [ %28, %30 ]
|
||||
+// PHINode should have one entry for each predecessor of its parent basic block!
|
||||
+// %47 = phi i32 [ 1, %45 ], [ 1, %45 ], [ 1, %45 ], [ 1, %45 ], [ %41, %43 ]
|
||||
+//
|
||||
+// This was fixed in dxil-remove-dead-blocks. See switch-with-multiple-same-successor.ll
|
||||
+// for the pass-specific checks. Here, we just want to make sure dxc compiles this without error.
|
||||
+
|
||||
+// CHECK: @main
|
||||
+
|
||||
+ByteAddressBuffer g_buff : register(t0);
|
||||
+
|
||||
+struct retval {
|
||||
+ float4 value : SV_Target0;
|
||||
+};
|
||||
+
|
||||
+retval main() {
|
||||
+ float4 g = asfloat(g_buff.Load4(0u));
|
||||
+ bool do_discard = false;
|
||||
+
|
||||
+ for (int i = 0; i < 10; ++i) {
|
||||
+ if (g.x != 0.0f)
|
||||
+ continue;
|
||||
+
|
||||
+ // Switch with the same successor in all cases
|
||||
+ switch(i) {
|
||||
+ case 1: {
|
||||
+ g.x = g.x;
|
||||
+ break;
|
||||
+ }
|
||||
+ case 2: {
|
||||
+ g.x = g.x;
|
||||
+ break;
|
||||
+ }
|
||||
+ case 3: {
|
||||
+ g.x = g.x;
|
||||
+ break;
|
||||
+ }
|
||||
+ // Skip 'case 4' to avoid case range combining
|
||||
+ case 5: {
|
||||
+ g.x = g.x;
|
||||
+ break;
|
||||
+ }
|
||||
+ }
|
||||
+ if (i == 6) {
|
||||
+ break;
|
||||
+ }
|
||||
+ g.x = atan2(1.0f, g.x);
|
||||
+ do_discard = true;
|
||||
+ }
|
||||
+
|
||||
+ if (do_discard) {
|
||||
+ discard;
|
||||
+ }
|
||||
+
|
||||
+ return (retval)0;
|
||||
+}
|
||||
diff --git a/tools/clang/test/DXC/Passes/DxilRemoveDeadBlocks/switch-with-multiple-same-successor.ll b/tools/clang/test/DXC/Passes/DxilRemoveDeadBlocks/switch-with-multiple-same-successor.ll
|
||||
new file mode 100644
|
||||
index 0000000000000000000000000000000000000000..d3e7e2f1e40c816c4ed28bfc45a1569e130f472c
|
||||
--- /dev/null
|
||||
+++ b/tools/clang/test/DXC/Passes/DxilRemoveDeadBlocks/switch-with-multiple-same-successor.ll
|
||||
@@ -0,0 +1,369 @@
|
||||
+; RUN: %dxopt %s -hlsl-passes-resume -dxil-remove-dead-blocks -S | FileCheck %s
|
||||
+
|
||||
+; Validate that a switch with a constant condition and multiple of the same successor
|
||||
+; is correctly removed, ensuring that PHIs in the successor are properly updated.
|
||||
+; For instance, in:
|
||||
+;
|
||||
+;
|
||||
+; if.end.1: ; preds = %for.inc
|
||||
+; switch i32 1, label %sw.epilog.1 [
|
||||
+; i32 1, label %dx.struct_exit.new_exiting.1
|
||||
+; i32 2, label %dx.struct_exit.new_exiting.1
|
||||
+; i32 3, label %dx.struct_exit.new_exiting.1
|
||||
+; i32 5, label %dx.struct_exit.new_exiting.1
|
||||
+; ], !dbg !31 ; line:23 col:5
|
||||
+;
|
||||
+; sw.epilog.1: ; preds = %if.end.1
|
||||
+; br label %dx.struct_exit.new_exiting.1
|
||||
+;
|
||||
+; dx.struct_exit.new_exiting.1: ; preds = %sw.epilog.1, %if.end.1, %if.end.1, %if.end.1, %if.end.1, %for.inc
|
||||
+; %dx.struct_exit.prop.1 = phi i32 [ %do_discard.2, %sw.epilog.1 ], [ 0, %if.end.1 ], [ 0, %if.end.1 ], [ 0, %if.end.1 ], [ 0, %if.end.1 ], [ 0, %for.inc ]
|
||||
+; %do_discard.2.1 = phi i32 [ 1, %sw.epilog.1 ], [ 1, %if.end.1 ], [ 1, %if.end.1 ], [ 1, %if.end.1 ], [ 1, %if.end.1 ], [ %do_discard.2, %for.inc ]
|
||||
+; %g.2.i0.1 = phi float [ 0x3FF921FB60000000, %sw.epilog.1 ], [ 0x3FF921FB60000000, %if.end.1 ], [ 0x3FF921FB60000000, %if.end.1 ], [ 0x3FF921FB60000000, %if.end.1 ], [ 0x3FF921FB60000000, %if.end.1 ], [ %g.2.i0, %for.inc ]
|
||||
+; br i1 false, label %cleanup, label %for.inc.1
|
||||
+;
|
||||
+;
|
||||
+; After dxil-remove-dead-blocks, the multiple `%if.end.1` in preds and in the two phi instructions should be removed,
|
||||
+; and only one instance should be left.
|
||||
+
|
||||
+; CHECK: if.end.1: ; preds = %for.inc
|
||||
+; CHECK-NEXT: br label %dx.struct_exit.new_exiting.1
|
||||
+
|
||||
+; CHECK: dx.struct_exit.new_exiting.1: ; preds = %if.end.1, %for.inc
|
||||
+; CHECK-NEXT: %do_discard.2.1 = phi i32 [ 1, %if.end.1 ], [ %do_discard.2, %for.inc ]
|
||||
+; CHECK-NEXT: %g.2.i0.1 = phi float [ 0x3FF921FB60000000, %if.end.1 ], [ %g.2.i0, %for.inc ]
|
||||
+
|
||||
+;
|
||||
+; Output signature:
|
||||
+;
|
||||
+; Name Index InterpMode DynIdx
|
||||
+; -------------------- ----- ---------------------- ------
|
||||
+; SV_Target 0
|
||||
+;
|
||||
+; Buffer Definitions:
|
||||
+;
|
||||
+;
|
||||
+; Resource Bindings:
|
||||
+;
|
||||
+; Name Type Format Dim ID HLSL Bind Count
|
||||
+; ------------------------------ ---------- ------- ----------- ------- -------------- ------
|
||||
+; g_buff texture byte r/o T0 t0 1
|
||||
+;
|
||||
+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"
|
||||
+
|
||||
+%struct.ByteAddressBuffer = type { i32 }
|
||||
+%dx.types.Handle = type { i8* }
|
||||
+%dx.types.ResourceProperties = type { i32, i32 }
|
||||
+%dx.types.ResRet.i32 = type { i32, i32, i32, i32, i32 }
|
||||
+%struct.retval = type { <4 x float> }
|
||||
+
|
||||
+@"\01?g_buff@@3UByteAddressBuffer@@A" = external global %struct.ByteAddressBuffer, align 4
|
||||
+@llvm.used = appending global [1 x i8*] [i8* bitcast (%struct.ByteAddressBuffer* @"\01?g_buff@@3UByteAddressBuffer@@A" to i8*)], section "llvm.metadata"
|
||||
+
|
||||
+; Function Attrs: nounwind
|
||||
+define void @main(<4 x float>* noalias nocapture readnone) #0 {
|
||||
+for.body.lr.ph:
|
||||
+ %1 = load %struct.ByteAddressBuffer, %struct.ByteAddressBuffer* @"\01?g_buff@@3UByteAddressBuffer@@A", align 4, !dbg !23 ; line:15 col:22
|
||||
+ %2 = call %dx.types.Handle @dx.op.createHandleForLib.struct.ByteAddressBuffer(i32 160, %struct.ByteAddressBuffer %1), !dbg !23 ; line:15 col:22 ; CreateHandleForLib(Resource)
|
||||
+ %3 = call %dx.types.Handle @dx.op.annotateHandle(i32 216, %dx.types.Handle %2, %dx.types.ResourceProperties { i32 11, i32 0 }), !dbg !23 ; line:15 col:22 ; AnnotateHandle(res,props) resource: ByteAddressBuffer
|
||||
+ %RawBufferLoad = call %dx.types.ResRet.i32 @dx.op.rawBufferLoad.i32(i32 139, %dx.types.Handle %3, i32 0, i32 undef, i8 15, i32 4), !dbg !23 ; line:15 col:22 ; RawBufferLoad(srv,index,elementOffset,mask,alignment)
|
||||
+ %4 = extractvalue %dx.types.ResRet.i32 %RawBufferLoad, 0, !dbg !23 ; line:15 col:22
|
||||
+ %.i0 = bitcast i32 %4 to float, !dbg !27 ; line:15 col:14
|
||||
+ br label %for.body, !dbg !28 ; line:18 col:3
|
||||
+
|
||||
+for.body: ; preds = %for.body.lr.ph
|
||||
+ %cmp3 = fcmp fast une float %.i0, 0.000000e+00, !dbg !29 ; line:19 col:13
|
||||
+ br i1 %cmp3, label %dx.struct_exit.new_exiting, label %if.end, !dbg !30 ; line:19 col:9
|
||||
+
|
||||
+if.end: ; preds = %for.body
|
||||
+ switch i32 0, label %sw.epilog [
|
||||
+ i32 1, label %dx.struct_exit.new_exiting
|
||||
+ i32 2, label %dx.struct_exit.new_exiting
|
||||
+ i32 3, label %dx.struct_exit.new_exiting
|
||||
+ i32 5, label %dx.struct_exit.new_exiting
|
||||
+ ], !dbg !31 ; line:23 col:5
|
||||
+
|
||||
+sw.epilog: ; preds = %if.end
|
||||
+ br label %dx.struct_exit.new_exiting
|
||||
+
|
||||
+dx.struct_exit.new_exiting: ; preds = %sw.epilog, %if.end, %if.end, %if.end, %if.end, %for.body
|
||||
+ %do_discard.2 = phi i32 [ 0, %for.body ], [ 1, %if.end ], [ 1, %if.end ], [ 1, %if.end ], [ 1, %if.end ], [ 1, %sw.epilog ]
|
||||
+ %g.2.i0 = phi float [ %.i0, %for.body ], [ 0x3FF921FB60000000, %if.end ], [ 0x3FF921FB60000000, %if.end ], [ 0x3FF921FB60000000, %if.end ], [ 0x3FF921FB60000000, %if.end ], [ 0x3FF921FB60000000, %sw.epilog ]
|
||||
+ br i1 false, label %cleanup, label %for.inc
|
||||
+
|
||||
+for.inc: ; preds = %dx.struct_exit.new_exiting
|
||||
+ %cmp3.1 = fcmp fast une float %g.2.i0, 0.000000e+00, !dbg !29 ; line:19 col:13
|
||||
+ br i1 %cmp3.1, label %dx.struct_exit.new_exiting.1, label %if.end.1, !dbg !30 ; line:19 col:9
|
||||
+
|
||||
+cleanup: ; preds = %for.inc.9, %dx.struct_exit.new_exiting.9, %dx.struct_exit.new_exiting.8, %dx.struct_exit.new_exiting.7, %dx.struct_exit.new_exiting.6, %dx.struct_exit.new_exiting.5, %dx.struct_exit.new_exiting.4, %dx.struct_exit.new_exiting.3, %dx.struct_exit.new_exiting.2, %dx.struct_exit.new_exiting.1, %dx.struct_exit.new_exiting
|
||||
+ %do_discard.3 = phi i32 [ 0, %dx.struct_exit.new_exiting ], [ %dx.struct_exit.prop.1, %dx.struct_exit.new_exiting.1 ], [ %dx.struct_exit.prop.2, %dx.struct_exit.new_exiting.2 ], [ %dx.struct_exit.prop.3, %dx.struct_exit.new_exiting.3 ], [ %dx.struct_exit.prop.4, %dx.struct_exit.new_exiting.4 ], [ %dx.struct_exit.prop.5, %dx.struct_exit.new_exiting.5 ], [ %dx.struct_exit.prop.6, %dx.struct_exit.new_exiting.6 ], [ %dx.struct_exit.prop.7, %dx.struct_exit.new_exiting.7 ], [ %dx.struct_exit.prop.8, %dx.struct_exit.new_exiting.8 ], [ %dx.struct_exit.prop.9, %dx.struct_exit.new_exiting.9 ], [ %do_discard.2.9, %for.inc.9 ]
|
||||
+ %tobool15 = icmp eq i32 %do_discard.3, 0, !dbg !32 ; line:49 col:7
|
||||
+ br i1 %tobool15, label %if.end.17, label %if.then.16, !dbg !32 ; line:49 col:7
|
||||
+
|
||||
+if.then.16: ; preds = %cleanup
|
||||
+ call void @dx.op.discard(i32 82, i1 true), !dbg !33 ; line:49 col:19 ; Discard(condition)
|
||||
+ br label %if.end.17, !dbg !34 ; line:51 col:3
|
||||
+
|
||||
+if.end.17: ; preds = %cleanup, %if.then.16
|
||||
+ call void @dx.op.storeOutput.f32(i32 5, i32 0, i32 0, i8 0, float 0.000000e+00), !dbg !35 ; line:53 col:18 ; StoreOutput(outputSigId,rowIndex,colIndex,value)
|
||||
+ call void @dx.op.storeOutput.f32(i32 5, i32 0, i32 0, i8 1, float 0.000000e+00), !dbg !35 ; line:53 col:18 ; StoreOutput(outputSigId,rowIndex,colIndex,value)
|
||||
+ call void @dx.op.storeOutput.f32(i32 5, i32 0, i32 0, i8 2, float 0.000000e+00), !dbg !35 ; line:53 col:18 ; StoreOutput(outputSigId,rowIndex,colIndex,value)
|
||||
+ call void @dx.op.storeOutput.f32(i32 5, i32 0, i32 0, i8 3, float 0.000000e+00), !dbg !35 ; line:53 col:18 ; StoreOutput(outputSigId,rowIndex,colIndex,value)
|
||||
+ ret void, !dbg !36 ; line:54 col:1
|
||||
+
|
||||
+if.end.1: ; preds = %for.inc
|
||||
+ switch i32 1, label %sw.epilog.1 [
|
||||
+ i32 1, label %dx.struct_exit.new_exiting.1
|
||||
+ i32 2, label %dx.struct_exit.new_exiting.1
|
||||
+ i32 3, label %dx.struct_exit.new_exiting.1
|
||||
+ i32 5, label %dx.struct_exit.new_exiting.1
|
||||
+ ], !dbg !31 ; line:23 col:5
|
||||
+
|
||||
+sw.epilog.1: ; preds = %if.end.1
|
||||
+ br label %dx.struct_exit.new_exiting.1
|
||||
+
|
||||
+dx.struct_exit.new_exiting.1: ; preds = %sw.epilog.1, %if.end.1, %if.end.1, %if.end.1, %if.end.1, %for.inc
|
||||
+ %dx.struct_exit.prop.1 = phi i32 [ %do_discard.2, %sw.epilog.1 ], [ 0, %if.end.1 ], [ 0, %if.end.1 ], [ 0, %if.end.1 ], [ 0, %if.end.1 ], [ 0, %for.inc ]
|
||||
+ %do_discard.2.1 = phi i32 [ 1, %sw.epilog.1 ], [ 1, %if.end.1 ], [ 1, %if.end.1 ], [ 1, %if.end.1 ], [ 1, %if.end.1 ], [ %do_discard.2, %for.inc ]
|
||||
+ %g.2.i0.1 = phi float [ 0x3FF921FB60000000, %sw.epilog.1 ], [ 0x3FF921FB60000000, %if.end.1 ], [ 0x3FF921FB60000000, %if.end.1 ], [ 0x3FF921FB60000000, %if.end.1 ], [ 0x3FF921FB60000000, %if.end.1 ], [ %g.2.i0, %for.inc ]
|
||||
+ br i1 false, label %cleanup, label %for.inc.1
|
||||
+
|
||||
+for.inc.1: ; preds = %dx.struct_exit.new_exiting.1
|
||||
+ %cmp3.2 = fcmp fast une float %g.2.i0.1, 0.000000e+00, !dbg !29 ; line:19 col:13
|
||||
+ br i1 %cmp3.2, label %dx.struct_exit.new_exiting.2, label %if.end.2, !dbg !30 ; line:19 col:9
|
||||
+
|
||||
+if.end.2: ; preds = %for.inc.1
|
||||
+ switch i32 2, label %sw.epilog.2 [
|
||||
+ i32 1, label %dx.struct_exit.new_exiting.2
|
||||
+ i32 2, label %dx.struct_exit.new_exiting.2
|
||||
+ i32 3, label %dx.struct_exit.new_exiting.2
|
||||
+ i32 5, label %dx.struct_exit.new_exiting.2
|
||||
+ ], !dbg !31 ; line:23 col:5
|
||||
+
|
||||
+sw.epilog.2: ; preds = %if.end.2
|
||||
+ br label %dx.struct_exit.new_exiting.2
|
||||
+
|
||||
+dx.struct_exit.new_exiting.2: ; preds = %sw.epilog.2, %if.end.2, %if.end.2, %if.end.2, %if.end.2, %for.inc.1
|
||||
+ %dx.struct_exit.prop.2 = phi i32 [ %do_discard.2.1, %sw.epilog.2 ], [ 0, %if.end.2 ], [ 0, %if.end.2 ], [ 0, %if.end.2 ], [ 0, %if.end.2 ], [ 0, %for.inc.1 ]
|
||||
+ %do_discard.2.2 = phi i32 [ 1, %sw.epilog.2 ], [ 1, %if.end.2 ], [ 1, %if.end.2 ], [ 1, %if.end.2 ], [ 1, %if.end.2 ], [ %do_discard.2.1, %for.inc.1 ]
|
||||
+ %g.2.i0.2 = phi float [ 0x3FF921FB60000000, %sw.epilog.2 ], [ 0x3FF921FB60000000, %if.end.2 ], [ 0x3FF921FB60000000, %if.end.2 ], [ 0x3FF921FB60000000, %if.end.2 ], [ 0x3FF921FB60000000, %if.end.2 ], [ %g.2.i0.1, %for.inc.1 ]
|
||||
+ br i1 false, label %cleanup, label %for.inc.2
|
||||
+
|
||||
+for.inc.2: ; preds = %dx.struct_exit.new_exiting.2
|
||||
+ %cmp3.3 = fcmp fast une float %g.2.i0.2, 0.000000e+00, !dbg !29 ; line:19 col:13
|
||||
+ br i1 %cmp3.3, label %dx.struct_exit.new_exiting.3, label %if.end.3, !dbg !30 ; line:19 col:9
|
||||
+
|
||||
+if.end.3: ; preds = %for.inc.2
|
||||
+ switch i32 3, label %sw.epilog.3 [
|
||||
+ i32 1, label %dx.struct_exit.new_exiting.3
|
||||
+ i32 2, label %dx.struct_exit.new_exiting.3
|
||||
+ i32 3, label %dx.struct_exit.new_exiting.3
|
||||
+ i32 5, label %dx.struct_exit.new_exiting.3
|
||||
+ ], !dbg !31 ; line:23 col:5
|
||||
+
|
||||
+sw.epilog.3: ; preds = %if.end.3
|
||||
+ br label %dx.struct_exit.new_exiting.3
|
||||
+
|
||||
+dx.struct_exit.new_exiting.3: ; preds = %sw.epilog.3, %if.end.3, %if.end.3, %if.end.3, %if.end.3, %for.inc.2
|
||||
+ %dx.struct_exit.prop.3 = phi i32 [ %do_discard.2.2, %sw.epilog.3 ], [ 0, %if.end.3 ], [ 0, %if.end.3 ], [ 0, %if.end.3 ], [ 0, %if.end.3 ], [ 0, %for.inc.2 ]
|
||||
+ %do_discard.2.3 = phi i32 [ 1, %sw.epilog.3 ], [ 1, %if.end.3 ], [ 1, %if.end.3 ], [ 1, %if.end.3 ], [ 1, %if.end.3 ], [ %do_discard.2.2, %for.inc.2 ]
|
||||
+ %g.2.i0.3 = phi float [ 0x3FF921FB60000000, %sw.epilog.3 ], [ 0x3FF921FB60000000, %if.end.3 ], [ 0x3FF921FB60000000, %if.end.3 ], [ 0x3FF921FB60000000, %if.end.3 ], [ 0x3FF921FB60000000, %if.end.3 ], [ %g.2.i0.2, %for.inc.2 ]
|
||||
+ br i1 false, label %cleanup, label %for.inc.3
|
||||
+
|
||||
+for.inc.3: ; preds = %dx.struct_exit.new_exiting.3
|
||||
+ %cmp3.4 = fcmp fast une float %g.2.i0.3, 0.000000e+00, !dbg !29 ; line:19 col:13
|
||||
+ br i1 %cmp3.4, label %dx.struct_exit.new_exiting.4, label %if.end.4, !dbg !30 ; line:19 col:9
|
||||
+
|
||||
+if.end.4: ; preds = %for.inc.3
|
||||
+ switch i32 4, label %sw.epilog.4 [
|
||||
+ i32 1, label %dx.struct_exit.new_exiting.4
|
||||
+ i32 2, label %dx.struct_exit.new_exiting.4
|
||||
+ i32 3, label %dx.struct_exit.new_exiting.4
|
||||
+ i32 5, label %dx.struct_exit.new_exiting.4
|
||||
+ ], !dbg !31 ; line:23 col:5
|
||||
+
|
||||
+sw.epilog.4: ; preds = %if.end.4
|
||||
+ br label %dx.struct_exit.new_exiting.4
|
||||
+
|
||||
+dx.struct_exit.new_exiting.4: ; preds = %sw.epilog.4, %if.end.4, %if.end.4, %if.end.4, %if.end.4, %for.inc.3
|
||||
+ %dx.struct_exit.prop.4 = phi i32 [ %do_discard.2.3, %sw.epilog.4 ], [ 0, %if.end.4 ], [ 0, %if.end.4 ], [ 0, %if.end.4 ], [ 0, %if.end.4 ], [ 0, %for.inc.3 ]
|
||||
+ %do_discard.2.4 = phi i32 [ 1, %sw.epilog.4 ], [ 1, %if.end.4 ], [ 1, %if.end.4 ], [ 1, %if.end.4 ], [ 1, %if.end.4 ], [ %do_discard.2.3, %for.inc.3 ]
|
||||
+ %g.2.i0.4 = phi float [ 0x3FF921FB60000000, %sw.epilog.4 ], [ 0x3FF921FB60000000, %if.end.4 ], [ 0x3FF921FB60000000, %if.end.4 ], [ 0x3FF921FB60000000, %if.end.4 ], [ 0x3FF921FB60000000, %if.end.4 ], [ %g.2.i0.3, %for.inc.3 ]
|
||||
+ br i1 false, label %cleanup, label %for.inc.4
|
||||
+
|
||||
+for.inc.4: ; preds = %dx.struct_exit.new_exiting.4
|
||||
+ %cmp3.5 = fcmp fast une float %g.2.i0.4, 0.000000e+00, !dbg !29 ; line:19 col:13
|
||||
+ br i1 %cmp3.5, label %dx.struct_exit.new_exiting.5, label %if.end.5, !dbg !30 ; line:19 col:9
|
||||
+
|
||||
+if.end.5: ; preds = %for.inc.4
|
||||
+ switch i32 5, label %sw.epilog.5 [
|
||||
+ i32 1, label %dx.struct_exit.new_exiting.5
|
||||
+ i32 2, label %dx.struct_exit.new_exiting.5
|
||||
+ i32 3, label %dx.struct_exit.new_exiting.5
|
||||
+ i32 5, label %dx.struct_exit.new_exiting.5
|
||||
+ ], !dbg !31 ; line:23 col:5
|
||||
+
|
||||
+sw.epilog.5: ; preds = %if.end.5
|
||||
+ br label %dx.struct_exit.new_exiting.5
|
||||
+
|
||||
+dx.struct_exit.new_exiting.5: ; preds = %sw.epilog.5, %if.end.5, %if.end.5, %if.end.5, %if.end.5, %for.inc.4
|
||||
+ %dx.struct_exit.prop.5 = phi i32 [ %do_discard.2.4, %sw.epilog.5 ], [ 0, %if.end.5 ], [ 0, %if.end.5 ], [ 0, %if.end.5 ], [ 0, %if.end.5 ], [ 0, %for.inc.4 ]
|
||||
+ %do_discard.2.5 = phi i32 [ 1, %sw.epilog.5 ], [ 1, %if.end.5 ], [ 1, %if.end.5 ], [ 1, %if.end.5 ], [ 1, %if.end.5 ], [ %do_discard.2.4, %for.inc.4 ]
|
||||
+ %g.2.i0.5 = phi float [ 0x3FF921FB60000000, %sw.epilog.5 ], [ 0x3FF921FB60000000, %if.end.5 ], [ 0x3FF921FB60000000, %if.end.5 ], [ 0x3FF921FB60000000, %if.end.5 ], [ 0x3FF921FB60000000, %if.end.5 ], [ %g.2.i0.4, %for.inc.4 ]
|
||||
+ br i1 false, label %cleanup, label %for.inc.5
|
||||
+
|
||||
+for.inc.5: ; preds = %dx.struct_exit.new_exiting.5
|
||||
+ %cmp3.6 = fcmp fast une float %g.2.i0.5, 0.000000e+00, !dbg !29 ; line:19 col:13
|
||||
+ br i1 %cmp3.6, label %dx.struct_exit.new_exiting.6, label %if.end.6, !dbg !30 ; line:19 col:9
|
||||
+
|
||||
+if.end.6: ; preds = %for.inc.5
|
||||
+ switch i32 6, label %sw.epilog.6 [
|
||||
+ i32 1, label %dx.struct_exit.new_exiting.6
|
||||
+ i32 2, label %dx.struct_exit.new_exiting.6
|
||||
+ i32 3, label %dx.struct_exit.new_exiting.6
|
||||
+ i32 5, label %dx.struct_exit.new_exiting.6
|
||||
+ ], !dbg !31 ; line:23 col:5
|
||||
+
|
||||
+sw.epilog.6: ; preds = %if.end.6
|
||||
+ br label %dx.struct_exit.new_exiting.6
|
||||
+
|
||||
+dx.struct_exit.new_exiting.6: ; preds = %sw.epilog.6, %if.end.6, %if.end.6, %if.end.6, %if.end.6, %for.inc.5
|
||||
+ %dx.struct_exit.prop23.6 = phi i1 [ true, %sw.epilog.6 ], [ false, %if.end.6 ], [ false, %if.end.6 ], [ false, %if.end.6 ], [ false, %if.end.6 ], [ false, %for.inc.5 ]
|
||||
+ %dx.struct_exit.prop.6 = phi i32 [ %do_discard.2.5, %sw.epilog.6 ], [ 0, %if.end.6 ], [ 0, %if.end.6 ], [ 0, %if.end.6 ], [ 0, %if.end.6 ], [ 0, %for.inc.5 ]
|
||||
+ %do_discard.2.6 = phi i32 [ 1, %sw.epilog.6 ], [ 1, %if.end.6 ], [ 1, %if.end.6 ], [ 1, %if.end.6 ], [ 1, %if.end.6 ], [ %do_discard.2.5, %for.inc.5 ]
|
||||
+ %g.2.i0.6 = phi float [ 0x3FF921FB60000000, %sw.epilog.6 ], [ 0x3FF921FB60000000, %if.end.6 ], [ 0x3FF921FB60000000, %if.end.6 ], [ 0x3FF921FB60000000, %if.end.6 ], [ 0x3FF921FB60000000, %if.end.6 ], [ %g.2.i0.5, %for.inc.5 ]
|
||||
+ br i1 %dx.struct_exit.prop23.6, label %cleanup, label %for.inc.6
|
||||
+
|
||||
+for.inc.6: ; preds = %dx.struct_exit.new_exiting.6
|
||||
+ %cmp3.7 = fcmp fast une float %g.2.i0.6, 0.000000e+00, !dbg !29 ; line:19 col:13
|
||||
+ br i1 %cmp3.7, label %dx.struct_exit.new_exiting.7, label %if.end.7, !dbg !30 ; line:19 col:9
|
||||
+
|
||||
+if.end.7: ; preds = %for.inc.6
|
||||
+ switch i32 7, label %sw.epilog.7 [
|
||||
+ i32 1, label %dx.struct_exit.new_exiting.7
|
||||
+ i32 2, label %dx.struct_exit.new_exiting.7
|
||||
+ i32 3, label %dx.struct_exit.new_exiting.7
|
||||
+ i32 5, label %dx.struct_exit.new_exiting.7
|
||||
+ ], !dbg !31 ; line:23 col:5
|
||||
+
|
||||
+sw.epilog.7: ; preds = %if.end.7
|
||||
+ br label %dx.struct_exit.new_exiting.7
|
||||
+
|
||||
+dx.struct_exit.new_exiting.7: ; preds = %sw.epilog.7, %if.end.7, %if.end.7, %if.end.7, %if.end.7, %for.inc.6
|
||||
+ %dx.struct_exit.prop.7 = phi i32 [ %do_discard.2.6, %sw.epilog.7 ], [ 0, %if.end.7 ], [ 0, %if.end.7 ], [ 0, %if.end.7 ], [ 0, %if.end.7 ], [ 0, %for.inc.6 ]
|
||||
+ %do_discard.2.7 = phi i32 [ 1, %sw.epilog.7 ], [ 1, %if.end.7 ], [ 1, %if.end.7 ], [ 1, %if.end.7 ], [ 1, %if.end.7 ], [ %do_discard.2.6, %for.inc.6 ]
|
||||
+ %g.2.i0.7 = phi float [ 0x3FF921FB60000000, %sw.epilog.7 ], [ 0x3FF921FB60000000, %if.end.7 ], [ 0x3FF921FB60000000, %if.end.7 ], [ 0x3FF921FB60000000, %if.end.7 ], [ 0x3FF921FB60000000, %if.end.7 ], [ %g.2.i0.6, %for.inc.6 ]
|
||||
+ br i1 false, label %cleanup, label %for.inc.7
|
||||
+
|
||||
+for.inc.7: ; preds = %dx.struct_exit.new_exiting.7
|
||||
+ %cmp3.8 = fcmp fast une float %g.2.i0.7, 0.000000e+00, !dbg !29 ; line:19 col:13
|
||||
+ br i1 %cmp3.8, label %dx.struct_exit.new_exiting.8, label %if.end.8, !dbg !30 ; line:19 col:9
|
||||
+
|
||||
+if.end.8: ; preds = %for.inc.7
|
||||
+ switch i32 8, label %sw.epilog.8 [
|
||||
+ i32 1, label %dx.struct_exit.new_exiting.8
|
||||
+ i32 2, label %dx.struct_exit.new_exiting.8
|
||||
+ i32 3, label %dx.struct_exit.new_exiting.8
|
||||
+ i32 5, label %dx.struct_exit.new_exiting.8
|
||||
+ ], !dbg !31 ; line:23 col:5
|
||||
+
|
||||
+sw.epilog.8: ; preds = %if.end.8
|
||||
+ br label %dx.struct_exit.new_exiting.8
|
||||
+
|
||||
+dx.struct_exit.new_exiting.8: ; preds = %sw.epilog.8, %if.end.8, %if.end.8, %if.end.8, %if.end.8, %for.inc.7
|
||||
+ %dx.struct_exit.prop.8 = phi i32 [ %do_discard.2.7, %sw.epilog.8 ], [ 0, %if.end.8 ], [ 0, %if.end.8 ], [ 0, %if.end.8 ], [ 0, %if.end.8 ], [ 0, %for.inc.7 ]
|
||||
+ %do_discard.2.8 = phi i32 [ 1, %sw.epilog.8 ], [ 1, %if.end.8 ], [ 1, %if.end.8 ], [ 1, %if.end.8 ], [ 1, %if.end.8 ], [ %do_discard.2.7, %for.inc.7 ]
|
||||
+ %g.2.i0.8 = phi float [ 0x3FF921FB60000000, %sw.epilog.8 ], [ 0x3FF921FB60000000, %if.end.8 ], [ 0x3FF921FB60000000, %if.end.8 ], [ 0x3FF921FB60000000, %if.end.8 ], [ 0x3FF921FB60000000, %if.end.8 ], [ %g.2.i0.7, %for.inc.7 ]
|
||||
+ br i1 false, label %cleanup, label %for.inc.8
|
||||
+
|
||||
+for.inc.8: ; preds = %dx.struct_exit.new_exiting.8
|
||||
+ %cmp3.9 = fcmp fast une float %g.2.i0.8, 0.000000e+00, !dbg !29 ; line:19 col:13
|
||||
+ br i1 %cmp3.9, label %dx.struct_exit.new_exiting.9, label %if.end.9, !dbg !30 ; line:19 col:9
|
||||
+
|
||||
+if.end.9: ; preds = %for.inc.8
|
||||
+ switch i32 9, label %sw.epilog.9 [
|
||||
+ i32 1, label %dx.struct_exit.new_exiting.9
|
||||
+ i32 2, label %dx.struct_exit.new_exiting.9
|
||||
+ i32 3, label %dx.struct_exit.new_exiting.9
|
||||
+ i32 5, label %dx.struct_exit.new_exiting.9
|
||||
+ ], !dbg !31 ; line:23 col:5
|
||||
+
|
||||
+sw.epilog.9: ; preds = %if.end.9
|
||||
+ br label %dx.struct_exit.new_exiting.9
|
||||
+
|
||||
+dx.struct_exit.new_exiting.9: ; preds = %sw.epilog.9, %if.end.9, %if.end.9, %if.end.9, %if.end.9, %for.inc.8
|
||||
+ %dx.struct_exit.prop.9 = phi i32 [ %do_discard.2.8, %sw.epilog.9 ], [ 0, %if.end.9 ], [ 0, %if.end.9 ], [ 0, %if.end.9 ], [ 0, %if.end.9 ], [ 0, %for.inc.8 ]
|
||||
+ %do_discard.2.9 = phi i32 [ 1, %sw.epilog.9 ], [ 1, %if.end.9 ], [ 1, %if.end.9 ], [ 1, %if.end.9 ], [ 1, %if.end.9 ], [ %do_discard.2.8, %for.inc.8 ]
|
||||
+ br i1 false, label %cleanup, label %for.inc.9
|
||||
+
|
||||
+for.inc.9: ; preds = %dx.struct_exit.new_exiting.9
|
||||
+ br label %cleanup
|
||||
+}
|
||||
+
|
||||
+; Function Attrs: nounwind
|
||||
+declare void @dx.op.storeOutput.f32(i32, i32, i32, i8, float) #0
|
||||
+
|
||||
+; Function Attrs: nounwind
|
||||
+declare void @dx.op.discard(i32, i1) #0
|
||||
+
|
||||
+; Function Attrs: nounwind readonly
|
||||
+declare %dx.types.ResRet.i32 @dx.op.rawBufferLoad.i32(i32, %dx.types.Handle, i32, i32, i8, i32) #1
|
||||
+
|
||||
+; Function Attrs: nounwind readonly
|
||||
+declare %dx.types.Handle @dx.op.createHandleForLib.struct.ByteAddressBuffer(i32, %struct.ByteAddressBuffer) #1
|
||||
+
|
||||
+; Function Attrs: nounwind readnone
|
||||
+declare %dx.types.Handle @dx.op.annotateHandle(i32, %dx.types.Handle, %dx.types.ResourceProperties) #2
|
||||
+
|
||||
+attributes #0 = { nounwind }
|
||||
+attributes #1 = { nounwind readonly }
|
||||
+attributes #2 = { nounwind readnone }
|
||||
+
|
||||
+!llvm.module.flags = !{!0}
|
||||
+!pauseresume = !{!1}
|
||||
+!llvm.ident = !{!2}
|
||||
+!dx.version = !{!3}
|
||||
+!dx.valver = !{!4}
|
||||
+!dx.shaderModel = !{!5}
|
||||
+!dx.resources = !{!6}
|
||||
+!dx.typeAnnotations = !{!9, !12}
|
||||
+!dx.entryPoints = !{!19}
|
||||
+
|
||||
+!0 = !{i32 2, !"Debug Info Version", i32 3}
|
||||
+!1 = !{!"hlsl-dxilemit", !"hlsl-dxilload"}
|
||||
+!2 = !{!"dxc(private) 1.8.0.4514 (d9bd2a706-dirty)"}
|
||||
+!3 = !{i32 1, i32 6}
|
||||
+!4 = !{i32 1, i32 8}
|
||||
+!5 = !{!"ps", i32 6, i32 6}
|
||||
+!6 = !{!7, null, null, null}
|
||||
+!7 = !{!8}
|
||||
+!8 = !{i32 0, %struct.ByteAddressBuffer* @"\01?g_buff@@3UByteAddressBuffer@@A", !"g_buff", i32 0, i32 0, i32 1, i32 11, i32 0, null}
|
||||
+!9 = !{i32 0, %struct.retval undef, !10}
|
||||
+!10 = !{i32 16, !11}
|
||||
+!11 = !{i32 6, !"value", i32 3, i32 0, i32 4, !"SV_Target0", i32 7, i32 9}
|
||||
+!12 = !{i32 1, void (<4 x float>*)* @main, !13}
|
||||
+!13 = !{!14, !16}
|
||||
+!14 = !{i32 0, !15, !15}
|
||||
+!15 = !{}
|
||||
+!16 = !{i32 1, !17, !18}
|
||||
+!17 = !{i32 4, !"SV_Target0", i32 7, i32 9}
|
||||
+!18 = !{i32 0}
|
||||
+!19 = !{void (<4 x float>*)* @main, !"main", !20, !6, null}
|
||||
+!20 = !{null, !21, null}
|
||||
+!21 = !{!22}
|
||||
+!22 = !{i32 0, !"SV_Target", i8 9, i8 16, !18, i8 0, i32 1, i8 4, i32 0, i8 0, null}
|
||||
+!23 = !DILocation(line: 15, column: 22, scope: !24)
|
||||
+!24 = !DISubprogram(name: "main", scope: !25, file: !25, line: 14, type: !26, isLocal: false, isDefinition: true, scopeLine: 14, flags: DIFlagPrototyped, isOptimized: false, function: void (<4 x float>*)* @main)
|
||||
+!25 = !DIFile(filename: "/home/amaiorano/src/external/DirectXShaderCompiler/tools/clang/test/DXC/Passes/DxilRemoveDeadBlocks/switch-with-multiple-same-successor.hlsl", directory: "")
|
||||
+!26 = !DISubroutineType(types: !15)
|
||||
+!27 = !DILocation(line: 15, column: 14, scope: !24)
|
||||
+!28 = !DILocation(line: 18, column: 3, scope: !24)
|
||||
+!29 = !DILocation(line: 19, column: 13, scope: !24)
|
||||
+!30 = !DILocation(line: 19, column: 9, scope: !24)
|
||||
+!31 = !DILocation(line: 23, column: 5, scope: !24)
|
||||
+!32 = !DILocation(line: 49, column: 7, scope: !24)
|
||||
+!33 = !DILocation(line: 49, column: 19, scope: !24)
|
||||
+!34 = !DILocation(line: 51, column: 3, scope: !24)
|
||||
+!35 = !DILocation(line: 53, column: 18, scope: !24)
|
||||
+!36 = !DILocation(line: 54, column: 1, scope: !24)
|
||||
243
patches/DirectXShaderCompiler/cherry-pick-511cfef8e050.patch
Normal file
243
patches/DirectXShaderCompiler/cherry-pick-511cfef8e050.patch
Normal file
@@ -0,0 +1,243 @@
|
||||
From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001
|
||||
From: Antonio Maiorano <amaiorano@google.com>
|
||||
Date: Mon, 27 May 2024 15:41:40 -0400
|
||||
Subject: Fix use-after-free in SimplifyCFG (#6628)
|
||||
|
||||
When SimplifySwitchOnSelect calls SimplifyTerminatorOnSelect, it holds
|
||||
onto the select's condition value to use for the conditional branch it
|
||||
replaces the switch with. When removing the switch's unused
|
||||
predecessors, it must make sure not to delete PHIs in case one of them
|
||||
is used by the condition value, otherwise the condition value itself may
|
||||
get deleted, resulting in an use-after-free.
|
||||
|
||||
Note that this was fixed in LLVM as well:
|
||||
|
||||
https://github.com/llvm/llvm-project/commit/dc3b67b4cad5c18a687edfabd50779c3c656c620
|
||||
|
||||
Bug: chromium:338103465
|
||||
Change-Id: Iff5d5f2e3ecf38a3fb22bbc65e7c33ad0de659fb
|
||||
Reviewed-on: https://chromium-review.googlesource.com/c/external/github.com/microsoft/DirectXShaderCompiler/+/5570018
|
||||
Reviewed-by: James Price <jrprice@google.com>
|
||||
Reviewed-by: Natalie Chouinard <chouinard@chromium.org>
|
||||
|
||||
diff --git a/lib/Transforms/Utils/SimplifyCFG.cpp b/lib/Transforms/Utils/SimplifyCFG.cpp
|
||||
index b45caa2929a5cc3aa064fdbd9c06c20ad9e1e155..0d3ba1e00719060c1e71fa238726f0c63bd5b32f 100644
|
||||
--- a/lib/Transforms/Utils/SimplifyCFG.cpp
|
||||
+++ b/lib/Transforms/Utils/SimplifyCFG.cpp
|
||||
@@ -2619,7 +2619,10 @@ static bool SimplifyTerminatorOnSelect(TerminatorInst *OldTerm, Value *Cond,
|
||||
else if (Succ == KeepEdge2)
|
||||
KeepEdge2 = nullptr;
|
||||
else
|
||||
- Succ->removePredecessor(OldTerm->getParent());
|
||||
+ Succ->removePredecessor(
|
||||
+ OldTerm->getParent(),
|
||||
+ /*DontDeleteUselessPHIs=*/true // HLSL Change: foward port LLVM fix
|
||||
+ );
|
||||
}
|
||||
|
||||
IRBuilder<> Builder(OldTerm);
|
||||
diff --git a/tools/clang/test/DXC/Passes/SimplifyCFG/simplifycfg-uaf-select-condition.ll b/tools/clang/test/DXC/Passes/SimplifyCFG/simplifycfg-uaf-select-condition.ll
|
||||
new file mode 100644
|
||||
index 0000000000000000000000000000000000000000..149906c11285ed99a19c0fe1743801a795827792
|
||||
--- /dev/null
|
||||
+++ b/tools/clang/test/DXC/Passes/SimplifyCFG/simplifycfg-uaf-select-condition.ll
|
||||
@@ -0,0 +1,199 @@
|
||||
+; RUN: %dxopt %s -hlsl-passes-resume -simplifycfg -S | FileCheck %s
|
||||
+
|
||||
+; The IR below comes from the following HLSL.
|
||||
+; Compiling this HLSL with dxc was resulting in an ASAN
|
||||
+; use-after-free in SimplifyCFG during
|
||||
+; SimplifyTerminatorOnSelect because it was deleting
|
||||
+; a PHI node with an input value that the pass later
|
||||
+; emits (the select condition value).
|
||||
+
|
||||
+; ByteAddressBuffer buff : register(t0);
|
||||
+;
|
||||
+; [numthreads(1, 1, 1)]
|
||||
+; void main() {
|
||||
+; if (buff.Load(0u)) {
|
||||
+; return;
|
||||
+; }
|
||||
+;
|
||||
+; int i = 0;
|
||||
+; int j = 0;
|
||||
+; while (true) {
|
||||
+; bool a = (i < 2);
|
||||
+; switch(i) {
|
||||
+; case 0: {
|
||||
+; while (true) {
|
||||
+; bool b = (j < 2);
|
||||
+; if (b) {
|
||||
+; } else {
|
||||
+; break;
|
||||
+; }
|
||||
+; while (true) {
|
||||
+; int unused = 0;
|
||||
+; while (true) {
|
||||
+; if (a) break;
|
||||
+; }
|
||||
+; while (true) {
|
||||
+; while (true) {
|
||||
+; if (b) {
|
||||
+; if (b) return;
|
||||
+; } else {
|
||||
+; break;
|
||||
+; }
|
||||
+; while (true) {
|
||||
+; i = 0;
|
||||
+; if (b) break;
|
||||
+; }
|
||||
+; if (a) break;
|
||||
+; }
|
||||
+; if (a) break;
|
||||
+; }
|
||||
+; if (a) break;
|
||||
+; }
|
||||
+; j = (j + 2);
|
||||
+; }
|
||||
+; }
|
||||
+; }
|
||||
+; }
|
||||
+; }
|
||||
+
|
||||
+; Make sure the phi node did not get deleted by simplifycfg
|
||||
+; CHECK: cleanup:
|
||||
+; CHECK-NEXT: %cleanup.dest.slot.0 = phi i32 [ 1, %while.body.20 ], [ %.mux, %while.end.37 ]
|
||||
+; CHECK-NEXT: switch i32 %cleanup.dest.slot.0, label %cleanup.46 [
|
||||
+
|
||||
+;
|
||||
+; Buffer Definitions:
|
||||
+;
|
||||
+;
|
||||
+; Resource Bindings:
|
||||
+;
|
||||
+; Name Type Format Dim ID HLSL Bind Count
|
||||
+; ------------------------------ ---------- ------- ----------- ------- -------------- ------
|
||||
+; buff texture byte r/o T0 t0 1
|
||||
+;
|
||||
+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"
|
||||
+
|
||||
+%struct.ByteAddressBuffer = type { i32 }
|
||||
+%dx.types.Handle = type { i8* }
|
||||
+%dx.types.ResourceProperties = type { i32, i32 }
|
||||
+
|
||||
+@"\01?buff@@3UByteAddressBuffer@@A" = external global %struct.ByteAddressBuffer, align 4
|
||||
+
|
||||
+; Function Attrs: nounwind
|
||||
+define void @main() #0 {
|
||||
+entry:
|
||||
+ %0 = load %struct.ByteAddressBuffer, %struct.ByteAddressBuffer* @"\01?buff@@3UByteAddressBuffer@@A", !dbg !17 ; line:5 col:7
|
||||
+ %1 = call %dx.types.Handle @"dx.hl.createhandle..%dx.types.Handle (i32, %struct.ByteAddressBuffer)"(i32 0, %struct.ByteAddressBuffer %0), !dbg !17 ; line:5 col:7
|
||||
+ %2 = call %dx.types.Handle @"dx.hl.annotatehandle..%dx.types.Handle (i32, %dx.types.Handle, %dx.types.ResourceProperties, %struct.ByteAddressBuffer)"(i32 14, %dx.types.Handle %1, %dx.types.ResourceProperties { i32 11, i32 0 }, %struct.ByteAddressBuffer undef), !dbg !17 ; line:5 col:7
|
||||
+ %3 = call i32 @"dx.hl.op.ro.i32 (i32, %dx.types.Handle, i32)"(i32 231, %dx.types.Handle %2, i32 0), !dbg !17 ; line:5 col:7
|
||||
+ %tobool = icmp ne i32 %3, 0, !dbg !17 ; line:5 col:7
|
||||
+ br i1 %tobool, label %return, label %while.body, !dbg !17 ; line:5 col:7
|
||||
+
|
||||
+while.body: ; preds = %while.body.3, %while.body, %cleanup.46, %entry
|
||||
+ %j.0 = phi i32 [ 0, %entry ], [ %j.1, %cleanup.46 ], [ %j.0, %while.body ], [ %j.1, %while.body.3 ]
|
||||
+ %i.0 = phi i32 [ 0, %entry ], [ %i.1, %cleanup.46 ], [ %i.0, %while.body ], [ %i.1, %while.body.3 ]
|
||||
+ %cmp = icmp slt i32 %i.0, 2, !dbg !21 ; line:12 col:17
|
||||
+ %cond = icmp eq i32 %i.0, 0, !dbg !22 ; line:13 col:5
|
||||
+ br i1 %cond, label %while.body.3, label %while.body, !dbg !22 ; line:13 col:5
|
||||
+
|
||||
+while.body.3: ; preds = %cleanup.46.thread, %while.body, %cleanup.46
|
||||
+ %j.1 = phi i32 [ %j.1, %cleanup.46 ], [ %j.0, %while.body ], [ %add, %cleanup.46.thread ]
|
||||
+ %i.1 = phi i32 [ %i.1, %cleanup.46 ], [ %i.0, %while.body ], [ %i.1, %cleanup.46.thread ]
|
||||
+ %cmp4 = icmp slt i32 %j.1, 2, !dbg !23 ; line:16 col:23
|
||||
+ br i1 %cmp4, label %while.body.11, label %while.body, !dbg !24 ; line:17 col:15
|
||||
+
|
||||
+while.body.11: ; preds = %while.body.3, %cleanup
|
||||
+ br label %while.body.13, !dbg !25 ; line:23 col:13
|
||||
+
|
||||
+while.body.13: ; preds = %while.body.13, %while.body.11
|
||||
+ br i1 %cmp, label %while.body.20, label %while.body.13, !dbg !26 ; line:24 col:19
|
||||
+
|
||||
+while.body.20: ; preds = %while.body.13, %while.end.37
|
||||
+ br i1 %cmp4, label %cleanup, label %while.end.37, !dbg !27 ; line:28 col:21
|
||||
+
|
||||
+while.end.37: ; preds = %while.body.20
|
||||
+ br i1 %cmp, label %cleanup, label %while.body.20, !dbg !28 ; line:39 col:19
|
||||
+
|
||||
+cleanup: ; preds = %while.end.37, %while.body.20
|
||||
+ %cleanup.dest.slot.0 = phi i32 [ 1, %while.body.20 ], [ 8, %while.end.37 ]
|
||||
+ switch i32 %cleanup.dest.slot.0, label %cleanup.46 [
|
||||
+ i32 0, label %while.body.11
|
||||
+ i32 8, label %cleanup.46.thread
|
||||
+ ]
|
||||
+
|
||||
+cleanup.46.thread: ; preds = %cleanup
|
||||
+ %add = add nsw i32 %j.1, 2, !dbg !29 ; line:43 col:18
|
||||
+ br label %while.body.3
|
||||
+
|
||||
+cleanup.46: ; preds = %cleanup
|
||||
+ switch i32 %cleanup.dest.slot.0, label %return [
|
||||
+ i32 0, label %while.body.3
|
||||
+ i32 6, label %while.body
|
||||
+ ]
|
||||
+
|
||||
+return: ; preds = %cleanup.46, %entry
|
||||
+ ret void, !dbg !30 ; line:48 col:1
|
||||
+}
|
||||
+
|
||||
+; Function Attrs: nounwind
|
||||
+declare void @llvm.lifetime.start(i64, i8* nocapture) #0
|
||||
+
|
||||
+; Function Attrs: nounwind
|
||||
+declare void @llvm.lifetime.end(i64, i8* nocapture) #0
|
||||
+
|
||||
+; Function Attrs: nounwind readonly
|
||||
+declare i32 @"dx.hl.op.ro.i32 (i32, %dx.types.Handle, i32)"(i32, %dx.types.Handle, i32) #1
|
||||
+
|
||||
+; Function Attrs: nounwind readnone
|
||||
+declare %dx.types.Handle @"dx.hl.createhandle..%dx.types.Handle (i32, %struct.ByteAddressBuffer)"(i32, %struct.ByteAddressBuffer) #2
|
||||
+
|
||||
+; Function Attrs: nounwind readnone
|
||||
+declare %dx.types.Handle @"dx.hl.annotatehandle..%dx.types.Handle (i32, %dx.types.Handle, %dx.types.ResourceProperties, %struct.ByteAddressBuffer)"(i32, %dx.types.Handle, %dx.types.ResourceProperties, %struct.ByteAddressBuffer) #2
|
||||
+
|
||||
+attributes #0 = { nounwind }
|
||||
+attributes #1 = { nounwind readonly }
|
||||
+attributes #2 = { nounwind readnone }
|
||||
+
|
||||
+!llvm.module.flags = !{!0}
|
||||
+!pauseresume = !{!1}
|
||||
+!llvm.ident = !{!2}
|
||||
+!dx.version = !{!3}
|
||||
+!dx.valver = !{!4}
|
||||
+!dx.shaderModel = !{!5}
|
||||
+!dx.typeAnnotations = !{!6}
|
||||
+!dx.entryPoints = !{!10}
|
||||
+!dx.fnprops = !{!14}
|
||||
+!dx.options = !{!15, !16}
|
||||
+
|
||||
+!0 = !{i32 2, !"Debug Info Version", i32 3}
|
||||
+!1 = !{!"hlsl-hlemit", !"hlsl-hlensure"}
|
||||
+!2 = !{!"dxc(private) 1.8.0.4514 (d9bd2a706-dirty)"}
|
||||
+!3 = !{i32 1, i32 6}
|
||||
+!4 = !{i32 1, i32 8}
|
||||
+!5 = !{!"cs", i32 6, i32 6}
|
||||
+!6 = !{i32 1, void ()* @main, !7}
|
||||
+!7 = !{!8}
|
||||
+!8 = !{i32 1, !9, !9}
|
||||
+!9 = !{}
|
||||
+!10 = !{void ()* @main, !"main", null, !11, null}
|
||||
+!11 = !{!12, null, null, null}
|
||||
+!12 = !{!13}
|
||||
+!13 = !{i32 0, %struct.ByteAddressBuffer* @"\01?buff@@3UByteAddressBuffer@@A", !"buff", i32 0, i32 0, i32 1, i32 11, i32 0, null}
|
||||
+!14 = !{void ()* @main, i32 5, i32 1, i32 1, i32 1}
|
||||
+!15 = !{i32 64}
|
||||
+!16 = !{i32 -1}
|
||||
+!17 = !DILocation(line: 5, column: 7, scope: !18)
|
||||
+!18 = !DISubprogram(name: "main", scope: !19, file: !19, line: 4, type: !20, isLocal: false, isDefinition: true, scopeLine: 4, flags: DIFlagPrototyped, isOptimized: false, function: void ()* @main)
|
||||
+!19 = !DIFile(filename: "/mnt/c/Users/amaiorano/Downloads/338103465/standalone_reduced.hlsl", directory: "")
|
||||
+!20 = !DISubroutineType(types: !9)
|
||||
+!21 = !DILocation(line: 12, column: 17, scope: !18)
|
||||
+!22 = !DILocation(line: 13, column: 5, scope: !18)
|
||||
+!23 = !DILocation(line: 16, column: 23, scope: !18)
|
||||
+!24 = !DILocation(line: 17, column: 15, scope: !18)
|
||||
+!25 = !DILocation(line: 23, column: 13, scope: !18)
|
||||
+!26 = !DILocation(line: 24, column: 19, scope: !18)
|
||||
+!27 = !DILocation(line: 28, column: 21, scope: !18)
|
||||
+!28 = !DILocation(line: 39, column: 19, scope: !18)
|
||||
+!29 = !DILocation(line: 43, column: 18, scope: !18)
|
||||
+!30 = !DILocation(line: 48, column: 1, scope: !18)
|
||||
@@ -146,3 +146,5 @@ cherry-pick-03609e39be8c.patch
|
||||
x11_use_localized_display_label_only_for_browser_process.patch
|
||||
cherry-pick-b922fcb61e3b.patch
|
||||
cherry-pick-0d9598145069.patch
|
||||
cherry-pick-24329fe5c4d0.patch
|
||||
m120-lts_mediasession_use_a_mediasessionimpl_weakptr_in.patch
|
||||
|
||||
106
patches/chromium/cherry-pick-24329fe5c4d0.patch
Normal file
106
patches/chromium/cherry-pick-24329fe5c4d0.patch
Normal file
@@ -0,0 +1,106 @@
|
||||
From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001
|
||||
From: Nidhi Jaju <nidhijaju@chromium.org>
|
||||
Date: Fri, 24 May 2024 01:26:02 +0000
|
||||
Subject: Streams: Check if buffer is detached when filling pull-into
|
||||
descriptor
|
||||
|
||||
The pull-into descriptor can become out-of-sync with the array buffer
|
||||
when the buffer is detached. This CL adds a check to see if the buffer
|
||||
is detached before trying to fill it.
|
||||
|
||||
(cherry picked from commit cd405492789ec4bc6ecd598754154c527ff60e95)
|
||||
|
||||
Bug: 339877167
|
||||
Change-Id: Ibf46a75e36dc739910db07f2e88ff9998c21e8a8
|
||||
Reviewed-on: https://chromium-review.googlesource.com/c/chromium/src/+/5553232
|
||||
Reviewed-by: Domenic Denicola <domenic@chromium.org>
|
||||
Commit-Queue: Nidhi Jaju <nidhijaju@chromium.org>
|
||||
Cr-Original-Commit-Position: refs/heads/main@{#1303628}
|
||||
Reviewed-on: https://chromium-review.googlesource.com/c/chromium/src/+/5553411
|
||||
Cr-Commit-Position: refs/branch-heads/6367@{#1228}
|
||||
Cr-Branched-From: d158c6dc6e3604e6f899041972edf26087a49740-refs/heads/main@{#1274542}
|
||||
|
||||
diff --git a/third_party/blink/renderer/core/streams/readable_byte_stream_controller.cc b/third_party/blink/renderer/core/streams/readable_byte_stream_controller.cc
|
||||
index 85e2214ca95790f547819e2a14628d342f7913bb..a844d84d20e68172e285cefe3301c49f3edfbd3a 100644
|
||||
--- a/third_party/blink/renderer/core/streams/readable_byte_stream_controller.cc
|
||||
+++ b/third_party/blink/renderer/core/streams/readable_byte_stream_controller.cc
|
||||
@@ -494,7 +494,8 @@ void ReadableByteStreamController::ProcessPullIntoDescriptorsUsingQueue(
|
||||
controller->pending_pull_intos_[0];
|
||||
// c. If ! ReadableByteStreamControllerFillPullIntoDescriptorFromQueue(
|
||||
// controller, pullIntoDescriptor) is true,
|
||||
- if (FillPullIntoDescriptorFromQueue(controller, pull_into_descriptor)) {
|
||||
+ if (FillPullIntoDescriptorFromQueue(controller, pull_into_descriptor,
|
||||
+ exception_state)) {
|
||||
// i. Perform !
|
||||
// ReadableByteStreamControllerShiftPendingPullInto(controller).
|
||||
ShiftPendingPullInto(controller);
|
||||
@@ -505,6 +506,15 @@ void ReadableByteStreamController::ProcessPullIntoDescriptorsUsingQueue(
|
||||
pull_into_descriptor, exception_state);
|
||||
DCHECK(!exception_state.HadException());
|
||||
}
|
||||
+ if (exception_state.HadException()) {
|
||||
+ // Instead of returning a rejection, which is inconvenient here,
|
||||
+ // call ControllerError(). The only difference this makes is that it
|
||||
+ // happens synchronously, but that should not be observable.
|
||||
+ ReadableByteStreamController::Error(script_state, controller,
|
||||
+ exception_state.GetException());
|
||||
+ exception_state.ClearException();
|
||||
+ return;
|
||||
+ }
|
||||
}
|
||||
}
|
||||
|
||||
@@ -989,7 +999,12 @@ void ReadableByteStreamController::FillHeadPullIntoDescriptor(
|
||||
|
||||
bool ReadableByteStreamController::FillPullIntoDescriptorFromQueue(
|
||||
ReadableByteStreamController* controller,
|
||||
- PullIntoDescriptor* pull_into_descriptor) {
|
||||
+ PullIntoDescriptor* pull_into_descriptor,
|
||||
+ ExceptionState& exception_state) {
|
||||
+ if (pull_into_descriptor->buffer->IsDetached()) {
|
||||
+ exception_state.ThrowTypeError("buffer is detached");
|
||||
+ return false;
|
||||
+ }
|
||||
// https://streams.spec.whatwg.org/#readable-byte-stream-controller-fill-pull-into-descriptor-from-queue
|
||||
// 1. Let elementSize be pullIntoDescriptor.[[elementSize]].
|
||||
const size_t element_size = pull_into_descriptor->element_size;
|
||||
@@ -1240,7 +1255,8 @@ void ReadableByteStreamController::PullInto(
|
||||
// a. If !
|
||||
// ReadableByteStreamControllerFillPullIntoDescriptorFromQueue(controller,
|
||||
// pullIntoDescriptor) is true,
|
||||
- if (FillPullIntoDescriptorFromQueue(controller, pull_into_descriptor)) {
|
||||
+ if (FillPullIntoDescriptorFromQueue(controller, pull_into_descriptor,
|
||||
+ exception_state)) {
|
||||
// i. Let filledView be !
|
||||
// ReadableByteStreamControllerConvertPullIntoDescriptor(pullIntoDescriptor).
|
||||
DOMArrayBufferView* filled_view = ConvertPullIntoDescriptor(
|
||||
@@ -1254,6 +1270,15 @@ void ReadableByteStreamController::PullInto(
|
||||
// iv. Return.
|
||||
return;
|
||||
}
|
||||
+ if (exception_state.HadException()) {
|
||||
+ // Instead of returning a rejection, which is inconvenient here,
|
||||
+ // call ControllerError(). The only difference this makes is that it
|
||||
+ // happens synchronously, but that should not be observable.
|
||||
+ ReadableByteStreamController::Error(script_state, controller,
|
||||
+ exception_state.GetException());
|
||||
+ exception_state.ClearException();
|
||||
+ return;
|
||||
+ }
|
||||
// b. If controller.[[closeRequested]] is true,
|
||||
if (controller->close_requested_) {
|
||||
// i. Let e be a TypeError exception.
|
||||
diff --git a/third_party/blink/renderer/core/streams/readable_byte_stream_controller.h b/third_party/blink/renderer/core/streams/readable_byte_stream_controller.h
|
||||
index aff7d589cef5a32f43e1dc0b06aa0d2921e39169..f31f660fddbc01d95dff904ad9ac5b1cf3ee8d86 100644
|
||||
--- a/third_party/blink/renderer/core/streams/readable_byte_stream_controller.h
|
||||
+++ b/third_party/blink/renderer/core/streams/readable_byte_stream_controller.h
|
||||
@@ -218,7 +218,8 @@ class CORE_EXPORT ReadableByteStreamController
|
||||
|
||||
// https://streams.spec.whatwg.org/#readable-byte-stream-controller-fill-pull-into-descriptor-from-queue
|
||||
static bool FillPullIntoDescriptorFromQueue(ReadableByteStreamController*,
|
||||
- PullIntoDescriptor*);
|
||||
+ PullIntoDescriptor*,
|
||||
+ ExceptionState&);
|
||||
|
||||
// https://streams.spec.whatwg.org/#abstract-opdef-readablebytestreamcontrollerfillreadrequestfromqueue
|
||||
static void FillReadRequestFromQueue(ScriptState*,
|
||||
@@ -0,0 +1,207 @@
|
||||
From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001
|
||||
From: Zakhar Voit <voit@google.com>
|
||||
Date: Fri, 7 Jun 2024 11:26:03 +0000
|
||||
Subject: MediaSession: Use a MediaSessionImpl WeakPtr in
|
||||
MediaSessionServiceImpl
|
||||
|
||||
Currently, every time MediaSessionServiceImpl wants to talk to its
|
||||
associated MediaSessionImpl, it recalculates it from its
|
||||
RenderFrameHostId. This can lead to issues where a
|
||||
MediaSessionServiceImpl of a disconnected RenderFrameHost can no longer
|
||||
access the MediaSessionImpl to tell it that it is being deleted,
|
||||
leaving MediaSessionImpl with a dangling raw_ptr.
|
||||
|
||||
(cherry picked from commit 1f0de3303671c6c041930c7f4f8a9ad017a7f211)
|
||||
|
||||
(cherry picked from commit 11c5f7911caab6930812a515eac27e35776ba35c)
|
||||
|
||||
Bug: 338929744
|
||||
Change-Id: I092d217d4a975b67a84280687ed5461a14ead98a
|
||||
Reviewed-on: https://chromium-review.googlesource.com/c/chromium/src/+/5577944
|
||||
Commit-Queue: Tommy Steimel <steimel@chromium.org>
|
||||
Cr-Original-Commit-Position: refs/branch-heads/6367@{#1245}
|
||||
Cr-Original-Branched-From: d158c6dc6e3604e6f899041972edf26087a49740-refs/heads/main@{#1274542}
|
||||
Reviewed-on: https://chromium-review.googlesource.com/c/chromium/src/+/5583452
|
||||
Owners-Override: Michael Ershov <miersh@google.com>
|
||||
Commit-Queue: Michael Ershov <miersh@google.com>
|
||||
Reviewed-by: Dale Curtis <dalecurtis@chromium.org>
|
||||
Reviewed-by: Michael Ershov <miersh@google.com>
|
||||
Cr-Commit-Position: refs/branch-heads/6099@{#2035}
|
||||
Cr-Branched-From: e6ee4500f7d6549a9ac1354f8d056da49ef406be-refs/heads/main@{#1217362}
|
||||
|
||||
diff --git a/content/browser/media/session/media_session_impl.cc b/content/browser/media/session/media_session_impl.cc
|
||||
index 5ccef5240eef2e3b5c82bc50b97331e1b2fb9f31..710aeb26aee5bcfd95fef96fc7b8be7aa27173ad 100644
|
||||
--- a/content/browser/media/session/media_session_impl.cc
|
||||
+++ b/content/browser/media/session/media_session_impl.cc
|
||||
@@ -1669,6 +1669,10 @@ const base::UnguessableToken& MediaSessionImpl::GetRequestId() const {
|
||||
return delegate_->request_id();
|
||||
}
|
||||
|
||||
+base::WeakPtr<MediaSessionImpl> MediaSessionImpl::GetWeakPtr() {
|
||||
+ return weak_factory_.GetWeakPtr();
|
||||
+}
|
||||
+
|
||||
void MediaSessionImpl::RebuildAndNotifyActionsChanged() {
|
||||
std::set<media_session::mojom::MediaSessionAction> actions =
|
||||
routed_service_ ? routed_service_->actions()
|
||||
diff --git a/content/browser/media/session/media_session_impl.h b/content/browser/media/session/media_session_impl.h
|
||||
index 1f30f99fdd94617e3ddb8fb701c01201fbebf9df..af0f967b45e52778837ea716bc8290c6c0e20a6a 100644
|
||||
--- a/content/browser/media/session/media_session_impl.h
|
||||
+++ b/content/browser/media/session/media_session_impl.h
|
||||
@@ -17,6 +17,7 @@
|
||||
#include "base/containers/id_map.h"
|
||||
#include "base/memory/raw_ptr.h"
|
||||
#include "base/memory/raw_ptr_exclusion.h"
|
||||
+#include "base/memory/weak_ptr.h"
|
||||
#include "base/timer/timer.h"
|
||||
#include "build/build_config.h"
|
||||
#include "content/browser/media/session/audio_focus_delegate.h"
|
||||
@@ -346,6 +347,9 @@ class MediaSessionImpl : public MediaSession,
|
||||
// Returns the Audio Focus request ID associated with this media session.
|
||||
const base::UnguessableToken& GetRequestId() const;
|
||||
|
||||
+ // Returns a WeakPtr to `this`.
|
||||
+ base::WeakPtr<MediaSessionImpl> GetWeakPtr();
|
||||
+
|
||||
CONTENT_EXPORT bool HasImageCacheForTest(const GURL& image_url) const;
|
||||
|
||||
// Make sure that all observers have received any pending callbacks from us,
|
||||
@@ -641,6 +645,8 @@ class MediaSessionImpl : public MediaSession,
|
||||
|
||||
media_session::mojom::RemotePlaybackMetadataPtr remote_playback_metadata_;
|
||||
|
||||
+ base::WeakPtrFactory<MediaSessionImpl> weak_factory_{this};
|
||||
+
|
||||
WEB_CONTENTS_USER_DATA_KEY_DECL();
|
||||
};
|
||||
|
||||
diff --git a/content/browser/media/session/media_session_service_impl.cc b/content/browser/media/session/media_session_service_impl.cc
|
||||
index 532d1161b5321fbe37552f1caca2d20782356f36..a3ca009421a22d51a9d85f4665dd769319d26c22 100644
|
||||
--- a/content/browser/media/session/media_session_service_impl.cc
|
||||
+++ b/content/browser/media/session/media_session_service_impl.cc
|
||||
@@ -22,14 +22,16 @@ MediaSessionServiceImpl::MediaSessionServiceImpl(
|
||||
: render_frame_host_id_(render_frame_host->GetGlobalId()),
|
||||
playback_state_(blink::mojom::MediaSessionPlaybackState::NONE) {
|
||||
MediaSessionImpl* session = GetMediaSession();
|
||||
- if (session)
|
||||
- session->OnServiceCreated(this);
|
||||
+ if (session) {
|
||||
+ media_session_ = session->GetWeakPtr();
|
||||
+ media_session_->OnServiceCreated(this);
|
||||
+ }
|
||||
}
|
||||
|
||||
MediaSessionServiceImpl::~MediaSessionServiceImpl() {
|
||||
- MediaSessionImpl* session = GetMediaSession();
|
||||
- if (session)
|
||||
- session->OnServiceDestroyed(this);
|
||||
+ if (media_session_) {
|
||||
+ media_session_->OnServiceDestroyed(this);
|
||||
+ }
|
||||
}
|
||||
|
||||
// static
|
||||
@@ -70,17 +72,17 @@ void MediaSessionServiceImpl::SetClient(
|
||||
void MediaSessionServiceImpl::SetPlaybackState(
|
||||
blink::mojom::MediaSessionPlaybackState state) {
|
||||
playback_state_ = state;
|
||||
- MediaSessionImpl* session = GetMediaSession();
|
||||
- if (session)
|
||||
- session->OnMediaSessionPlaybackStateChanged(this);
|
||||
+ if (media_session_) {
|
||||
+ media_session_->OnMediaSessionPlaybackStateChanged(this);
|
||||
+ }
|
||||
}
|
||||
|
||||
void MediaSessionServiceImpl::SetPositionState(
|
||||
const std::optional<media_session::MediaPosition>& position) {
|
||||
position_ = position;
|
||||
- MediaSessionImpl* session = GetMediaSession();
|
||||
- if (session)
|
||||
- session->RebuildAndNotifyMediaPositionChanged();
|
||||
+ if (media_session_) {
|
||||
+ media_session_->RebuildAndNotifyMediaPositionChanged();
|
||||
+ }
|
||||
}
|
||||
|
||||
void MediaSessionServiceImpl::SetMetadata(
|
||||
@@ -102,48 +104,48 @@ void MediaSessionServiceImpl::SetMetadata(
|
||||
metadata_ = std::move(metadata);
|
||||
}
|
||||
|
||||
- MediaSessionImpl* session = GetMediaSession();
|
||||
- if (session)
|
||||
- session->OnMediaSessionMetadataChanged(this);
|
||||
+ if (media_session_) {
|
||||
+ media_session_->OnMediaSessionMetadataChanged(this);
|
||||
+ }
|
||||
}
|
||||
|
||||
void MediaSessionServiceImpl::SetMicrophoneState(
|
||||
media_session::mojom::MicrophoneState microphone_state) {
|
||||
microphone_state_ = microphone_state;
|
||||
- MediaSessionImpl* session = GetMediaSession();
|
||||
- if (session)
|
||||
- session->OnMediaSessionInfoChanged(this);
|
||||
+ if (media_session_) {
|
||||
+ media_session_->OnMediaSessionInfoChanged(this);
|
||||
+ }
|
||||
}
|
||||
|
||||
void MediaSessionServiceImpl::SetCameraState(
|
||||
media_session::mojom::CameraState camera_state) {
|
||||
camera_state_ = camera_state;
|
||||
- MediaSessionImpl* session = GetMediaSession();
|
||||
- if (session)
|
||||
- session->OnMediaSessionInfoChanged(this);
|
||||
+ if (media_session_) {
|
||||
+ media_session_->OnMediaSessionInfoChanged(this);
|
||||
+ }
|
||||
}
|
||||
|
||||
void MediaSessionServiceImpl::EnableAction(
|
||||
media_session::mojom::MediaSessionAction action) {
|
||||
actions_.insert(action);
|
||||
- MediaSessionImpl* session = GetMediaSession();
|
||||
- if (session)
|
||||
- session->OnMediaSessionActionsChanged(this);
|
||||
+ if (media_session_) {
|
||||
+ media_session_->OnMediaSessionActionsChanged(this);
|
||||
+ }
|
||||
}
|
||||
|
||||
void MediaSessionServiceImpl::DisableAction(
|
||||
media_session::mojom::MediaSessionAction action) {
|
||||
actions_.erase(action);
|
||||
- MediaSessionImpl* session = GetMediaSession();
|
||||
- if (session)
|
||||
- session->OnMediaSessionActionsChanged(this);
|
||||
+ if (media_session_) {
|
||||
+ media_session_->OnMediaSessionActionsChanged(this);
|
||||
+ }
|
||||
}
|
||||
|
||||
void MediaSessionServiceImpl::ClearActions() {
|
||||
actions_.clear();
|
||||
- MediaSessionImpl* session = GetMediaSession();
|
||||
- if (session)
|
||||
- session->OnMediaSessionActionsChanged(this);
|
||||
+ if (media_session_) {
|
||||
+ media_session_->OnMediaSessionActionsChanged(this);
|
||||
+ }
|
||||
}
|
||||
|
||||
MediaSessionImpl* MediaSessionServiceImpl::GetMediaSession() {
|
||||
diff --git a/content/browser/media/session/media_session_service_impl.h b/content/browser/media/session/media_session_service_impl.h
|
||||
index 4eeffe2a8bbc532d15e5deb7bc77eebea41326cf..514c043648e70b3c29a57ddc5faabaf85e103491 100644
|
||||
--- a/content/browser/media/session/media_session_service_impl.h
|
||||
+++ b/content/browser/media/session/media_session_service_impl.h
|
||||
@@ -85,6 +85,8 @@ class CONTENT_EXPORT MediaSessionServiceImpl
|
||||
|
||||
const GlobalRenderFrameHostId render_frame_host_id_;
|
||||
|
||||
+ base::WeakPtr<MediaSessionImpl> media_session_;
|
||||
+
|
||||
mojo::Remote<blink::mojom::MediaSessionClient> client_;
|
||||
blink::mojom::MediaSessionPlaybackState playback_state_;
|
||||
blink::mojom::SpecMediaMetadataPtr metadata_;
|
||||
@@ -13,5 +13,6 @@
|
||||
{ "patch_dir": "src/electron/patches/webrtc", "repo": "src/third_party/webrtc" },
|
||||
{ "patch_dir": "src/electron/patches/reclient-configs", "repo": "src/third_party/engflow-reclient-configs" },
|
||||
{ "patch_dir": "src/electron/patches/angle", "repo": "src/third_party/angle" },
|
||||
{ "patch_dir": "src/electron/patches/DirectXShaderCompiler", "repo": "src/third_party/dawn/third_party/dxc" }
|
||||
{ "patch_dir": "src/electron/patches/DirectXShaderCompiler", "repo": "src/third_party/dawn/third_party/dxc" },
|
||||
{ "patch_dir": "src/electron/patches/libaom", "repo": "src/third_party/libaom/source/libaom"}
|
||||
]
|
||||
|
||||
2
patches/libaom/.patches
Normal file
2
patches/libaom/.patches
Normal file
@@ -0,0 +1,2 @@
|
||||
update_codec_config_after_svc_scale_controls.patch
|
||||
encode_api_test_add_repro_for_chromium_339877165.patch
|
||||
@@ -0,0 +1,162 @@
|
||||
From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001
|
||||
From: James Zern <jzern@google.com>
|
||||
Date: Thu, 16 May 2024 13:44:52 -0700
|
||||
Subject: encode_api_test: add repro for chromium 339877165
|
||||
|
||||
BUG=chromium:339877165
|
||||
|
||||
Change-Id: I69dcc2cda098ec96a34e1e5f7ef557ee8caf5521
|
||||
(cherry picked from commit 01467cdbd524900eed283660836179fd1b2cd536)
|
||||
|
||||
diff --git a/test/encode_api_test.cc b/test/encode_api_test.cc
|
||||
index 605743f9be8ccc776aa3b8dcae0a79e7dc6711e6..c0a79fe734e7985b52bdbaaa5d8dec2c541275e5 100644
|
||||
--- a/test/encode_api_test.cc
|
||||
+++ b/test/encode_api_test.cc
|
||||
@@ -556,6 +556,147 @@ TEST(EncodeAPI, Buganizer310457427) {
|
||||
encoder.Encode(false);
|
||||
}
|
||||
|
||||
+// Reproduces https://crbug.com/339877165.
|
||||
+TEST(EncodeAPI, Buganizer339877165) {
|
||||
+ // Initialize libaom encoder.
|
||||
+ aom_codec_iface_t *const iface = aom_codec_av1_cx();
|
||||
+ aom_codec_ctx_t enc;
|
||||
+ aom_codec_enc_cfg_t cfg;
|
||||
+
|
||||
+ ASSERT_EQ(aom_codec_enc_config_default(iface, &cfg, AOM_USAGE_REALTIME),
|
||||
+ AOM_CODEC_OK);
|
||||
+
|
||||
+ cfg.g_w = 2560;
|
||||
+ cfg.g_h = 1600;
|
||||
+ cfg.rc_target_bitrate = 231;
|
||||
+ cfg.rc_end_usage = AOM_CBR;
|
||||
+ cfg.g_threads = 8;
|
||||
+
|
||||
+ ASSERT_EQ(aom_codec_enc_init(&enc, iface, &cfg, 0), AOM_CODEC_OK);
|
||||
+
|
||||
+ // From libaom_av1_encoder.cc in WebRTC.
|
||||
+ ASSERT_EQ(aom_codec_control(&enc, AOME_SET_CPUUSED, 11), AOM_CODEC_OK);
|
||||
+ ASSERT_EQ(aom_codec_control(&enc, AV1E_SET_ENABLE_CDEF, 1), AOM_CODEC_OK);
|
||||
+ ASSERT_EQ(aom_codec_control(&enc, AV1E_SET_ENABLE_TPL_MODEL, 0),
|
||||
+ AOM_CODEC_OK);
|
||||
+ ASSERT_EQ(aom_codec_control(&enc, AV1E_SET_DELTAQ_MODE, 0), AOM_CODEC_OK);
|
||||
+ ASSERT_EQ(aom_codec_control(&enc, AV1E_SET_ENABLE_ORDER_HINT, 0),
|
||||
+ AOM_CODEC_OK);
|
||||
+ ASSERT_EQ(aom_codec_control(&enc, AV1E_SET_AQ_MODE, 3), AOM_CODEC_OK);
|
||||
+ ASSERT_EQ(aom_codec_control(&enc, AOME_SET_MAX_INTRA_BITRATE_PCT, 300),
|
||||
+ AOM_CODEC_OK);
|
||||
+ ASSERT_EQ(aom_codec_control(&enc, AV1E_SET_COEFF_COST_UPD_FREQ, 3),
|
||||
+ AOM_CODEC_OK);
|
||||
+ ASSERT_EQ(aom_codec_control(&enc, AV1E_SET_MODE_COST_UPD_FREQ, 3),
|
||||
+ AOM_CODEC_OK);
|
||||
+ ASSERT_EQ(aom_codec_control(&enc, AV1E_SET_MV_COST_UPD_FREQ, 3),
|
||||
+ AOM_CODEC_OK);
|
||||
+ ASSERT_EQ(aom_codec_control(&enc, AV1E_SET_TUNE_CONTENT, AOM_CONTENT_SCREEN),
|
||||
+ AOM_CODEC_OK);
|
||||
+ ASSERT_EQ(aom_codec_control(&enc, AV1E_SET_ENABLE_PALETTE, 1), AOM_CODEC_OK);
|
||||
+ ASSERT_EQ(aom_codec_control(&enc, AV1E_SET_TILE_ROWS, 1), AOM_CODEC_OK);
|
||||
+ ASSERT_EQ(aom_codec_control(&enc, AV1E_SET_TILE_COLUMNS, 2), AOM_CODEC_OK);
|
||||
+ ASSERT_EQ(aom_codec_control(&enc, AV1E_SET_ENABLE_OBMC, 0), AOM_CODEC_OK);
|
||||
+ ASSERT_EQ(aom_codec_control(&enc, AV1E_SET_NOISE_SENSITIVITY, 0),
|
||||
+ AOM_CODEC_OK);
|
||||
+ ASSERT_EQ(aom_codec_control(&enc, AV1E_SET_ENABLE_WARPED_MOTION, 0),
|
||||
+ AOM_CODEC_OK);
|
||||
+ ASSERT_EQ(aom_codec_control(&enc, AV1E_SET_ENABLE_GLOBAL_MOTION, 0),
|
||||
+ AOM_CODEC_OK);
|
||||
+ ASSERT_EQ(aom_codec_control(&enc, AV1E_SET_ENABLE_REF_FRAME_MVS, 0),
|
||||
+ AOM_CODEC_OK);
|
||||
+ ASSERT_EQ(aom_codec_control(&enc, AV1E_SET_SUPERBLOCK_SIZE,
|
||||
+ AOM_SUPERBLOCK_SIZE_DYNAMIC),
|
||||
+ AOM_CODEC_OK);
|
||||
+ ASSERT_EQ(aom_codec_control(&enc, AV1E_SET_ENABLE_CFL_INTRA, 0),
|
||||
+ AOM_CODEC_OK);
|
||||
+ ASSERT_EQ(aom_codec_control(&enc, AV1E_SET_ENABLE_SMOOTH_INTRA, 0),
|
||||
+ AOM_CODEC_OK);
|
||||
+ ASSERT_EQ(aom_codec_control(&enc, AV1E_SET_ENABLE_ANGLE_DELTA, 0),
|
||||
+ AOM_CODEC_OK);
|
||||
+ ASSERT_EQ(aom_codec_control(&enc, AV1E_SET_ENABLE_FILTER_INTRA, 0),
|
||||
+ AOM_CODEC_OK);
|
||||
+ ASSERT_EQ(aom_codec_control(&enc, AV1E_SET_INTRA_DEFAULT_TX_ONLY, 1),
|
||||
+ AOM_CODEC_OK);
|
||||
+ ASSERT_EQ(aom_codec_control(&enc, AV1E_SET_DISABLE_TRELLIS_QUANT, 1),
|
||||
+ AOM_CODEC_OK);
|
||||
+ ASSERT_EQ(aom_codec_control(&enc, AV1E_SET_ENABLE_DIST_WTD_COMP, 0),
|
||||
+ AOM_CODEC_OK);
|
||||
+ ASSERT_EQ(aom_codec_control(&enc, AV1E_SET_ENABLE_DIFF_WTD_COMP, 0),
|
||||
+ AOM_CODEC_OK);
|
||||
+ ASSERT_EQ(aom_codec_control(&enc, AV1E_SET_ENABLE_DUAL_FILTER, 0),
|
||||
+ AOM_CODEC_OK);
|
||||
+ ASSERT_EQ(aom_codec_control(&enc, AV1E_SET_ENABLE_INTERINTRA_COMP, 0),
|
||||
+ AOM_CODEC_OK);
|
||||
+ ASSERT_EQ(aom_codec_control(&enc, AV1E_SET_ENABLE_INTERINTRA_WEDGE, 0),
|
||||
+ AOM_CODEC_OK);
|
||||
+ ASSERT_EQ(aom_codec_control(&enc, AV1E_SET_ENABLE_INTRA_EDGE_FILTER, 0),
|
||||
+ AOM_CODEC_OK);
|
||||
+ ASSERT_EQ(aom_codec_control(&enc, AV1E_SET_ENABLE_INTRABC, 0), AOM_CODEC_OK);
|
||||
+ ASSERT_EQ(aom_codec_control(&enc, AV1E_SET_ENABLE_MASKED_COMP, 0),
|
||||
+ AOM_CODEC_OK);
|
||||
+ ASSERT_EQ(aom_codec_control(&enc, AV1E_SET_ENABLE_PAETH_INTRA, 0),
|
||||
+ AOM_CODEC_OK);
|
||||
+ ASSERT_EQ(aom_codec_control(&enc, AV1E_SET_ENABLE_QM, 0), AOM_CODEC_OK);
|
||||
+ ASSERT_EQ(aom_codec_control(&enc, AV1E_SET_ENABLE_RECT_PARTITIONS, 0),
|
||||
+ AOM_CODEC_OK);
|
||||
+ ASSERT_EQ(aom_codec_control(&enc, AV1E_SET_ENABLE_RESTORATION, 0),
|
||||
+ AOM_CODEC_OK);
|
||||
+ ASSERT_EQ(aom_codec_control(&enc, AV1E_SET_ENABLE_SMOOTH_INTERINTRA, 0),
|
||||
+ AOM_CODEC_OK);
|
||||
+ ASSERT_EQ(aom_codec_control(&enc, AV1E_SET_ENABLE_TX64, 0), AOM_CODEC_OK);
|
||||
+ ASSERT_EQ(aom_codec_control(&enc, AV1E_SET_MAX_REFERENCE_FRAMES, 3),
|
||||
+ AOM_CODEC_OK);
|
||||
+ ASSERT_EQ(aom_codec_enc_config_set(&enc, &cfg), AOM_CODEC_OK);
|
||||
+
|
||||
+ aom_svc_params_t svc_params = {};
|
||||
+ svc_params.number_spatial_layers = 2;
|
||||
+ svc_params.number_temporal_layers = 1;
|
||||
+ svc_params.max_quantizers[0] = svc_params.max_quantizers[1] = 56;
|
||||
+ svc_params.min_quantizers[0] = svc_params.min_quantizers[1] = 10;
|
||||
+ svc_params.scaling_factor_num[0] = svc_params.scaling_factor_num[1] = 1;
|
||||
+ svc_params.scaling_factor_den[0] = 2;
|
||||
+ svc_params.scaling_factor_den[1] = 1;
|
||||
+ svc_params.layer_target_bitrate[0] = cfg.rc_target_bitrate;
|
||||
+ svc_params.framerate_factor[0] = 1;
|
||||
+ ASSERT_EQ(aom_codec_control(&enc, AV1E_SET_SVC_PARAMS, &svc_params),
|
||||
+ AOM_CODEC_OK);
|
||||
+
|
||||
+ aom_svc_layer_id_t layer_id = {};
|
||||
+ ASSERT_EQ(aom_codec_control(&enc, AV1E_SET_SVC_LAYER_ID, &layer_id),
|
||||
+ AOM_CODEC_OK);
|
||||
+
|
||||
+ aom_svc_ref_frame_config_t ref_frame_config = {};
|
||||
+ ref_frame_config.refresh[0] = 1;
|
||||
+ ASSERT_EQ(
|
||||
+ aom_codec_control(&enc, AV1E_SET_SVC_REF_FRAME_CONFIG, &ref_frame_config),
|
||||
+ AOM_CODEC_OK);
|
||||
+
|
||||
+ // Create input image.
|
||||
+ aom_image_t *const image =
|
||||
+ CreateGrayImage(AOM_IMG_FMT_I420, cfg.g_w, cfg.g_h);
|
||||
+ ASSERT_NE(image, nullptr);
|
||||
+
|
||||
+ // Encode layer 0.
|
||||
+ ASSERT_EQ(aom_codec_encode(&enc, image, 0, 1, 0), AOM_CODEC_OK);
|
||||
+
|
||||
+ layer_id.spatial_layer_id = 1;
|
||||
+ ASSERT_EQ(aom_codec_control(&enc, AV1E_SET_SVC_LAYER_ID, &layer_id),
|
||||
+ AOM_CODEC_OK);
|
||||
+
|
||||
+ ref_frame_config.refresh[0] = 0;
|
||||
+ ASSERT_EQ(
|
||||
+ aom_codec_control(&enc, AV1E_SET_SVC_REF_FRAME_CONFIG, &ref_frame_config),
|
||||
+ AOM_CODEC_OK);
|
||||
+
|
||||
+ // Encode layer 1.
|
||||
+ ASSERT_EQ(aom_codec_encode(&enc, image, 0, 1, 0), AOM_CODEC_OK);
|
||||
+
|
||||
+ // Free resources.
|
||||
+ aom_img_free(image);
|
||||
+ aom_codec_destroy(&enc);
|
||||
+}
|
||||
+
|
||||
class EncodeAPIParameterized
|
||||
: public testing::TestWithParam<std::tuple<
|
||||
/*usage=*/unsigned int, /*speed=*/int, /*aq_mode=*/unsigned int>> {};
|
||||
@@ -0,0 +1,196 @@
|
||||
From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001
|
||||
From: James Zern <jzern@google.com>
|
||||
Date: Tue, 14 May 2024 17:54:10 -0700
|
||||
Subject: update codec config after svc/scale controls
|
||||
|
||||
This ensures the encoder state/allocations stay in sync with scaling and
|
||||
svc layer changes. In the SVC case, depending on the resolution,
|
||||
differences in the chosen superblock size among layers may have caused a
|
||||
crash. This was reproducible in WebRTC in screen content mode.
|
||||
|
||||
The fix is based on a change by Yuan Tong (tongyuan200097) [1]. It
|
||||
refreshes the encoder config after AOME_SET_SCALEMODE,
|
||||
AOME_SET_NUMBER_SPATIAL_LAYERS and AV1E_SET_SVC_PARAMS if no frames have
|
||||
been encoded. AV1E_SET_SVC_PARAMS was missed in the original change.
|
||||
|
||||
[1]: https://aomedia-review.googlesource.com/c/aom/+/171941/2
|
||||
|
||||
Bug: chromium:339877165
|
||||
Change-Id: Ib3d2a123b159898d7c7e19c81e89ff148920e1f1
|
||||
(cherry picked from commit e42f4b1980bbbc772aa886d8b43a885461d7b89e)
|
||||
|
||||
diff --git a/av1/av1_cx_iface.c b/av1/av1_cx_iface.c
|
||||
index 9214feb4e6f9dd068444e76bf8073a0bbe772134..68d6de21845a4e635f67f0a972126563d8f4fb7c 100644
|
||||
--- a/av1/av1_cx_iface.c
|
||||
+++ b/av1/av1_cx_iface.c
|
||||
@@ -1602,37 +1602,42 @@ static aom_codec_err_t ctrl_get_baseline_gf_interval(aom_codec_alg_priv_t *ctx,
|
||||
return AOM_CODEC_OK;
|
||||
}
|
||||
|
||||
+static aom_codec_err_t update_encoder_cfg(aom_codec_alg_priv_t *ctx) {
|
||||
+ set_encoder_config(&ctx->oxcf, &ctx->cfg, &ctx->extra_cfg);
|
||||
+ av1_check_fpmt_config(ctx->ppi, &ctx->oxcf);
|
||||
+ bool is_sb_size_changed = false;
|
||||
+ av1_change_config_seq(ctx->ppi, &ctx->oxcf, &is_sb_size_changed);
|
||||
+ for (int i = 0; i < ctx->ppi->num_fp_contexts; i++) {
|
||||
+ AV1_COMP *const cpi = ctx->ppi->parallel_cpi[i];
|
||||
+ struct aom_internal_error_info *const error = cpi->common.error;
|
||||
+ if (setjmp(error->jmp)) {
|
||||
+ error->setjmp = 0;
|
||||
+ return error->error_code;
|
||||
+ }
|
||||
+ error->setjmp = 1;
|
||||
+ av1_change_config(cpi, &ctx->oxcf, is_sb_size_changed);
|
||||
+ error->setjmp = 0;
|
||||
+ }
|
||||
+ if (ctx->ppi->cpi_lap != NULL) {
|
||||
+ AV1_COMP *const cpi_lap = ctx->ppi->cpi_lap;
|
||||
+ struct aom_internal_error_info *const error = cpi_lap->common.error;
|
||||
+ if (setjmp(error->jmp)) {
|
||||
+ error->setjmp = 0;
|
||||
+ return error->error_code;
|
||||
+ }
|
||||
+ error->setjmp = 1;
|
||||
+ av1_change_config(cpi_lap, &ctx->oxcf, is_sb_size_changed);
|
||||
+ error->setjmp = 0;
|
||||
+ }
|
||||
+ return AOM_CODEC_OK;
|
||||
+}
|
||||
+
|
||||
static aom_codec_err_t update_extra_cfg(aom_codec_alg_priv_t *ctx,
|
||||
const struct av1_extracfg *extra_cfg) {
|
||||
const aom_codec_err_t res = validate_config(ctx, &ctx->cfg, extra_cfg);
|
||||
if (res == AOM_CODEC_OK) {
|
||||
ctx->extra_cfg = *extra_cfg;
|
||||
- set_encoder_config(&ctx->oxcf, &ctx->cfg, &ctx->extra_cfg);
|
||||
- av1_check_fpmt_config(ctx->ppi, &ctx->oxcf);
|
||||
- bool is_sb_size_changed = false;
|
||||
- av1_change_config_seq(ctx->ppi, &ctx->oxcf, &is_sb_size_changed);
|
||||
- for (int i = 0; i < ctx->ppi->num_fp_contexts; i++) {
|
||||
- AV1_COMP *const cpi = ctx->ppi->parallel_cpi[i];
|
||||
- struct aom_internal_error_info *const error = cpi->common.error;
|
||||
- if (setjmp(error->jmp)) {
|
||||
- error->setjmp = 0;
|
||||
- return error->error_code;
|
||||
- }
|
||||
- error->setjmp = 1;
|
||||
- av1_change_config(cpi, &ctx->oxcf, is_sb_size_changed);
|
||||
- error->setjmp = 0;
|
||||
- }
|
||||
- if (ctx->ppi->cpi_lap != NULL) {
|
||||
- AV1_COMP *const cpi_lap = ctx->ppi->cpi_lap;
|
||||
- struct aom_internal_error_info *const error = cpi_lap->common.error;
|
||||
- if (setjmp(error->jmp)) {
|
||||
- error->setjmp = 0;
|
||||
- return error->error_code;
|
||||
- }
|
||||
- error->setjmp = 1;
|
||||
- av1_change_config(cpi_lap, &ctx->oxcf, is_sb_size_changed);
|
||||
- error->setjmp = 0;
|
||||
- }
|
||||
+ return update_encoder_cfg(ctx);
|
||||
}
|
||||
return res;
|
||||
}
|
||||
@@ -3573,11 +3578,23 @@ static aom_codec_err_t ctrl_set_scale_mode(aom_codec_alg_priv_t *ctx,
|
||||
aom_scaling_mode_t *const mode = va_arg(args, aom_scaling_mode_t *);
|
||||
|
||||
if (mode) {
|
||||
- const int res = av1_set_internal_size(
|
||||
- &ctx->ppi->cpi->oxcf, &ctx->ppi->cpi->resize_pending_params,
|
||||
- mode->h_scaling_mode, mode->v_scaling_mode);
|
||||
- av1_check_fpmt_config(ctx->ppi, &ctx->ppi->cpi->oxcf);
|
||||
- return (res == 0) ? AOM_CODEC_OK : AOM_CODEC_INVALID_PARAM;
|
||||
+ AV1EncoderConfig *const oxcf =
|
||||
+ ctx->ppi->seq_params_locked ? &ctx->ppi->cpi->oxcf : &ctx->oxcf;
|
||||
+ const int res =
|
||||
+ av1_set_internal_size(oxcf, &ctx->ppi->cpi->resize_pending_params,
|
||||
+ mode->h_scaling_mode, mode->v_scaling_mode);
|
||||
+ if (res == 0) {
|
||||
+ // update_encoder_cfg() is somewhat costly and this control may be called
|
||||
+ // multiple times, so update_encoder_cfg() is only called to ensure frame
|
||||
+ // and superblock sizes are updated before they're fixed by the first
|
||||
+ // encode call.
|
||||
+ if (ctx->ppi->seq_params_locked) {
|
||||
+ av1_check_fpmt_config(ctx->ppi, &ctx->ppi->cpi->oxcf);
|
||||
+ return AOM_CODEC_OK;
|
||||
+ }
|
||||
+ return update_encoder_cfg(ctx);
|
||||
+ }
|
||||
+ return AOM_CODEC_INVALID_PARAM;
|
||||
} else {
|
||||
return AOM_CODEC_INVALID_PARAM;
|
||||
}
|
||||
@@ -3598,6 +3615,13 @@ static aom_codec_err_t ctrl_set_number_spatial_layers(aom_codec_alg_priv_t *ctx,
|
||||
if (number_spatial_layers > MAX_NUM_SPATIAL_LAYERS)
|
||||
return AOM_CODEC_INVALID_PARAM;
|
||||
ctx->ppi->number_spatial_layers = number_spatial_layers;
|
||||
+ // update_encoder_cfg() is somewhat costly and this control may be called
|
||||
+ // multiple times, so update_encoder_cfg() is only called to ensure frame and
|
||||
+ // superblock sizes are updated before they're fixed by the first encode
|
||||
+ // call.
|
||||
+ if (!ctx->ppi->seq_params_locked) {
|
||||
+ return update_encoder_cfg(ctx);
|
||||
+ }
|
||||
return AOM_CODEC_OK;
|
||||
}
|
||||
|
||||
@@ -3615,8 +3639,6 @@ static aom_codec_err_t ctrl_set_svc_params(aom_codec_alg_priv_t *ctx,
|
||||
va_list args) {
|
||||
AV1_PRIMARY *const ppi = ctx->ppi;
|
||||
AV1_COMP *const cpi = ppi->cpi;
|
||||
- AV1_COMMON *const cm = &cpi->common;
|
||||
- AV1EncoderConfig *oxcf = &cpi->oxcf;
|
||||
aom_svc_params_t *const params = va_arg(args, aom_svc_params_t *);
|
||||
int64_t target_bandwidth = 0;
|
||||
ppi->number_spatial_layers = params->number_spatial_layers;
|
||||
@@ -3656,19 +3678,38 @@ static aom_codec_err_t ctrl_set_svc_params(aom_codec_alg_priv_t *ctx,
|
||||
target_bandwidth += lc->layer_target_bitrate;
|
||||
}
|
||||
}
|
||||
- if (cm->current_frame.frame_number == 0) {
|
||||
- if (!cpi->ppi->seq_params_locked) {
|
||||
- SequenceHeader *const seq_params = &ppi->seq_params;
|
||||
- seq_params->operating_points_cnt_minus_1 =
|
||||
- ppi->number_spatial_layers * ppi->number_temporal_layers - 1;
|
||||
- av1_init_seq_coding_tools(ppi, &cpi->oxcf, 1);
|
||||
- }
|
||||
+
|
||||
+ if (ppi->seq_params_locked) {
|
||||
+ AV1EncoderConfig *const oxcf = &cpi->oxcf;
|
||||
+ // Keep ctx->oxcf in sync in case further codec controls are made prior
|
||||
+ // to encoding.
|
||||
+ ctx->oxcf.rc_cfg.target_bandwidth = oxcf->rc_cfg.target_bandwidth =
|
||||
+ target_bandwidth;
|
||||
+ set_primary_rc_buffer_sizes(oxcf, ppi);
|
||||
+ av1_update_layer_context_change_config(cpi, target_bandwidth);
|
||||
+ check_reset_rc_flag(cpi);
|
||||
+ } else {
|
||||
+ // Note av1_init_layer_context() relies on cpi->oxcf. The order of that
|
||||
+ // call and the ones in the other half of this block (which
|
||||
+ // update_encoder_cfg() transitively makes) is important. So we keep
|
||||
+ // ctx->oxcf and cpi->oxcf in sync here as update_encoder_cfg() will
|
||||
+ // overwrite cpi->oxcf with ctx->oxcf.
|
||||
+ ctx->oxcf.rc_cfg.target_bandwidth = cpi->oxcf.rc_cfg.target_bandwidth =
|
||||
+ target_bandwidth;
|
||||
+ SequenceHeader *const seq_params = &ppi->seq_params;
|
||||
+ seq_params->operating_points_cnt_minus_1 =
|
||||
+ ppi->number_spatial_layers * ppi->number_temporal_layers - 1;
|
||||
+
|
||||
av1_init_layer_context(cpi);
|
||||
+ // update_encoder_cfg() is somewhat costly and this control may be called
|
||||
+ // multiple times, so update_encoder_cfg() is only called to ensure frame
|
||||
+ // and superblock sizes are updated before they're fixed by the first
|
||||
+ // encode call.
|
||||
+ return update_encoder_cfg(ctx);
|
||||
}
|
||||
- oxcf->rc_cfg.target_bandwidth = target_bandwidth;
|
||||
- set_primary_rc_buffer_sizes(oxcf, cpi->ppi);
|
||||
- av1_update_layer_context_change_config(cpi, target_bandwidth);
|
||||
- check_reset_rc_flag(cpi);
|
||||
+ } else if (!ppi->seq_params_locked) {
|
||||
+ // Ensure frame and superblock sizes are updated.
|
||||
+ return update_encoder_cfg(ctx);
|
||||
}
|
||||
av1_check_fpmt_config(ctx->ppi, &ctx->ppi->cpi->oxcf);
|
||||
return AOM_CODEC_OK;
|
||||
@@ -6,3 +6,4 @@ cherry-pick-b3c01ac1e60a.patch
|
||||
cherry-pick-6503a987d966.patch
|
||||
cherry-pick-3e037e195e50.patch
|
||||
cherry-pick-e7b64c6ee185.patch
|
||||
cherry-pick-f911ff372723.patch
|
||||
|
||||
45
patches/v8/cherry-pick-f911ff372723.patch
Normal file
45
patches/v8/cherry-pick-f911ff372723.patch
Normal file
@@ -0,0 +1,45 @@
|
||||
From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001
|
||||
From: Shu-yu Guo <syg@chromium.org>
|
||||
Date: Fri, 10 May 2024 12:08:04 -0700
|
||||
Subject: Merged: [ic] Use slow stub element handler for non-JSObjects
|
||||
|
||||
Fixed: 339736513
|
||||
(cherry picked from commit 8a69c7880844ab00ee2f32079579a040a87eedca)
|
||||
|
||||
Change-Id: If87462eb044c194798a32cb25a5f3648ff823196
|
||||
Reviewed-on: https://chromium-review.googlesource.com/c/v8/v8/+/5555847
|
||||
Commit-Queue: Shu-yu Guo <syg@chromium.org>
|
||||
Reviewed-by: Adam Klein <adamk@chromium.org>
|
||||
Commit-Queue: Adam Klein <adamk@chromium.org>
|
||||
Auto-Submit: Shu-yu Guo <syg@chromium.org>
|
||||
Cr-Commit-Position: refs/branch-heads/12.4@{#36}
|
||||
Cr-Branched-From: 309640da62fae0485c7e4f64829627c92d53b35d-refs/heads/12.4.254@{#1}
|
||||
Cr-Branched-From: 5dc24701432278556a9829d27c532f974643e6df-refs/heads/main@{#92862}
|
||||
|
||||
diff --git a/src/ic/ic.cc b/src/ic/ic.cc
|
||||
index 61bb82aff98e4273b651801b875416c686de872e..34cf7eb6d2f5ef74b37103a6ee2356b8825d3f58 100644
|
||||
--- a/src/ic/ic.cc
|
||||
+++ b/src/ic/ic.cc
|
||||
@@ -2349,15 +2349,16 @@ Handle<Object> KeyedStoreIC::StoreElementHandler(
|
||||
isolate()),
|
||||
IsStoreInArrayLiteralIC());
|
||||
|
||||
- if (IsJSProxyMap(*receiver_map)) {
|
||||
+ if (!IsJSObjectMap(*receiver_map)) {
|
||||
// DefineKeyedOwnIC, which is used to define computed fields in instances,
|
||||
- // should be handled by the slow stub.
|
||||
- if (IsDefineKeyedOwnIC()) {
|
||||
- TRACE_HANDLER_STATS(isolate(), KeyedStoreIC_SlowStub);
|
||||
- return StoreHandler::StoreSlow(isolate(), store_mode);
|
||||
+ // should handled by the slow stub below instead of the proxy stub.
|
||||
+ if (IsJSProxyMap(*receiver_map) && !IsDefineKeyedOwnIC()) {
|
||||
+ return StoreHandler::StoreProxy(isolate());
|
||||
}
|
||||
|
||||
- return StoreHandler::StoreProxy(isolate());
|
||||
+ // Wasm objects or other kind of special objects go through the slow stub.
|
||||
+ TRACE_HANDLER_STATS(isolate(), KeyedStoreIC_SlowStub);
|
||||
+ return StoreHandler::StoreSlow(isolate(), store_mode);
|
||||
}
|
||||
|
||||
// TODO(ishell): move to StoreHandler::StoreElement().
|
||||
Reference in New Issue
Block a user