From 9ef4814e02be8f3a4bf5b23480cb689f538ae828 Mon Sep 17 00:00:00 2001 From: Min Hsu Date: Mon, 21 Oct 2024 12:07:33 -0700 Subject: [PATCH 1/2] [RISCV] Avoid redundant SchedRead on _TIED VPseudos _TIED and _MASK_TIED pseudos have one less operand compared to other pseudos, thus we shouldn't attach the same number of SchedRead for these instructions. --- llvm/lib/Target/RISCV/RISCVInstrInfoV.td | 17 +++++++++++++++-- 1 file changed, 15 insertions(+), 2 deletions(-) diff --git a/llvm/lib/Target/RISCV/RISCVInstrInfoV.td b/llvm/lib/Target/RISCV/RISCVInstrInfoV.td index 4e8619c5ec239..e63a23899152f 100644 --- a/llvm/lib/Target/RISCV/RISCVInstrInfoV.td +++ b/llvm/lib/Target/RISCV/RISCVInstrInfoV.td @@ -104,13 +104,26 @@ class SchedCommon writes, list reads, string mx = "WorstCase", int sew = 0, bit forceMasked = 0, bit forcePassthruRead = 0> : Sched<[]> { defvar isMasked = !ne(!find(NAME, "_MASK"), -1); + defvar isTied = !ne(!find(NAME, "_TIED"), -1); defvar isMaskedOrForceMasked = !or(forceMasked, isMasked); + defvar isTiedMasked = !and(isMaskedOrForceMasked, isTied); defvar passthruRead = !if(!or(!eq(mx, "WorstCase"), !eq(sew, 0)), !cast("ReadVPassthru_" # mx), !cast("ReadVPassthru_" # mx # "_E" #sew)); - defvar needsPassthruRead = !or(isMaskedOrForceMasked, forcePassthruRead); + // We don't need passthru operand if it's already _TIED without mask. + defvar needsForcePassthruRead = !and(forcePassthruRead, !not(isTied)); + defvar needsPassthruRead = !or(isMaskedOrForceMasked, needsForcePassthruRead); + // If this is a _TIED + masked operation, $rs2 (i.e. the first operand) is + // merged with the mask. + // NOTE: the following if statement is written in such a weird way because + // TableGen's `!if` doesn't have a proper short-circuit behavior, so if the + // predicate of this `!if` cannot be resolved right away, `!tail(reads)` will + // still be resolved right away even when `reads` is empty, which leads to + // an assertion failure. + defvar readsWithTiedMask = + !if(isTiedMasked, !if(!not(!empty(reads)), !tail(reads), reads), reads); defvar readsWithMask = - !if(isMaskedOrForceMasked, !listconcat(reads, [ReadVMask]), reads); + !if(isMaskedOrForceMasked, !listconcat(readsWithTiedMask, [ReadVMask]), reads); defvar allReads = !if(needsPassthruRead, !listconcat([passthruRead], readsWithMask), reads); let SchedRW = !listconcat(writes, allReads); From 10c049e6503c9ecfc98c2941d2996b3304e6a986 Mon Sep 17 00:00:00 2001 From: Min Hsu Date: Mon, 28 Oct 2024 10:37:57 -0700 Subject: [PATCH 2/2] Add more clarifications in the comments --- llvm/lib/Target/RISCV/RISCVInstrInfoV.td | 8 +++++--- 1 file changed, 5 insertions(+), 3 deletions(-) diff --git a/llvm/lib/Target/RISCV/RISCVInstrInfoV.td b/llvm/lib/Target/RISCV/RISCVInstrInfoV.td index e63a23899152f..8e0c4826ac00d 100644 --- a/llvm/lib/Target/RISCV/RISCVInstrInfoV.td +++ b/llvm/lib/Target/RISCV/RISCVInstrInfoV.td @@ -116,9 +116,11 @@ class SchedCommon writes, list reads, // If this is a _TIED + masked operation, $rs2 (i.e. the first operand) is // merged with the mask. // NOTE: the following if statement is written in such a weird way because - // TableGen's `!if` doesn't have a proper short-circuit behavior, so if the - // predicate of this `!if` cannot be resolved right away, `!tail(reads)` will - // still be resolved right away even when `reads` is empty, which leads to + // should we want to write something like + // `!if(!and(!not(!empty(reads), isTiedMasked), !tail(reads), reads)` + // since `!if` doesn't have a proper short-circuit behavior, if the + // condition of this `!if` cannot be resolved right away, `!tail(reads)` will + // be immediately evaluated anyway even when `reads` is empty, which leads to // an assertion failure. defvar readsWithTiedMask = !if(isTiedMasked, !if(!not(!empty(reads)), !tail(reads), reads), reads);