Skip to content

Commit f3768ab

Browse files
author
Mikhail Gudim
committed
[CFIInstrInserter] Tests for scenarios not currently handled by
`CFIInstrInserter`. We add an option to enable `CFIInstrInserter` on RISCV (`false` by default). On RISCV there exists a realistic scenario (involing scalable vectors) where we need CFIInstrInserter to handle `cfi_escape`. We add a test for that. Also, we add a test for the scenario when a callee-saved register is saved at different locations.
1 parent 81a8b20 commit f3768ab

File tree

5 files changed

+146
-1
lines changed

5 files changed

+146
-1
lines changed

llvm/lib/Target/RISCV/RISCVFrameLowering.cpp

Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -2239,3 +2239,12 @@ void RISCVFrameLowering::inlineStackProbe(MachineFunction &MF,
22392239
}
22402240
}
22412241
}
2242+
2243+
int RISCVFrameLowering::getInitialCFAOffset(const MachineFunction &MF) const {
2244+
return 0;
2245+
}
2246+
2247+
Register
2248+
RISCVFrameLowering::getInitialCFARegister(const MachineFunction &MF) const {
2249+
return RISCV::X2;
2250+
}

llvm/lib/Target/RISCV/RISCVFrameLowering.h

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -112,6 +112,8 @@ class RISCVFrameLowering : public TargetFrameLowering {
112112
const DebugLoc &DL, int64_t Amount,
113113
MachineInstr::MIFlag Flag, bool EmitCFI,
114114
bool DynAllocation) const;
115+
int getInitialCFAOffset(const MachineFunction &MF) const override;
116+
Register getInitialCFARegister(const MachineFunction &MF) const override;
115117
};
116118
} // namespace llvm
117119
#endif

llvm/lib/Target/RISCV/RISCVTargetMachine.cpp

Lines changed: 12 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -117,6 +117,11 @@ static cl::opt<bool>
117117
cl::desc("Enable Machine Pipeliner for RISC-V"),
118118
cl::init(false), cl::Hidden);
119119

