diff options
| author | Yonghong Song <yhs@fb.com> | 2019-10-24 22:57:06 -0700 |
|---|---|---|
| committer | Yonghong Song <yhs@fb.com> | 2019-10-25 14:27:25 -0700 |
| commit | a27c998c0060eef006ca9e225e4d12a35f4d1912 (patch) | |
| tree | 87a605f6ca4cc41d8712ca36395b2cd30ad9445f /llvm/lib/Target | |
| parent | e070cf81196d2415f2f64ddbdfed9a49d9b96245 (diff) | |
| download | bcm5719-llvm-a27c998c0060eef006ca9e225e4d12a35f4d1912.tar.gz bcm5719-llvm-a27c998c0060eef006ca9e225e4d12a35f4d1912.zip | |
[BPF] fix a CO-RE issue with -mattr=+alu32
Ilya Leoshkevich (<iii@linux.ibm.com>) reported an issue that
with -mattr=+alu32 CO-RE has a segfault in BPF MISimplifyPatchable
pass.
The pattern will be transformed by MISimplifyPatchable
pass looks like below:
r5 = ld_imm64 @"b:0:0$0:0"
r2 = ldw r5, 0
... r2 ... // use r2
The pass will remove the intermediate 'ldw' instruction
and replacing all r2 with r5 likes below:
r5 = ld_imm64 @"b:0:0$0:0"
... r5 ... // use r5
Later, the ld_imm64 insn will be replaced with
r5 = <patched immediate>
for field relocation purpose.
With -mattr=+alu32, the input code may become
r5 = ld_imm64 @"b:0:0$0:0"
w2 = ldw32 r5, 0
... w2 ... // use w2
Replacing "w2" with "r5" is incorrect and will
trigger compiler internal errors.
To fix the problem, if the register class of ldw* dest
register is sub_32, we just replace the original ldw*
register with:
w2 = w5
Directly replacing all uses of w2 with in-place
constructed w5 for the use operand seems not working in all cases.
The latest kernel will have -mattr=+alu32 on by default,
so added this flag to all CORE tests.
Tested with latest kernel bpf-next branch as well with this patch.
Differential Revision: https://reviews.llvm.org/D69438
Diffstat (limited to 'llvm/lib/Target')
| -rw-r--r-- | llvm/lib/Target/BPF/BPFMISimplifyPatchable.cpp | 15 |
1 files changed, 10 insertions, 5 deletions
diff --git a/llvm/lib/Target/BPF/BPFMISimplifyPatchable.cpp b/llvm/lib/Target/BPF/BPFMISimplifyPatchable.cpp index 9c689aed641..d21b977af90 100644 --- a/llvm/lib/Target/BPF/BPFMISimplifyPatchable.cpp +++ b/llvm/lib/Target/BPF/BPFMISimplifyPatchable.cpp @@ -124,11 +124,16 @@ bool BPFMISimplifyPatchable::removeLD() { if (!IsCandidate) continue; - auto Begin = MRI->use_begin(DstReg), End = MRI->use_end(); - decltype(End) NextI; - for (auto I = Begin; I != End; I = NextI) { - NextI = std::next(I); - I->setReg(SrcReg); + if (MRI->getRegClass(DstReg) == &BPF::GPR32RegClass) { + BuildMI(MBB, MI, MI.getDebugLoc(), TII->get(BPF::COPY), DstReg) + .addReg(SrcReg, 0, BPF::sub_32); + } else { + auto Begin = MRI->use_begin(DstReg), End = MRI->use_end(); + decltype(End) NextI; + for (auto I = Begin; I != End; I = NextI) { + NextI = std::next(I); + I->setReg(SrcReg); + } } ToErase = &MI; |

