[PATCH] D98610: [RISCV] Support clang -fpatchable-function-entry && GNU function attribute 'patchable_function_entry'

2021-03-16 Thread Fangrui Song via Phabricator via cfe-commits
This revision was landed with ongoing or failed builds.
This revision was automatically updated to reflect the committed changes.
Closed by commit rG6ab892793185: [RISCV] Support clang 
-fpatchable-function-entry && GNU function attribute… (authored by 
MaskRay).

Repository:
  rG LLVM Github Monorepo

CHANGES SINCE LAST ACTION
  https://reviews.llvm.org/D98610/new/

https://reviews.llvm.org/D98610

Files:
  clang/include/clang/Basic/Attr.td
  clang/include/clang/Basic/AttrDocs.td
  clang/lib/Driver/ToolChains/Clang.cpp
  clang/test/Driver/fpatchable-function-entry.c
  clang/test/Sema/patchable-function-entry-attr.cpp
  llvm/lib/Target/RISCV/RISCV.h
  llvm/lib/Target/RISCV/RISCVAsmPrinter.cpp
  llvm/lib/Target/RISCV/RISCVInstrInfo.cpp
  llvm/lib/Target/RISCV/RISCVInstrInfo.h
  llvm/lib/Target/RISCV/RISCVMCInstLower.cpp
  llvm/test/CodeGen/RISCV/patchable-function-entry.ll

Index: llvm/test/CodeGen/RISCV/patchable-function-entry.ll
===
--- /dev/null
+++ llvm/test/CodeGen/RISCV/patchable-function-entry.ll
@@ -0,0 +1,71 @@
+;; Test the function attribute "patchable-function-entry".
+; RUN: llc -mtriple=riscv32 --riscv-no-aliases < %s | FileCheck %s --check-prefixes=CHECK,RV32,NORVC
+; RUN: llc -mtriple=riscv64 --riscv-no-aliases < %s | FileCheck %s --check-prefixes=CHECK,RV64,NORVC
+; RUN: llc -mtriple=riscv32 -mattr=+c --riscv-no-aliases < %s | FileCheck %s --check-prefixes=CHECK,RV32,RVC
+; RUN: llc -mtriple=riscv64 -mattr=+c --riscv-no-aliases < %s | FileCheck %s --check-prefixes=CHECK,RV64,RVC
+
+define void @f0() "patchable-function-entry"="0" {
+; CHECK-LABEL: f0:
+; CHECK-NEXT:  .Lfunc_begin0:
+; CHECK-NOT: {{addi|c.nop}}
+; NORVC: jalr zero, 0(ra)
+; RVC:   c.jr ra
+; CHECK-NOT:   .section __patchable_function_entries
+  ret void
+}
+
+define void @f1() "patchable-function-entry"="1" {
+; CHECK-LABEL: f1:
+; CHECK-NEXT: .Lfunc_begin1:
+; NORVC: addi zero, zero, 0
+; NORVC-NEXT:jalr zero, 0(ra)
+; RVC:   c.nop
+; RVC-NEXT:  c.jr ra
+; CHECK:   .section __patchable_function_entries,"awo",@progbits,f1{{$}}
+; 32:  .p2align 2
+; 32-NEXT: .word .Lfunc_begin1
+; 64:  .p2align 3
+; 64-NEXT: .quad .Lfunc_begin1
+  ret void
+}
+
+$f5 = comdat any
+define void @f5() "patchable-function-entry"="5" comdat {
+; CHECK-LABEL: f5:
+; CHECK-NEXT:  .Lfunc_begin2:
+; NORVC-COUNT-5: addi zero, zero, 0
+; NORVC-NEXT:jalr zero, 0(ra)
+; RVC-COUNT-5:   c.nop
+; RVC-NEXT:  c.jr ra
+; CHECK:   .section __patchable_function_entries,"aGwo",@progbits,f5,comdat,f5{{$}}
+; RV32:.p2align 2
+; RV32-NEXT:   .word .Lfunc_begin2
+; RV64:.p2align 3
+; RV64-NEXT:   .quad .Lfunc_begin2
+  ret void
+}
+
+;; -fpatchable-function-entry=3,2
+;; "patchable-function-prefix" emits data before the function entry label.
+define void @f3_2() "patchable-function-entry"="1" "patchable-function-prefix"="2" {
+; CHECK-LABEL: .type f3_2,@function
+; CHECK-NEXT:  .Ltmp0: # @f3_2
+; NORVC-COUNT-2: addi zero, zero, 0
+; RVC-COUNT-2:   c.nop
+; CHECK-NEXT:  f3_2:
+; CHECK:   # %bb.0:
+; NORVC-NEXT:addi zero, zero, 0
+; NORVC-NEXT:addi sp, sp, -16
+; RVC-NEXT:  c.nop
+; RVC-NEXT:  c.addi sp, -16
+;; .size does not include the prefix.
+; CHECK:  .Lfunc_end3:
+; CHECK-NEXT: .size f3_2, .Lfunc_end3-f3_2
+; CHECK:  .section __patchable_function_entries,"awo",@progbits,f3_2{{$}}
+; RV32:   .p2align 2
+; RV32-NEXT:  .word .Ltmp0
+; RV64:   .p2align 3
+; RV64-NEXT:  .quad .Ltmp0
+  %frame = alloca i8, i32 16
+  ret void
+}
Index: llvm/lib/Target/RISCV/RISCVMCInstLower.cpp
===
--- llvm/lib/Target/RISCV/RISCVMCInstLower.cpp
+++ llvm/lib/Target/RISCV/RISCVMCInstLower.cpp
@@ -204,10 +204,10 @@
   return true;
 }
 