120+
static cl::opt<bool> EnableCFIInstrInserter(
121+
"riscv-enable-cfi-instr-inserter",
122+
cl::desc("Enable CFI Instruction Inserter for RISC-V"), cl::init(false),
123+
cl::Hidden);
124+
120125
extern "C" LLVM_EXTERNAL_VISIBILITY void LLVMInitializeRISCVTarget() {
121126
RegisterTargetMachine<RISCVTargetMachine> X(getTheRISCV32Target());
122127
RegisterTargetMachine<RISCVTargetMachine> Y(getTheRISCV64Target());
@@ -187,7 +192,10 @@ RISCVTargetMachine::RISCVTargetMachine(const Target &T, const Triple &TT,
187192
if (TT.isOSFuchsia() && !TT.isArch64Bit())
188193
report_fatal_error("Fuchsia is only supported for 64-bit");
189194

190-
setCFIFixup(true);
195+
if (EnableCFIInstrInserter)
196+
setCFIFixup(false);
197+
else
198+
setCFIFixup(true);
191199
}
192200

193201
const RISCVSubtarget *
@@ -584,6 +592,9 @@ void RISCVPassConfig::addPreEmitPass2() {
584592
addPass(createUnpackMachineBundles([&](const MachineFunction &MF) {
585593
return MF.getFunction().getParent()->getModuleFlag("kcfi");
586594
}));
595+
596+
if (EnableCFIInstrInserter)
597+
addPass(createCFIInstrInserter());
587598
}
588599

589600
void RISCVPassConfig::addMachineSSAOptimization() {
Lines changed: 88 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,88 @@
1+
# NOTE: Assertions have been autogenerated by utils/update_mir_test_checks.py UTC_ARGS: --version 5
2+
# RUN: llc %s -mtriple=riscv64 -mattr=+v \
3+
# RUN: -run-pass=prologepilog,cfi-instr-inserter \
4+
# RUN: -riscv-enable-cfi-instr-inserter=true \
5+
# RUN: | FileCheck %s
6+
#
7+
# In this test prolog will be inserted in bb.3. We need to save the scalable vector register v1.
8+
# This will emit cfi_escape in bb.3. We need to emit the same cfi_escape in the begining of bb.2.
9+
# Currently, CFIInstrInserter doesn't handle escape, so we have wrong cfi in this example.
10+
11+
--- |
12+
13+
define riscv_vector_cc void @test0(ptr %p0, ptr %p1) #0 {
14+
entry:
15+
%v = load <4 x i32>, ptr %p0, align 16
16+
store <4 x i32> %v, ptr %p1, align 16
17+
ret void
18+
}
19+
20+
attributes #0 = { "target-features"="+v" }
21+
22+
...
23+
---
24+
name: test0
25+
tracksRegLiveness: true
26+
frameInfo:
27+
savePoint: '%bb.3'
28+
restorePoint: '%bb.2'
29+
body: |
30+
; CHECK-LABEL: name: test0
31+
; CHECK: bb.0.entry:
32+
; CHECK-NEXT: successors: %bb.3(0x40000000), %bb.1(0x40000000)
33+
; CHECK-NEXT: liveins: $x10, $x11, $v1
34+
; CHECK-NEXT: {{ $}}
35+
; CHECK-NEXT: BEQ $x10, $x0, %bb.3
36+
; CHECK-NEXT: {{ $}}
37+
; CHECK-NEXT: bb.1:
38+
; CHECK-NEXT: liveins: $v1
39+
; CHECK-NEXT: {{ $}}
40+
; CHECK-NEXT: PseudoRET
41+
; CHECK-NEXT: {{ $}}
42+
; CHECK-NEXT: bb.2:
43+
; CHECK-NEXT: successors: %bb.1(0x80000000)
44+
; CHECK-NEXT: {{ $}}
45+
; CHECK-NEXT: CFI_INSTRUCTION def_cfa_offset 16
46+
; CHECK-NEXT: $x10 = ADDI $x2, 16
47+
; CHECK-NEXT: $v1 = frame-destroy VL1RE8_V killed $x10 :: (load unknown-size from %stack.0, align 8)
48+
; CHECK-NEXT: $x10 = frame-destroy PseudoReadVLENB
49+
; CHECK-NEXT: $x2 = frame-destroy ADD $x2, killed $x10
50+
; CHECK-NEXT: frame-destroy CFI_INSTRUCTION def_cfa $x2, 16
51+
; CHECK-NEXT: frame-destroy CFI_INSTRUCTION restore $v1
52+
; CHECK-NEXT: $x2 = frame-destroy ADDI $x2, 16
53+
; CHECK-NEXT: frame-destroy CFI_INSTRUCTION def_cfa_offset 0
54+
; CHECK-NEXT: PseudoBR %bb.1
55+
; CHECK-NEXT: {{ $}}
56+
; CHECK-NEXT: bb.3:
57+
; CHECK-NEXT: successors: %bb.2(0x80000000)
58+
; CHECK-NEXT: liveins: $x10, $x11, $v1
59+
; CHECK-NEXT: {{ $}}
60+
; CHECK-NEXT: $x2 = frame-setup ADDI $x2, -16
61+
; CHECK-NEXT: frame-setup CFI_INSTRUCTION def_cfa_offset 16
62+
; CHECK-NEXT: $x12 = frame-setup PseudoReadVLENB
63+
; CHECK-NEXT: $x2 = frame-setup SUB $x2, killed $x12
64+
; CHECK-NEXT: frame-setup CFI_INSTRUCTION escape 0x0f, 0x0d, 0x72, 0x00, 0x11, 0x10, 0x22, 0x11, 0x01, 0x92, 0xa2, 0x38, 0x00, 0x1e, 0x22
65+
; CHECK-NEXT: $x12 = ADDI $x2, 16
66+
; CHECK-NEXT: frame-setup VS1R_V killed $v1, killed $x12 :: (store unknown-size into %stack.0, align 8)
67+
; CHECK-NEXT: frame-setup CFI_INSTRUCTION escape 0x10, 0x61, 0x08, 0x11, 0x7f, 0x92, 0xa2, 0x38, 0x00, 0x1e, 0x22
68+
; CHECK-NEXT: dead $x0 = PseudoVSETIVLI 4, 208 /* e32, m1, ta, ma */, implicit-def $vl, implicit-def $vtype
69+
; CHECK-NEXT: renamable $v1 = PseudoVLE32_V_M1 undef renamable $v1, killed renamable $x10, 4, 5 /* e32 */, 2 /* tu, ma */, implicit $vl, implicit $vtype
70+
; CHECK-NEXT: PseudoVSE32_V_M1 killed renamable $v1, killed renamable $x11, 4, 5 /* e32 */, implicit $vl, implicit $vtype
71+
; CHECK-NEXT: PseudoBR %bb.2
72+
bb.0.entry:
73+
liveins: $x10, $x11
74+
BEQ $x10, $x0, %bb.3
75+
76+
bb.1:
77+
PseudoRET
78+
79+
bb.2:
80+
PseudoBR %bb.1
81+
82+
bb.3:
83+
liveins: $x10, $x11
84+
dead $x0 = PseudoVSETIVLI 4, 208, implicit-def $vl, implicit-def $vtype
85+
renamable $v1 = PseudoVLE32_V_M1 undef renamable $v1, killed renamable $x10, 4, 5, 2, implicit $vl, implicit $vtype
86+
PseudoVSE32_V_M1 killed renamable $v1, killed renamable $x11, 4, 5, implicit $vl, implicit $vtype
87+
PseudoBR %bb.2
88+
...
Lines changed: 35 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,35 @@
1+
# RUN: llc %s -mtriple=riscv64 \
2+
# RUN: -run-pass=cfi-instr-inserter \
3+
# RUN: -riscv-enable-cfi-instr-inserter=true \
4+
# RUN: | FileCheck %s
5+
# XFAIL: *
6+
7+
# Technically, it is possible that the a callee-saved register is saved in different locations.
8+
# CFIInstrInserter should handle this, but currently it does not.
9+
---
10+
name: multiple_locations
11+
tracksRegLiveness: true
12+
body: |
13+
bb.0.entry:
14+
liveins: $x10, $x9, $x2
15+
BEQ $x10, $x0, %bb.3
16+
17+
bb.1:
18+
liveins: $x10, $x9, $x2
19+
$x5 = COPY $x9
20+
CFI_INSTRUCTION register $x9, $x5
21+
$x9 = COPY $x5
22+
CFI_INSTRUCTION register $x9, $x9
23+
PseudoBR %bb.3
24+
25+
bb.2:
26+
liveins: $x10, $x9, $x2
27+
SD $x10, $x2, 0 :: (store (s64))
28+
CFI_INSTRUCTION offset $x9, 0
29+
$x10 = LD $x2, 0 :: (load (s64))
30+
CFI_INSTRUCTION register $x9, $x9
31+
PseudoBR %bb.1
32+
33+
bb.3:
34+
PseudoRET
35+
...

0 commit comments

Comments
 (0)