From 90904c693cecb8976f9cf3a7aaf0e6be669fe794 Mon Sep 17 00:00:00 2001 From: Dylan McKay Date: Thu, 13 Jul 2017 08:09:36 +0000 Subject: [PATCH] [AVR] Fix indirect calls to function pointers Patch by Carl Peto. git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@307888 91177308-0d34-0410-b5e6-96231b3b80d8 --- lib/Target/AVR/AVRMCInstLower.cpp | 16 ++++++++++++++-- .../AVR/icall-func-pointer-correct-addr-space.ll | 15 +++++++++++++++ 2 files changed, 29 insertions(+), 2 deletions(-) create mode 100644 test/CodeGen/AVR/icall-func-pointer-correct-addr-space.ll diff --git a/lib/Target/AVR/AVRMCInstLower.cpp b/lib/Target/AVR/AVRMCInstLower.cpp index 475dda420e8..dfefd09bc4b 100644 --- a/lib/Target/AVR/AVRMCInstLower.cpp +++ b/lib/Target/AVR/AVRMCInstLower.cpp @@ -37,10 +37,22 @@ MCOperand AVRMCInstLower::lowerSymbolOperand(const MachineOperand &MO, Expr, MCConstantExpr::create(MO.getOffset(), Ctx), Ctx); } + bool IsFunction = MO.isGlobal() && isa(MO.getGlobal()); + if (TF & AVRII::MO_LO) { - Expr = AVRMCExpr::create(AVRMCExpr::VK_AVR_LO8, Expr, IsNegated, Ctx); + if (IsFunction) { + // N.B. Should we use _GS fixups here to cope with >128k progmem? + Expr = AVRMCExpr::create(AVRMCExpr::VK_AVR_PM_LO8, Expr, IsNegated, Ctx); + } else { + Expr = AVRMCExpr::create(AVRMCExpr::VK_AVR_LO8, Expr, IsNegated, Ctx); + } } else if (TF & AVRII::MO_HI) { - Expr = AVRMCExpr::create(AVRMCExpr::VK_AVR_HI8, Expr, IsNegated, Ctx); + if (IsFunction) { + // N.B. Should we use _GS fixups here to cope with >128k progmem? + Expr = AVRMCExpr::create(AVRMCExpr::VK_AVR_PM_HI8, Expr, IsNegated, Ctx); + } else { + Expr = AVRMCExpr::create(AVRMCExpr::VK_AVR_HI8, Expr, IsNegated, Ctx); + } } else if (TF != 0) { llvm_unreachable("Unknown target flag on symbol operand"); } diff --git a/test/CodeGen/AVR/icall-func-pointer-correct-addr-space.ll b/test/CodeGen/AVR/icall-func-pointer-correct-addr-space.ll new file mode 100644 index 00000000000..17ac29e2cdb --- /dev/null +++ b/test/CodeGen/AVR/icall-func-pointer-correct-addr-space.ll @@ -0,0 +1,15 @@ +; RUN: llc -mattr=lpm,lpmw < %s -march=avr | FileCheck %s + +declare void @callback(i16 zeroext) + +; CHECK-LABEL: foo +define void @foo() { +entry: + ; CHECK: ldi r{{[0-9]+}}, pm_lo8(callback) + ; CHECK-NEXT: ldi r{{[0-9]+}}, pm_hi8(callback) + call void @bar(i8 zeroext undef, void (i16)* @callback) + ret void +} + +declare void @bar(i8 zeroext, void (i16)*) +