[all-commits] [llvm/llvm-project] 6657d4: [TTI][RISCV] Unconditionally break critical edges ...
Philip Reames via All-commits
all-commits at lists.llvm.org
Mon Nov 25 18:59:53 PST 2024
Branch: refs/heads/main
Home: https://github.com/llvm/llvm-project
Commit: 6657d4bd70523e6852f07f64711fb15bdf7b347a
https://github.com/llvm/llvm-project/commit/6657d4bd70523e6852f07f64711fb15bdf7b347a
Author: Philip Reames <preames at rivosinc.com>
Date: 2024-11-25 (Mon, 25 Nov 2024)
Changed paths:
M llvm/include/llvm/CodeGen/TargetInstrInfo.h
M llvm/lib/CodeGen/MachineSink.cpp
M llvm/lib/Target/RISCV/RISCVInstrInfo.h
M llvm/test/CodeGen/RISCV/GlobalISel/double-convert.ll
M llvm/test/CodeGen/RISCV/GlobalISel/float-convert.ll
M llvm/test/CodeGen/RISCV/GlobalISel/rv64zbb.ll
M llvm/test/CodeGen/RISCV/aext-to-sext.ll
M llvm/test/CodeGen/RISCV/compress-opt-select.ll
M llvm/test/CodeGen/RISCV/machine-sink-load-immediate.ll
M llvm/test/CodeGen/RISCV/rv64m-w-insts-legalization.ll
M llvm/test/CodeGen/RISCV/select-const.ll
M llvm/test/CodeGen/RISCV/select.ll
M llvm/test/CodeGen/RISCV/sextw-removal.ll
M llvm/test/CodeGen/RISCV/typepromotion-overflow.ll
Log Message:
-----------
[TTI][RISCV] Unconditionally break critical edges to sink ADDI (#108889)
This looks like a rather weird change, so let me explain why this isn't
as unreasonable as it looks. Let's start with the problem it's solving.
```
define signext i32 @overlap_live_ranges(ptr %arg, i32 signext %arg1) { bb:
%i = icmp eq i32 %arg1, 1
br i1 %i, label %bb2, label %bb5
bb2: ; preds = %bb
%i3 = getelementptr inbounds nuw i8, ptr %arg, i64 4
%i4 = load i32, ptr %i3, align 4
br label %bb5
bb5: ; preds = %bb2, %bb
%i6 = phi i32 [ %i4, %bb2 ], [ 13, %bb ]
ret i32 %i6
}
```
Right now, we codegen this as:
```
li a3, 1
li a2, 13
bne a1, a3, .LBB0_2
lw a2, 4(a0)
.LBB0_2:
mv a0, a2
ret
```
In this example, we have two values which must be assigned to a0 per the
ABI (%arg, and the return value). SelectionDAG ensures that all values
used in a successor phi are defined before exit the predecessor block.
This creates an ADDI to materialize the immediate in the entry block.
Currently, this ADDI is not sunk into the tail block because we'd have
to split a critical edges to do so. Note that if our immediate was
anything large enough to require two instructions we *would* split this
critical edge.
Looking at other targets, we notice that they don't seem to have this
problem. They perform the sinking, and tail duplication that we don't.
Why? Well, it turns out for AArch64 that this is entirely an accident of
the existance of the gpr32all register class. The immediate is
materialized into the gpr32 class, and then copied into the gpr32all
register class. The existance of that copy puts us right back into the
two instruction case noted above.
This change essentially just bypasses this emergent behavior aspect of
the aarch64 behavior, and implements the same "always sink immediates"
behavior for RISCV as well.
To unsubscribe from these emails, change your notification settings at https://github.com/llvm/llvm-project/settings/notifications
More information about the All-commits
mailing list