diff --git a/llvm/lib/CodeGen/GCRootLowering.cpp b/llvm/lib/CodeGen/GCRootLowering.cpp index 894ab9a0486a7..0d82f2bab8960 100644 --- a/llvm/lib/CodeGen/GCRootLowering.cpp +++ b/llvm/lib/CodeGen/GCRootLowering.cpp @@ -81,6 +81,9 @@ class GCMachineCodeAnalysis : public MachineFunctionPass { PreservedAnalyses GCLoweringPass::run(Function &F, FunctionAnalysisManager &FAM) { + if (!F.hasGC()) + return PreservedAnalyses::all(); + auto &Info = FAM.getResult(F); bool Changed = DoLowering(F, Info.getStrategy()); diff --git a/llvm/test/CodeGen/Generic/gc-lowering.ll b/llvm/test/CodeGen/Generic/gc-lowering.ll new file mode 100644 index 0000000000000..fa2e92ab495f4 --- /dev/null +++ b/llvm/test/CodeGen/Generic/gc-lowering.ll @@ -0,0 +1,62 @@ +; NOTE: Assertions have been autogenerated by utils/update_test_checks.py +; RUN: opt -S -passes='require,function(gc-lowering)' < %s | FileCheck %s + +declare ptr @llvm_gc_allocate(i32) +declare void @llvm_gc_initialize(i32) + +declare void @llvm.gcroot(ptr, ptr) +declare void @llvm.gcwrite(ptr, ptr, ptr) + +define i32 @main() gc "shadow-stack" { +; CHECK-LABEL: define i32 @main() gc "shadow-stack" { +; CHECK-NEXT: entry: +; CHECK-NEXT: [[A:%.*]] = alloca ptr, align 8 +; CHECK-NEXT: store ptr null, ptr [[A]], align 8 +; CHECK-NEXT: [[B:%.*]] = alloca ptr, align 8 +; CHECK-NEXT: store ptr null, ptr [[B]], align 8 +; CHECK-NEXT: call void @llvm_gc_initialize(i32 1048576) +; CHECK-NEXT: call void @llvm.gcroot(ptr [[A]], ptr null) +; CHECK-NEXT: [[APTR:%.*]] = call ptr @llvm_gc_allocate(i32 10) +; CHECK-NEXT: store ptr [[APTR]], ptr [[A]], align 8 +; CHECK-NEXT: call void @llvm.gcroot(ptr [[B]], ptr null) +; CHECK-NEXT: [[B_UPGRD_1:%.*]] = call ptr @llvm_gc_allocate(i32 8) +; CHECK-NEXT: store ptr [[B_UPGRD_1]], ptr [[B]], align 8 +; CHECK-NEXT: [[B_1:%.*]] = load ptr, ptr [[B]], align 8 +; CHECK-NEXT: [[A_1:%.*]] = load ptr, ptr [[A]], align 8 +; CHECK-NEXT: store ptr [[A_1]], ptr [[B_1]], align 8 +; CHECK-NEXT: ret i32 0 +; +entry: + %A = alloca ptr + %B = alloca ptr + + call void @llvm_gc_initialize(i32 1048576) ; Start with 1MB heap + + ;; ptr A; + call void @llvm.gcroot(ptr %A, ptr null) + + ;; A = gcalloc(10); + %Aptr = call ptr @llvm_gc_allocate(i32 10) + store ptr %Aptr, ptr %A + + ;; ptr B; + call void @llvm.gcroot(ptr %B, ptr null) + + ;; B = gcalloc(4); + %B.upgrd.1 = call ptr @llvm_gc_allocate(i32 8) + store ptr %B.upgrd.1, ptr %B + + ;; *B = A; + %B.1 = load ptr, ptr %B + %A.1 = load ptr, ptr %A + call void @llvm.gcwrite(ptr %A.1, ptr %B.upgrd.1, ptr %B.1) + + ret i32 0 +} + +define void @no_gc() { +; CHECK-LABEL: define void @no_gc() { +; CHECK-NEXT: ret void +; + ret void +}