-void llvm::LowerRISCVMachineInstrToMCInst(const MachineInstr *MI, MCInst &OutMI,
-  const AsmPrinter &AP) {
+bool llvm::lowerRISCVMachineInstrToMCInst(const MachineInstr *MI, MCInst &OutMI,
+  AsmPrinter &AP) {
   if (lowerRISCVVMachineInstrToMCInst(MI, OutMI))
-return;
+return false;
 
   OutMI.setOpcode(MI->getOpcode());
 
@@ -217,19 +217,32 @@
   OutMI.addOperand(MCOp);
   }
 
-  if (OutMI.getOpcode() == RISCV::PseudoReadVLENB) {
+  switch (OutMI.getOpcode()) {
+  case TargetOpcode::PATCHABLE_FUNCTION_ENTER: {
+const Function &F = MI->getParent()->getParent()->getFunction();
+if (F.hasFnAttribute("patchable-function-entry")) {
+  unsigned Num;
+  if (F.getFnAttribute("patchable-function-entry")
+  .getValueAsString()
+  .getAsInteger(10, Num))
+return false;
+  AP.emitNops(Num);
+  return true;
+}
+break;
+  }
+  case RISCV::PseudoReadVLENB:
 OutMI.setOpcode(RISCV::CSRRS);
 OutMI.addOperand(MCOperand::createImm(
 RISCVSysReg::l

[PATCH] D98610: [RISCV] Support clang -fpatchable-function-entry && GNU function attribute 'patchable_function_entry'

2021-03-15 Thread Fangrui Song via Phabricator via cfe-commits
MaskRay added inline comments.



Comment at: llvm/test/CodeGen/RISCV/patchable-function-entry.ll:24
+; RVC-NEXT:  c.jr ra
+; CHECK:   .section __patchable_function_entries,"awo",@progbits,f1{{$}}
+; 32:  .p2align 2

jrtc27 wrote:
> Is there a benefit from treating these like labels with CHECK-LABEL?
I don't find a difference regarding the diagnostic.

The `:29:2: note: possible intended match here\n.section 
__patchable_function_entries,"awo",@progbits,f1` lines do not change. So 
`-LABEL:` does not improve diagnostic.


Repository:
  rG LLVM Github Monorepo

CHANGES SINCE LAST ACTION
  https://reviews.llvm.org/D98610/new/

https://reviews.llvm.org/D98610

___
cfe-commits mailing list
cfe-commits@lists.llvm.org
https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits


[PATCH] D98610: [RISCV] Support clang -fpatchable-function-entry && GNU function attribute 'patchable_function_entry'

2021-03-15 Thread Fangrui Song via Phabricator via cfe-commits
MaskRay updated this revision to Diff 330759.
MaskRay marked 5 inline comments as done.
MaskRay added a comment.

Change check prefixes from 32/64 to RV32/RV64

Rebase and use `MCInst getNop`


Repository:
  rG LLVM Github Monorepo

CHANGES SINCE LAST ACTION
  https://reviews.llvm.org/D98610/new/

https://reviews.llvm.org/D98610

Files:
  clang/include/clang/Basic/Attr.td
  clang/include/clang/Basic/AttrDocs.td
  clang/lib/Driver/ToolChains/Clang.cpp
  clang/test/Driver/fpatchable-function-entry.c
  clang/test/Sema/patchable-function-entry-attr.cpp
  llvm/lib/Target/RISCV/RISCV.h
  llvm/lib/Target/RISCV/RISCVAsmPrinter.cpp
  llvm/lib/Target/RISCV/RISCVInstrInfo.cpp
  llvm/lib/Target/RISCV/RISCVInstrInfo.h
  llvm/lib/Target/RISCV/RISCVMCInstLower.cpp
  llvm/test/CodeGen/RISCV/patchable-function-entry.ll

Index: llvm/test/CodeGen/RISCV/patchable-function-entry.ll
===
--- /dev/null
+++ llvm/test/CodeGen/RISCV/patchable-function-entry.ll
@@ -0,0 +1,71 @@
+;; Test the function attribute "patchable-function-entry".
+; RUN: llc -mtriple=riscv32 --riscv-no-aliases < %s | FileCheck %s --check-prefixes=CHECK,RV32,NORVC
+; RUN: llc -mtriple=riscv64 --riscv-no-aliases < %s | FileCheck %s --check-prefixes=CHECK,RV64,NORVC
+; RUN: llc -mtriple=riscv32 -mattr=+c --riscv-no-aliases < %s | FileCheck %s --check-prefixes=CHECK,RV32,RVC
+; RUN: llc -mtriple=riscv64 -mattr=+c --riscv-no-aliases < %s | FileCheck %s --check-prefixes=CHECK,RV64,RVC
+
+define void @f0() "patchable-function-entry"="0" {
+; CHECK-LABEL: f0:
+; CHECK-NEXT:  .Lfunc_begin0:
+; CHECK-NOT: {{addi|c.nop}}
+; NORVC: jalr zero, 0(ra)
+; RVC:   c.jr ra
+; CHECK-NOT:   .section __patchable_function_entries
+  ret void
+}
+
+define void @f1() "patchable-function-entry"="1" {
+; CHECK-LABEL: f1:
+; CHECK-NEXT: .Lfunc_begin1:
+; NORVC: addi zero, zero, 0
+; NORVC-NEXT:jalr zero, 0(ra)
+; RVC:   c.nop
+; RVC-NEXT:  c.jr ra
+; CHECK:   .section __patchable_function_entries,"awo",@progbits,f1{{$}}
+; 32:  .p2align 2
+; 32-NEXT: .word .Lfunc_begin1
+; 64:  .p2align 3
+; 64-NEXT: .quad .Lfunc_begin1
+  ret void
+}
+
+$f5 = comdat any
+define void @f5() "patchable-function-entry"="5" comdat {
+; CHECK-LABEL: f5:
+; CHECK-NEXT:  .Lfunc_begin2:
+; NORVC-COUNT-5: addi zero, zero, 0
+; NORVC-NEXT:jalr zero, 0(ra)
+; RVC-COUNT-5:   c.nop
+; RVC-NEXT:  c.jr ra
+; CHECK:   .section __patchable_function_entries,"aGwo",@progbits,f5,comdat,f5{{$}}
+; RV32:.p2align 2
+; RV32-NEXT:   .word .Lfunc_begin2
+; RV64:.p2align 3
+; RV64-NEXT:   .quad .Lfunc_begin2
+  ret void
+}
+
+;; -fpatchable-function-entry=3,2
+;; "patchable-function-prefix" emits data before the function entry label.
+define void @f3_2() "patchable-function-entry"="1" "patchable-function-prefix"="2" {
+; CHECK-LABEL: .type f3_2,@function
+; CHECK-NEXT:  .Ltmp0: # @f3_2
+; NORVC-COUNT-2: addi zero, zero, 0
+; RVC-COUNT-2:   c.nop
+; CHECK-NEXT:  f3_2:
+; CHECK:   # %bb.0:
+; NORVC-NEXT:addi zero, zero, 0
+; NORVC-NEXT:addi sp, sp, -16
+; RVC-NEXT:  c.nop
+; RVC-NEXT:  c.addi sp, -16
+;; .size does not include the prefix.
+; CHECK:  .Lfunc_end3:
+; CHECK-NEXT: .size f3_2, .Lfunc_end3-f3_2
+; CHECK:  .section __patchable_function_entries,"awo",@progbits,f3_2{{$}}
+; RV32:   .p2align 2
+; RV32-NEXT:  .word .Ltmp0
+; RV64:   .p2align 3
+; RV64-NEXT:  .quad .Ltmp0
+  %frame = alloca i8, i32 16
+  ret void
+}
Index: llvm/lib/Target/RISCV/RISCVMCInstLower.cpp
===
--- llvm/lib/Target/RISCV/RISCVMCInstLower.cpp
+++ llvm/lib/Target/RISCV/RISCVMCInstLower.cpp
@@ -204,10 +204,10 @@
   return true;
 }
 
-void llvm::LowerRISCVMachineInstrToMCInst(const MachineInstr *MI, MCInst &OutMI,
-  const AsmPrinter &AP) {
+bool llvm::lowerRISCVMachineInstrToMCInst(const MachineInstr *MI, MCInst &OutMI,
+  AsmPrinter &AP) {
   if (lowerRISCVVMachineInstrToMCInst(MI, OutMI))
-return;
+return false;
 
   OutMI.setOpcode(MI->getOpcode());
 
@@ -217,19 +217,32 @@
   OutMI.addOperand(MCOp);
   }
 
-  if (OutMI.getOpcode() == RISCV::PseudoReadVLENB) {
+  switch (OutMI.getOpcode()) {
+  case TargetOpcode::PATCHABLE_FUNCTION_ENTER: {
+const Function &F = MI->getParent()->getParent()->getFunction();
+if (F.hasFnAttribute("patchable-function-entry")) {
+  unsigned Num;
+  if (F.getFnAttribute("patchable-function-entry")
+  .getValueAsString()
+  .getAsInteger(10, Num))
+return false;
+  AP.emitNops(Num);
+  return true;
+}
+break;
+  }
+  case RISCV::PseudoReadVLENB:
 OutMI.setOpcode(RISCV::CSRRS);
 OutMI.addOperand(MCOperand::createImm(
 RISCVSysReg::lookupSysRegByName("VLENB")->Encoding));
 OutMI.addOperand(MCOperand

[PATCH] D98610: [RISCV] Support clang -fpatchable-function-entry && GNU function attribute 'patchable_function_entry'

2021-03-15 Thread Jessica Clarke via Phabricator via cfe-commits
jrtc27 added inline comments.



Comment at: llvm/lib/Target/RISCV/RISCVInstrInfo.cpp:53
 
+void RISCVInstrInfo::getNoop(MCInst &NopInst) const {
+  if (STI.getFeatureBits()[RISCV::FeatureStdExtC])

MaskRay wrote:
> jrtc27 wrote:
> > I will forever wonder why TII didn't make it `MCInst getNoop()`...
> Let me do a refactoring before this patch?
Definitely won't complain if you're volunteering to fix it to be a saner 
interface :)



Comment at: llvm/lib/Target/RISCV/RISCVMCInstLower.cpp:247
   }
+  return false;
 }

MaskRay wrote:
> jrtc27 wrote:
> > true, surely?
> false.
> 
> We want to call `EmitToStreamer(*OutStreamer, TmpInst);`
> 
> If a pseudo instruction is not handled here, in MCAsmStreamer we will see its 
> comment (`AsmString`).
Ok, yes, I agree now, worked out what's going on



Comment at: llvm/test/CodeGen/RISCV/patchable-function-entry.ll:24
+; RVC-NEXT:  c.jr ra
+; CHECK:   .section __patchable_function_entries,"awo",@progbits,f1{{$}}
+; 32:  .p2align 2

Is there a benefit from treating these like labels with CHECK-LABEL?



Comment at: llvm/test/CodeGen/RISCV/patchable-function-entry.ll:1-3
+;; Test the function attribute "patchable-function-entry".
+; RUN: llc -mtriple=riscv32 < %s | FileCheck %s --check-prefixes=CHECK,32
+; RUN: llc -mtriple=riscv64 < %s | FileCheck %s --check-prefixes=CHECK,64

jrtc27 wrote:
> MaskRay wrote:
> > jrtc27 wrote:
> > > luismarques wrote:
> > > > jrtc27 wrote:
> > > > > Please match the style of the other tests: 
> > > > > - update_llc_test_checks.py
> > > > > - RV32I/RV32IC/RV64I/RV64IC
> > > > > Please match the style of the other tests: 
> > > > > - update_llc_test_checks.py
> > > > 
> > > > I was going to comment on that but I was unsure it applied here, given 
> > > > that this test was running more than just `llc`. The other RISC-V 
> > > > CodeGen tests we have with objdump don't use the update script IIRC. 
> > > > (And these manual tests were neatly written and much more condensed 
> > > > that the sprawling output of the auto updated checks). But I agree that 
> > > > in general using the script is the way to go for the RISC-V tests.
> > > Yeah, though as you'll see in my comment below I don't think using 
> > > llvm-objdump adds any value, at which point UTC works just fine.
> > I do not think we can use `update_llc_test_checks.py`. We should test 
> > `__patchable_function_entries` which can be scrubbed by 
> > `update_llc_test_checks.py`.
> > 
> > The test is written in such a way with low maintenance: it will very 
> > unlikely change due to codegen differences. (The one `; CHECK-NEXT:addi 
> > sp, sp, -16` below is the only exception.)
> > 
> > Testing more variants seems wasteful.
> > 
> Testing more variants is not wasteful if you can unify the compressed 
> checking RUN lines below with these ones. There would only be 4 separate RUN 
> lines in total, one for each, checking the assembly output (without aliases).
Ok now please use RV32/RV64 rather than bare 32/64 to be more consistent with 
existing tests


Repository:
  rG LLVM Github Monorepo

CHANGES SINCE LAST ACTION
  https://reviews.llvm.org/D98610/new/

https://reviews.llvm.org/D98610

___
cfe-commits mailing list
cfe-commits@lists.llvm.org
https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits


[PATCH] D98610: [RISCV] Support clang -fpatchable-function-entry && GNU function attribute 'patchable_function_entry'

2021-03-15 Thread Fangrui Song via Phabricator via cfe-commits
MaskRay added inline comments.



Comment at: llvm/lib/Target/RISCV/RISCVInstrInfo.cpp:53
 
+void RISCVInstrInfo::getNoop(MCInst &NopInst) const {
+  if (STI.getFeatureBits()[RISCV::FeatureStdExtC])

jrtc27 wrote:
> I will forever wonder why TII didn't make it `MCInst getNoop()`...
Let me do a refactoring before this patch?


Repository:
  rG LLVM Github Monorepo

CHANGES SINCE LAST ACTION
  https://reviews.llvm.org/D98610/new/

https://reviews.llvm.org/D98610

___
cfe-commits mailing list
cfe-commits@lists.llvm.org
https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits


[PATCH] D98610: [RISCV] Support clang -fpatchable-function-entry && GNU function attribute 'patchable_function_entry'

2021-03-15 Thread Fangrui Song via Phabricator via cfe-commits
MaskRay updated this revision to Diff 330744.
MaskRay marked 8 inline comments as done.
MaskRay added a comment.

Mention supported targets in clang/include/clang/Basic/AttrDocs.td

Use 4 llc RUN lines and --riscv-no-aliases


Repository:
  rG LLVM Github Monorepo

CHANGES SINCE LAST ACTION
  https://reviews.llvm.org/D98610/new/

https://reviews.llvm.org/D98610

Files:
  clang/include/clang/Basic/Attr.td
  clang/include/clang/Basic/AttrDocs.td
  clang/lib/Driver/ToolChains/Clang.cpp
  clang/test/Driver/fpatchable-function-entry.c
  clang/test/Sema/patchable-function-entry-attr.cpp
  llvm/lib/Target/RISCV/RISCV.h
  llvm/lib/Target/RISCV/RISCVAsmPrinter.cpp
  llvm/lib/Target/RISCV/RISCVInstrInfo.cpp
  llvm/lib/Target/RISCV/RISCVInstrInfo.h
  llvm/lib/Target/RISCV/RISCVMCInstLower.cpp
  llvm/test/CodeGen/RISCV/patchable-function-entry.ll

Index: llvm/test/CodeGen/RISCV/patchable-function-entry.ll
===
--- /dev/null
+++ llvm/test/CodeGen/RISCV/patchable-function-entry.ll
@@ -0,0 +1,71 @@
+;; Test the function attribute "patchable-function-entry".
+; RUN: llc -mtriple=riscv32 --riscv-no-aliases < %s | FileCheck %s --check-prefixes=CHECK,32,NORVC
+; RUN: llc -mtriple=riscv64 --riscv-no-aliases < %s | FileCheck %s --check-prefixes=CHECK,64,NORVC
+; RUN: llc -mtriple=riscv32 -mattr=+c --riscv-no-aliases < %s | FileCheck %s --check-prefixes=CHECK,32,RVC
+; RUN: llc -mtriple=riscv64 -mattr=+c --riscv-no-aliases < %s | FileCheck %s --check-prefixes=CHECK,64,RVC
+
+define void @f0() "patchable-function-entry"="0" {
+; CHECK-LABEL: f0:
+; CHECK-NEXT:  .Lfunc_begin0:
+; CHECK-NOT: {{addi|c.nop}}
+; NORVC: jalr zero, 0(ra)
+; RVC:   c.jr ra
+; CHECK-NOT:   .section __patchable_function_entries
+  ret void
+}
+
+define void @f1() "patchable-function-entry"="1" {
+; CHECK-LABEL: f1:
+; CHECK-NEXT: .Lfunc_begin1:
+; NORVC: addi zero, zero, 0
+; NORVC-NEXT:jalr zero, 0(ra)
+; RVC:   c.nop
+; RVC-NEXT:  c.jr ra
+; CHECK:   .section __patchable_function_entries,"awo",@progbits,f1{{$}}
+; 32:  .p2align 2
+; 32-NEXT: .word .Lfunc_begin1
+; 64:  .p2align 3
+; 64-NEXT: .quad .Lfunc_begin1
+  ret void
+}
+
+$f5 = comdat any
+define void @f5() "patchable-function-entry"="5" comdat {
+; CHECK-LABEL: f5:
+; CHECK-NEXT:  .Lfunc_begin2:
+; NORVC-COUNT-5: addi zero, zero, 0
+; NORVC-NEXT:jalr zero, 0(ra)
+; RVC-COUNT-5:   c.nop
+; RVC-NEXT:  c.jr ra
+; CHECK:   .section __patchable_function_entries,"aGwo",@progbits,f5,comdat,f5{{$}}
+; 32:  .p2align 2
+; 32-NEXT: .word .Lfunc_begin2
+; 64:  .p2align 3
+; 64-NEXT: .quad .Lfunc_begin2
+  ret void
+}
+
+;; -fpatchable-function-entry=3,2
+;; "patchable-function-prefix" emits data before the function entry label.
+define void @f3_2() "patchable-function-entry"="1" "patchable-function-prefix"="2" {
+; CHECK-LABEL: .type f3_2,@function
+; CHECK-NEXT:  .Ltmp0: # @f3_2
+; NORVC-COUNT-2: addi zero, zero, 0
+; RVC-COUNT-2:   c.nop
+; CHECK-NEXT:  f3_2:
+; CHECK:   # %bb.0:
+; NORVC-NEXT:addi zero, zero, 0
+; NORVC-NEXT:addi sp, sp, -16
+; RVC-NEXT:  c.nop
+; RVC-NEXT:  c.addi sp, -16
+;; .size does not include the prefix.
+; CHECK:  .Lfunc_end3:
+; CHECK-NEXT: .size f3_2, .Lfunc_end3-f3_2
+; CHECK:  .section __patchable_function_entries,"awo",@progbits,f3_2{{$}}
+; 32: .p2align 2
+; 32-NEXT:.word .Ltmp0
+; 64: .p2align 3
+; 64-NEXT:.quad .Ltmp0
+  %frame = alloca i8, i32 16
+  ret void
+}
Index: llvm/lib/Target/RISCV/RISCVMCInstLower.cpp
===
--- llvm/lib/Target/RISCV/RISCVMCInstLower.cpp
+++ llvm/lib/Target/RISCV/RISCVMCInstLower.cpp
@@ -204,10 +204,10 @@
   return true;
 }
 
-void llvm::LowerRISCVMachineInstrToMCInst(const MachineInstr *MI, MCInst &OutMI,
-  const AsmPrinter &AP) {
+bool llvm::lowerRISCVMachineInstrToMCInst(const MachineInstr *MI, MCInst &OutMI,
+  AsmPrinter &AP) {
   if (lowerRISCVVMachineInstrToMCInst(MI, OutMI))
-return;
+return false;
 
   OutMI.setOpcode(MI->getOpcode());
 
@@ -217,19 +217,32 @@
   OutMI.addOperand(MCOp);
   }
 
-  if (OutMI.getOpcode() == RISCV::PseudoReadVLENB) {
+  switch (OutMI.getOpcode()) {
+  case TargetOpcode::PATCHABLE_FUNCTION_ENTER: {
+const Function &F = MI->getParent()->getParent()->getFunction();
+if (F.hasFnAttribute("patchable-function-entry")) {
+  unsigned Num;
+  if (F.getFnAttribute("patchable-function-entry")
+  .getValueAsString()
+  .getAsInteger(10, Num))
+return false;
+  AP.emitNops(Num);
+  return true;
+}
+break;
+  }
+  case RISCV::PseudoReadVLENB:
 OutMI.setOpcode(RISCV::CSRRS);
 OutMI.addOperand(MCOperand::createImm(
 RISCVSysReg::lookupSysRegByName("VLENB")->Encoding));
 O

[PATCH] D98610: [RISCV] Support clang -fpatchable-function-entry && GNU function attribute 'patchable_function_entry'

2021-03-15 Thread Jessica Clarke via Phabricator via cfe-commits
jrtc27 added inline comments.



Comment at: llvm/test/CodeGen/RISCV/patchable-function-entry.ll:1-3
+;; Test the function attribute "patchable-function-entry".
+; RUN: llc -mtriple=riscv32 < %s | FileCheck %s --check-prefixes=CHECK,32
+; RUN: llc -mtriple=riscv64 < %s | FileCheck %s --check-prefixes=CHECK,64

MaskRay wrote:
> jrtc27 wrote:
> > luismarques wrote:
> > > jrtc27 wrote:
> > > > Please match the style of the other tests: 
> > > > - update_llc_test_checks.py
> > > > - RV32I/RV32IC/RV64I/RV64IC
> > > > Please match the style of the other tests: 
> > > > - update_llc_test_checks.py
> > > 
> > > I was going to comment on that but I was unsure it applied here, given 
> > > that this test was running more than just `llc`. The other RISC-V CodeGen 
> > > tests we have with objdump don't use the update script IIRC. (And these 
> > > manual tests were neatly written and much more condensed that the 
> > > sprawling output of the auto updated checks). But I agree that in general 
> > > using the script is the way to go for the RISC-V tests.
> > Yeah, though as you'll see in my comment below I don't think using 
> > llvm-objdump adds any value, at which point UTC works just fine.
> I do not think we can use `update_llc_test_checks.py`. We should test 
> `__patchable_function_entries` which can be scrubbed by 
> `update_llc_test_checks.py`.
> 
> The test is written in such a way with low maintenance: it will very unlikely 
> change due to codegen differences. (The one `; CHECK-NEXT:addi sp, sp, 
> -16` below is the only exception.)
> 
> Testing more variants seems wasteful.
> 
Testing more variants is not wasteful if you can unify the compressed checking 
RUN lines below with these ones. There would only be 4 separate RUN lines in 
total, one for each, checking the assembly output (without aliases).



Comment at: llvm/test/CodeGen/RISCV/patchable-function-entry.ll:5-9
+;; RVC uses 2-byte nop.
+; RUN: llc -filetype=obj -mtriple=riscv64 %s -o %t.o
+; RUN: llvm-objdump -d %t.o | FileCheck %s --check-prefix=NORVC
+; RUN: llc -filetype=obj -mtriple=riscv64 -mattr=+c %s -o %tc.o
+; RUN: llvm-objdump -d %tc.o | FileCheck %s --check-prefix=RVC

MaskRay wrote:
> jrtc27 wrote:
> > I don't think this is particularly useful if we've checked the assembly 
> > output (and it stops us using update_llc_test_checks.py), we know nops get 
> > emitted correctly, that's tested in various other places.
> objdump -d/llvm-objdump -d does not print c.nop => it is an important detail. 
> Without it we cannot make sure the correct number of bytes is used.
Then use -riscv-no-aliases for the assembly-printing llc above, you don't need 
to go through assembling and dumping


Repository:
  rG LLVM Github Monorepo

CHANGES SINCE LAST ACTION
  https://reviews.llvm.org/D98610/new/

https://reviews.llvm.org/D98610

___
cfe-commits mailing list
cfe-commits@lists.llvm.org
https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits


[PATCH] D98610: [RISCV] Support clang -fpatchable-function-entry && GNU function attribute 'patchable_function_entry'

2021-03-15 Thread Fangrui Song via Phabricator via cfe-commits
MaskRay marked 2 inline comments as done.
MaskRay added inline comments.



Comment at: llvm/lib/Target/RISCV/RISCVMCInstLower.cpp:247
   }
+  return false;
 }

jrtc27 wrote:
> true, surely?
false.

We want to call `EmitToStreamer(*OutStreamer, TmpInst);`

If a pseudo instruction is not handled here, in MCAsmStreamer we will see its 
comment (`AsmString`).



Comment at: llvm/test/CodeGen/RISCV/patchable-function-entry.ll:1-3
+;; Test the function attribute "patchable-function-entry".
+; RUN: llc -mtriple=riscv32 < %s | FileCheck %s --check-prefixes=CHECK,32
+; RUN: llc -mtriple=riscv64 < %s | FileCheck %s --check-prefixes=CHECK,64

jrtc27 wrote:
> luismarques wrote:
> > jrtc27 wrote:
> > > Please match the style of the other tests: 
> > > - update_llc_test_checks.py
> > > - RV32I/RV32IC/RV64I/RV64IC
> > > Please match the style of the other tests: 
> > > - update_llc_test_checks.py
> > 
> > I was going to comment on that but I was unsure it applied here, given that 
> > this test was running more than just `llc`. The other RISC-V CodeGen tests 
> > we have with objdump don't use the update script IIRC. (And these manual 
> > tests were neatly written and much more condensed that the sprawling output 
> > of the auto updated checks). But I agree that in general using the script 
> > is the way to go for the RISC-V tests.
> Yeah, though as you'll see in my comment below I don't think using 
> llvm-objdump adds any value, at which point UTC works just fine.
I do not think we can use `update_llc_test_checks.py`. We should test 
`__patchable_function_entries` which can be scrubbed by 
`update_llc_test_checks.py`.

The test is written in such a way with low maintenance: it will very unlikely 
change due to codegen differences. (The one `; CHECK-NEXT:addi sp, sp, -16` 
below is the only exception.)

Testing more variants seems wasteful.




Comment at: llvm/test/CodeGen/RISCV/patchable-function-entry.ll:5-9
+;; RVC uses 2-byte nop.
+; RUN: llc -filetype=obj -mtriple=riscv64 %s -o %t.o
+; RUN: llvm-objdump -d %t.o | FileCheck %s --check-prefix=NORVC
+; RUN: llc -filetype=obj -mtriple=riscv64 -mattr=+c %s -o %tc.o
+; RUN: llvm-objdump -d %tc.o | FileCheck %s --check-prefix=RVC

jrtc27 wrote:
> I don't think this is particularly useful if we've checked the assembly 
> output (and it stops us using update_llc_test_checks.py), we know nops get 
> emitted correctly, that's tested in various other places.
objdump -d/llvm-objdump -d does not print c.nop => it is an important detail. 
Without it we cannot make sure the correct number of bytes is used.


Repository:
  rG LLVM Github Monorepo

CHANGES SINCE LAST ACTION
  https://reviews.llvm.org/D98610/new/

https://reviews.llvm.org/D98610

___
cfe-commits mailing list
cfe-commits@lists.llvm.org
https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits


[PATCH] D98610: [RISCV] Support clang -fpatchable-function-entry && GNU function attribute 'patchable_function_entry'

2021-03-15 Thread Jessica Clarke via Phabricator via cfe-commits
jrtc27 added inline comments.



Comment at: llvm/test/CodeGen/RISCV/patchable-function-entry.ll:1-3
+;; Test the function attribute "patchable-function-entry".
+; RUN: llc -mtriple=riscv32 < %s | FileCheck %s --check-prefixes=CHECK,32
+; RUN: llc -mtriple=riscv64 < %s | FileCheck %s --check-prefixes=CHECK,64

luismarques wrote:
> jrtc27 wrote:
> > Please match the style of the other tests: 
> > - update_llc_test_checks.py
> > - RV32I/RV32IC/RV64I/RV64IC
> > Please match the style of the other tests: 
> > - update_llc_test_checks.py
> 
> I was going to comment on that but I was unsure it applied here, given that 
> this test was running more than just `llc`. The other RISC-V CodeGen tests we 
> have with objdump don't use the update script IIRC. (And these manual tests 
> were neatly written and much more condensed that the sprawling output of the 
> auto updated checks). But I agree that in general using the script is the way 
> to go for the RISC-V tests.
Yeah, though as you'll see in my comment below I don't think using llvm-objdump 
adds any value, at which point UTC works just fine.


Repository:
  rG LLVM Github Monorepo

CHANGES SINCE LAST ACTION
  https://reviews.llvm.org/D98610/new/

https://reviews.llvm.org/D98610

___
cfe-commits mailing list
cfe-commits@lists.llvm.org
https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits


[PATCH] D98610: [RISCV] Support clang -fpatchable-function-entry && GNU function attribute 'patchable_function_entry'

2021-03-15 Thread Aaron Ballman via Phabricator via cfe-commits
aaron.ballman added a comment.

The attribute bits look fine to me aside from the documentation request.




Comment at: clang/include/clang/Basic/Attr.td:738
   let Args = [UnsignedArgument<"Count">, DefaultIntArgument<"Offset", 0>];
   let Documentation = [PatchableFunctionEntryDocs];
 }

We should probably add some documentation about what targets this attribute is 
supported on.


Repository:
  rG LLVM Github Monorepo

CHANGES SINCE LAST ACTION
  https://reviews.llvm.org/D98610/new/

https://reviews.llvm.org/D98610

___
cfe-commits mailing list
cfe-commits@lists.llvm.org
https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits


[PATCH] D98610: [RISCV] Support clang -fpatchable-function-entry && GNU function attribute 'patchable_function_entry'

2021-03-14 Thread Luís Marques via Phabricator via cfe-commits
luismarques added inline comments.



Comment at: llvm/test/CodeGen/RISCV/patchable-function-entry.ll:1-3
+;; Test the function attribute "patchable-function-entry".
+; RUN: llc -mtriple=riscv32 < %s | FileCheck %s --check-prefixes=CHECK,32
+; RUN: llc -mtriple=riscv64 < %s | FileCheck %s --check-prefixes=CHECK,64

jrtc27 wrote:
> Please match the style of the other tests: 
> - update_llc_test_checks.py
> - RV32I/RV32IC/RV64I/RV64IC
> Please match the style of the other tests: 
> - update_llc_test_checks.py

I was going to comment on that but I was unsure it applied here, given that 
this test was running more than just `llc`. The other RISC-V CodeGen tests we 
have with objdump don't use the update script IIRC. (And these manual tests 
were neatly written and much more condensed that the sprawling output of the 
auto updated checks). But I agree that in general using the script is the way 
to go for the RISC-V tests.


Repository:
  rG LLVM Github Monorepo

CHANGES SINCE LAST ACTION
  https://reviews.llvm.org/D98610/new/

https://reviews.llvm.org/D98610

___
cfe-commits mailing list
cfe-commits@lists.llvm.org
https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits


[PATCH] D98610: [RISCV] Support clang -fpatchable-function-entry && GNU function attribute 'patchable_function_entry'

2021-03-14 Thread Jessica Clarke via Phabricator via cfe-commits
jrtc27 added inline comments.



Comment at: llvm/lib/Target/RISCV/RISCVInstrInfo.cpp:53
 
+void RISCVInstrInfo::getNoop(MCInst &NopInst) const {
+  if (STI.getFeatureBits()[RISCV::FeatureStdExtC])

I will forever wonder why TII didn't make it `MCInst getNoop()`...



Comment at: llvm/lib/Target/RISCV/RISCVMCInstLower.cpp:247
   }
+  return false;
 }

true, surely?



Comment at: llvm/test/CodeGen/RISCV/patchable-function-entry.ll:1-3
+;; Test the function attribute "patchable-function-entry".
+; RUN: llc -mtriple=riscv32 < %s | FileCheck %s --check-prefixes=CHECK,32
+; RUN: llc -mtriple=riscv64 < %s | FileCheck %s --check-prefixes=CHECK,64

Please match the style of the other tests: 
- update_llc_test_checks.py
- RV32I/RV32IC/RV64I/RV64IC



Comment at: llvm/test/CodeGen/RISCV/patchable-function-entry.ll:5-9
+;; RVC uses 2-byte nop.
+; RUN: llc -filetype=obj -mtriple=riscv64 %s -o %t.o
+; RUN: llvm-objdump -d %t.o | FileCheck %s --check-prefix=NORVC
+; RUN: llc -filetype=obj -mtriple=riscv64 -mattr=+c %s -o %tc.o
+; RUN: llvm-objdump -d %tc.o | FileCheck %s --check-prefix=RVC

I don't think this is particularly useful if we've checked the assembly output 
(and it stops us using update_llc_test_checks.py), we know nops get emitted 
correctly, that's tested in various other places.


Repository:
  rG LLVM Github Monorepo

CHANGES SINCE LAST ACTION
  https://reviews.llvm.org/D98610/new/

https://reviews.llvm.org/D98610

___
cfe-commits mailing list
cfe-commits@lists.llvm.org
https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits


[PATCH] D98610: [RISCV] Support clang -fpatchable-function-entry && GNU function attribute 'patchable_function_entry'

2021-03-14 Thread Fangrui Song via Phabricator via cfe-commits
MaskRay updated this revision to Diff 330548.
MaskRay added a comment.

fix comment


Repository:
  rG LLVM Github Monorepo

CHANGES SINCE LAST ACTION
  https://reviews.llvm.org/D98610/new/

https://reviews.llvm.org/D98610

Files:
  clang/include/clang/Basic/Attr.td
  clang/lib/Driver/ToolChains/Clang.cpp
  clang/test/Driver/fpatchable-function-entry.c
  clang/test/Sema/patchable-function-entry-attr.cpp
  llvm/lib/Target/RISCV/RISCV.h
  llvm/lib/Target/RISCV/RISCVAsmPrinter.cpp
  llvm/lib/Target/RISCV/RISCVInstrInfo.cpp
  llvm/lib/Target/RISCV/RISCVInstrInfo.h
  llvm/lib/Target/RISCV/RISCVMCInstLower.cpp
  llvm/test/CodeGen/RISCV/patchable-function-entry.ll

Index: llvm/test/CodeGen/RISCV/patchable-function-entry.ll
===
--- /dev/null
+++ llvm/test/CodeGen/RISCV/patchable-function-entry.ll
@@ -0,0 +1,71 @@
+;; Test the function attribute "patchable-function-entry".
+; RUN: llc -mtriple=riscv32 < %s | FileCheck %s --check-prefixes=CHECK,32
+; RUN: llc -mtriple=riscv64 < %s | FileCheck %s --check-prefixes=CHECK,64
+
+;; RVC uses 2-byte nop.
+; RUN: llc -filetype=obj -mtriple=riscv64 %s -o %t.o
+; RUN: llvm-objdump -d %t.o | FileCheck %s --check-prefix=NORVC
+; RUN: llc -filetype=obj -mtriple=riscv64 -mattr=+c %s -o %tc.o
+; RUN: llvm-objdump -d %tc.o | FileCheck %s --check-prefix=RVC
+
+; NORVC: 13 00 00 00  nop
+; RVC:   01 00nop
+
+define void @f0() "patchable-function-entry"="0" {
+; CHECK-LABEL: f0:
+; CHECK-NEXT:  .Lfunc_begin0:
+; CHECK-NOT: nop
+; CHECK: ret
+; CHECK-NOT:   .section __patchable_function_entries
+  ret void
+}
+
+define void @f1() "patchable-function-entry"="1" {
+; CHECK-LABEL: f1:
+; CHECK-NEXT: .Lfunc_begin1:
+; CHECK: nop
+; CHECK-NEXT:ret
+; CHECK:   .section __patchable_function_entries,"awo",@progbits,f1{{$}}
+; 32:  .p2align 2
+; 32-NEXT: .word .Lfunc_begin1
+; 64:  .p2align 3
+; 64-NEXT: .quad .Lfunc_begin1
+  ret void
+}
+
+$f5 = comdat any
+define void @f5() "patchable-function-entry"="5" comdat {
+; CHECK-LABEL: f5:
+; CHECK-NEXT:  .Lfunc_begin2:
+; CHECK-COUNT-5: nop
+; CHECK-NEXT:ret
+; CHECK:   .section __patchable_function_entries,"aGwo",@progbits,f5,comdat,f5{{$}}
+; 32:  .p2align 2
+; 32-NEXT: .word .Lfunc_begin2
+; 64:  .p2align 3
+; 64-NEXT: .quad .Lfunc_begin2
+  ret void
+}
+
+;; -fpatchable-function-entry=3,2
+;; "patchable-function-prefix" emits data before the function entry label.
+define void @f3_2() "patchable-function-entry"="1" "patchable-function-prefix"="2" {
+; CHECK-LABEL: .type f3_2,@function
+; CHECK-NEXT:  .Ltmp0: # @f3_2
+; CHECK-NEXT:nop
+; CHECK-NEXT:nop
+; CHECK-NEXT:  f3_2:
+; CHECK:   # %bb.0:
+; CHECK-NEXT:nop
+; CHECK-NEXT:addi sp, sp, -16
+;; .size does not include the prefix.
+; CHECK:  .Lfunc_end3:
+; CHECK-NEXT: .size f3_2, .Lfunc_end3-f3_2
+; CHECK:  .section __patchable_function_entries,"awo",@progbits,f3_2{{$}}
+; 32: .p2align 2
+; 32-NEXT:.word .Ltmp0
+; 64: .p2align 3
+; 64-NEXT:.quad .Ltmp0
+  %frame = alloca i8, i32 16
+  ret void
+}
Index: llvm/lib/Target/RISCV/RISCVMCInstLower.cpp
===
--- llvm/lib/Target/RISCV/RISCVMCInstLower.cpp
+++ llvm/lib/Target/RISCV/RISCVMCInstLower.cpp
@@ -204,10 +204,10 @@
   return true;
 }
 
-void llvm::LowerRISCVMachineInstrToMCInst(const MachineInstr *MI, MCInst &OutMI,
-  const AsmPrinter &AP) {
+bool llvm::lowerRISCVMachineInstrToMCInst(const MachineInstr *MI, MCInst &OutMI,
+  AsmPrinter &AP) {
   if (lowerRISCVVMachineInstrToMCInst(MI, OutMI))
-return;
+return false;
 
   OutMI.setOpcode(MI->getOpcode());
 
@@ -217,19 +217,32 @@
   OutMI.addOperand(MCOp);
   }
 
-  if (OutMI.getOpcode() == RISCV::PseudoReadVLENB) {
+  switch (OutMI.getOpcode()) {
+  case TargetOpcode::PATCHABLE_FUNCTION_ENTER: {
+const Function &F = MI->getParent()->getParent()->getFunction();
+if (F.hasFnAttribute("patchable-function-entry")) {
+  unsigned Num;
+  if (F.getFnAttribute("patchable-function-entry")
+  .getValueAsString()
+  .getAsInteger(10, Num))
+return false;
+  AP.emitNops(Num);
+  return true;
+}
+break;
+  }
+  case RISCV::PseudoReadVLENB:
 OutMI.setOpcode(RISCV::CSRRS);
 OutMI.addOperand(MCOperand::createImm(
 RISCVSysReg::lookupSysRegByName("VLENB")->Encoding));
 OutMI.addOperand(MCOperand::createReg(RISCV::X0));
-return;
-  }
-
-  if (OutMI.getOpcode() == RISCV::PseudoReadVL) {
+break;
+  case RISCV::PseudoReadVL:
 OutMI.setOpcode(RISCV::CSRRS);
-OutMI.addOperand(MCOperand::createImm(
-RISCVSysReg::lookupSysRegByName("VL")->Encoding));
+OutMI.addOperand(
+MCOperand::createImm(RISCVSysReg::lookupSysRegByName("VL")->Encoding));
 

[PATCH] D98610: [RISCV] Support clang -fpatchable-function-entry && GNU function attribute 'patchable_function_entry'

2021-03-14 Thread Luís Marques via Phabricator via cfe-commits
luismarques accepted this revision.
luismarques added a comment.
This revision is now accepted and ready to land.

Overall LGTM.
I just don't understand what you mean with "1-byte NOPs" in the patchable 
prefix case. Regular NOPs are emitted. Please clarify the comment/patch as 
needed.


Repository:
  rG LLVM Github Monorepo

CHANGES SINCE LAST ACTION
  https://reviews.llvm.org/D98610/new/

https://reviews.llvm.org/D98610

___
cfe-commits mailing list
cfe-commits@lists.llvm.org
https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits


[PATCH] D98610: [RISCV] Support clang -fpatchable-function-entry && GNU function attribute 'patchable_function_entry'

2021-03-14 Thread Fangrui Song via Phabricator via cfe-commits
MaskRay created this revision.
MaskRay added reviewers: asb, craig.topper, HsiangKai, khchen.
Herald added subscribers: vkmr, frasercrmck, evandro, luismarques, apazos, 
sameer.abuasal, pengfei, s.egerton, Jim, benna, psnobl, jocewei, PkmX, the_o, 
brucehoult, MartinMosbeck, rogfer01, edward-jones, zzheng, jrtc27, shiva0217, 
kito-cheng, niosHD, sabuasal, simoncook, johnrusso, rbar, hiraditya, 
kristof.beyls.
Herald added a reviewer: aaron.ballman.
MaskRay requested review of this revision.
Herald added projects: clang, LLVM.
Herald added subscribers: llvm-commits, cfe-commits.

Similar to D72215  (AArch64) and D72220 
 (x86).

Recently the mainline kernel started to use -fpatchable-function-entry=8 for 
riscv (https://git.kernel.org/linus/afc76b8b80112189b6f11e67e19cf58301944814).


Repository:
  rG LLVM Github Monorepo

https://reviews.llvm.org/D98610

Files:
  clang/include/clang/Basic/Attr.td
  clang/lib/Driver/ToolChains/Clang.cpp
  clang/test/Driver/fpatchable-function-entry.c
  clang/test/Sema/patchable-function-entry-attr.cpp
  llvm/lib/Target/RISCV/RISCV.h
  llvm/lib/Target/RISCV/RISCVAsmPrinter.cpp
  llvm/lib/Target/RISCV/RISCVInstrInfo.cpp
  llvm/lib/Target/RISCV/RISCVInstrInfo.h
  llvm/lib/Target/RISCV/RISCVMCInstLower.cpp
  llvm/test/CodeGen/RISCV/patchable-function-entry.ll

Index: llvm/test/CodeGen/RISCV/patchable-function-entry.ll
===
--- /dev/null
+++ llvm/test/CodeGen/RISCV/patchable-function-entry.ll
@@ -0,0 +1,72 @@
+;; Test the function attribute "patchable-function-entry".
+; RUN: llc -mtriple=riscv32 < %s | FileCheck %s --check-prefixes=CHECK,32
+; RUN: llc -mtriple=riscv64 < %s | FileCheck %s --check-prefixes=CHECK,64
+
+; RUN: llc -filetype=obj -mtriple=riscv64 %s -o %t.o
+; RUN: llvm-objdump -d %t.o | FileCheck %s --check-prefix=NORVC
+; RUN: llc -filetype=obj -mtriple=riscv64 -mattr=+c %s -o %tc.o
+; RUN: llvm-objdump -d %tc.o | FileCheck %s --check-prefix=RVC
+
+; NORVC: 13 00 00 00  nop
+; RVC:   01 00nop
+
+define void @f0() "patchable-function-entry"="0" {
+; CHECK-LABEL: f0:
+; CHECK-NEXT:  .Lfunc_begin0:
+; CHECK-NOT: nop
+; CHECK: ret
+; CHECK-NOT:   .section __patchable_function_entries
+  ret void
+}
+
+define void @f1() "patchable-function-entry"="1" {
+; CHECK-LABEL: f1:
+; CHECK-NEXT: .Lfunc_begin1:
+; CHECK: nop
+; CHECK-NEXT:ret
+; CHECK:   .section __patchable_function_entries,"awo",@progbits,f1{{$}}
+; 32:  .p2align 2
+; 32-NEXT: .word .Lfunc_begin1
+; 64:  .p2align 3
+; 64-NEXT: .quad .Lfunc_begin1
+  ret void
+}
+
+$f5 = comdat any
+define void @f5() "patchable-function-entry"="5" comdat {
+; CHECK-LABEL: f5:
+; CHECK-NEXT:  .Lfunc_begin2:
+; CHECK-COUNT-5: nop
+; CHECK-NEXT:ret
+; CHECK:   .section __patchable_function_entries,"aGwo",@progbits,f5,comdat,f5{{$}}
+; 32:  .p2align 2
+; 32-NEXT: .word .Lfunc_begin2
+; 64:  .p2align 3
+; 64-NEXT: .quad .Lfunc_begin2
+  ret void
+}
+
+;; -fpatchable-function-entry=3,2
+;; "patchable-function-prefix" emits data before the function entry label.
+;; We emit 1-byte NOPs before the function entry, so that with a partial patch,
+;; the remaining instructions do not need to be modified.
+define void @f3_2() "patchable-function-entry"="1" "patchable-function-prefix"="2" {
+; CHECK-LABEL: .type f3_2,@function
+; CHECK-NEXT:  .Ltmp0: # @f3_2
+; CHECK-NEXT:nop
+; CHECK-NEXT:nop
+; CHECK-NEXT:  f3_2:
+; CHECK:   # %bb.0:
+; CHECK-NEXT:nop
+; CHECK-NEXT:addi sp, sp, -16
+;; .size does not include the prefix.
+; CHECK:  .Lfunc_end3:
+; CHECK-NEXT: .size f3_2, .Lfunc_end3-f3_2
+; CHECK:  .section __patchable_function_entries,"awo",@progbits,f3_2{{$}}
+; 32: .p2align 2
+; 32-NEXT:.word .Ltmp0
+; 64: .p2align 3
+; 64-NEXT:.quad .Ltmp0
+  %frame = alloca i8, i32 16
+  ret void
+}
Index: llvm/lib/Target/RISCV/RISCVMCInstLower.cpp
===
--- llvm/lib/Target/RISCV/RISCVMCInstLower.cpp
+++ llvm/lib/Target/RISCV/RISCVMCInstLower.cpp
@@ -204,10 +204,10 @@
   return true;
 }
 
-void llvm::LowerRISCVMachineInstrToMCInst(const MachineInstr *MI, MCInst &OutMI,
-  const AsmPrinter &AP) {
+bool llvm::lowerRISCVMachineInstrToMCInst(const MachineInstr *MI, MCInst &OutMI,
+  AsmPrinter &AP) {
   if (lowerRISCVVMachineInstrToMCInst(MI, OutMI))
-return;
+return false;
 
   OutMI.setOpcode(MI->getOpcode());
 
@@ -217,19 +217,32 @@
   OutMI.addOperand(MCOp);
   }
 
-  if (OutMI.getOpcode() == RISCV::PseudoReadVLENB) {
+  switch (OutMI.getOpcode()) {
+  case TargetOpcode::PATCHABLE_FUNCTION_ENTER: {
+const Function &F = MI->getParent()->getParent()->getFunction();
+if (F.hasFnAttribute("patchable-function-entry")) {
+  unsi