This is an archive of the discontinued LLVM Phabricator instance.

Warn when calling a non interrupt function from an interrupt on ARM
ClosedPublic

Authored by jroelofs on Jan 17 2017, 11:50 AM.

Details

Reviewers
rengolin
compnerd
Summary

The idea for this originated from a really tricky bug: ISRs on ARM don't automatically save off the VFP regs, so if say, memcpy gets interrupted and the ISR itself calls memcpy, the regs are left clobbered when the ISR is done.

If the equivalent problem is likely to happen on other arches, I'd be happy to extend this to them. Suggestions on a more arch-neutral spelling of the warning itself would be helpful in that case.

Diff Detail

Event Timeline

jroelofs created this revision.Jan 17 2017, 11:50 AM
rengolin accepted this revision.Jan 18 2017, 4:55 AM

Seems like a very specific corner case on ARM, but is that attribute guaranteed to be ARM-only?

If so, LGTM as is. If not, avoid mentioning "VFP" on the error message.

This revision is now accepted and ready to land.Jan 18 2017, 4:55 AM

Seems like a very specific corner case on ARM, but is that attribute guaranteed to be ARM-only?

If so, LGTM as is. If not, avoid mentioning "VFP" on the error message.

Yeah, the attribute is parsed in a target-specific way, so this warning as written won't match on other arches even though mips/x86 have their own similar spellings of it.

jroelofs closed this revision.Jan 18 2017, 7:42 AM

r292375

Why can't the compiler handle this case itself transparently? According to your description, the interrupt calling convention is different from the normal hard-float AAPCS calling convention: the VFP registers are all callee-save. The compiler knows this; it should be able to insert the appropriate spills itself.

Why can't the compiler handle this case itself transparently? According to your description, the interrupt calling convention is different from the normal hard-float AAPCS calling convention: the VFP registers are all callee-save. The compiler knows this; it should be able to insert the appropriate spills itself.

There would be a big performance penalty for ISRs with callees that don't use VFP regs.

Why can't the compiler handle this case itself transparently? According to your description, the interrupt calling convention is different from the normal hard-float AAPCS calling convention: the VFP registers are all callee-save. The compiler knows this; it should be able to insert the appropriate spills itself.

There would be a big performance penalty for ISRs with callees that don't use VFP regs.

Then again, it probably makes sense to add all the VFP regs to the ISR calling convention's CalleeSavedRegs, as the ISR /should/ be spilling them if it uses them.

There would be a big performance penalty for ISRs with callees that don't use VFP regs.

Sacrificing correctness for the sake of performance seems like a bad idea... especially given that the optimizer can insert calls to memcpy where they didn't originally exist in the source.

There would be a big performance penalty for ISRs with callees that don't use VFP regs.

Sacrificing correctness for the sake of performance seems like a bad idea...

I don't quite see it that way, but I understand where you're coming from.

especially given that the optimizer can insert calls to memcpy where they didn't originally exist in the source.

That, however, is the nail in the coffin of my argument :)

When compiling for softfp targets, this new warning doesn't make sense: there are no VFP registers to save.
Jonathan, would you please conditionalize it to only affect hardfp targets?

When compiling for softfp targets, this new warning doesn't make sense: there are no VFP registers to save.
Jonathan, would you please conditionalize it to only affect hardfp targets?

Sure, I can do that.

Hi , I am looking for some helps on the issue i have in my project after this change for the compiler.

typedef void (*callback_t)(uint32_t icciar, void * context);

callback_t callee1;
void _ _attribute((interrupt("IRQ"))) cs3_isr_irq() {

callee1(icciar , context);

}

the above code gives me the expected error " call to function without interrupt attribute could clobber interruptee's VFP registers"

below is my attempt

typedef void _ _attribute__((interrupt("IRQ"))) (*callback_t)(uint32_t icciar, void * context);

callback_t _ _attribute((interrupt("IRQ"))) callee1;
void _ _attribute
((interrupt("IRQ"))) __cs3_isr_irq() {

callee1(icciar , context);

}

However, it is still giving me the error "" call to function without interrupt attribute could clobber interruptee's VFP registers"
What is the best way to modify the code for this compiler change ?

thanks all in advance !!

What is the best way to modify the code for this compiler change ?

Currently, the "interrupt" attribute only has an effect on functions, not function pointers, so your code won't work the way you want. It's a bug that we don't emit a warning for this.

Currently, this warning doesn't have its own warning flag, instead being lumped under -Wextra. This is also a bug.

We don't emit the warning if your code is compiled for a target which doesn't support floating-point (-mfpu=none or -msoft-float); see https://reviews.llvm.org/D32918. But otherwise, if you're sure your code is actually correct, you can turn off the warning with -Wno-extra or something like that. (The whole thing is kind of awkward because the implementation of the interrupt attribute in clang is buggy: the frontend lies to the backend about the calling convention, so the backend can't save/restore VFP registers correctly.)

What is the best way to modify the code for this compiler change ?

Currently, the "interrupt" attribute only has an effect on functions, not function pointers, so your code won't work the way you want. It's a bug that we don't emit a warning for this.

Currently, this warning doesn't have its own warning flag, instead being lumped under -Wextra. This is also a bug.

We don't emit the warning if your code is compiled for a target which doesn't support floating-point (-mfpu=none or -msoft-float); see https://reviews.llvm.org/D32918. But otherwise, if you're sure your code is actually correct, you can turn off the warning with -Wno-extra or something like that. (The whole thing is kind of awkward because the implementation of the interrupt attribute in clang is buggy: the frontend lies to the backend about the calling convention, so the backend can't save/restore VFP registers correctly.)

so is there any plan to make the "interrupt" attribute not just support on functions?

What is the best way to modify the code for this compiler change ?

Currently, the "interrupt" attribute only has an effect on functions, not function pointers, so your code won't work the way you want. It's a bug that we don't emit a warning for this.

https://bugs.llvm.org/show_bug.cgi?id=35527

Currently, this warning doesn't have its own warning flag, instead being lumped under -Wextra. This is also a bug.

https://bugs.llvm.org/show_bug.cgi?id=35528

We don't emit the warning if your code is compiled for a target which doesn't support floating-point (-mfpu=none or -msoft-float); see https://reviews.llvm.org/D32918. But otherwise, if you're sure your code is actually correct, you can turn off the warning with -Wno-extra or something like that. (The whole thing is kind of awkward because the implementation of the interrupt attribute in clang is buggy: the frontend lies to the backend about the calling convention, so the backend can't save/restore VFP registers correctly.)

https://i.imgur.com/BFRoEUO.gif

so is there any plan to make the "interrupt" attribute not just support on functions?

I'll fix these. Give me a few weeks though.

What is the best way to modify the code for this compiler change ?

Currently, the "interrupt" attribute only has an effect on functions, not function pointers, so your code won't work the way you want. It's a bug that we don't emit a warning for this.

https://bugs.llvm.org/show_bug.cgi?id=35527

Currently, this warning doesn't have its own warning flag, instead being lumped under -Wextra. This is also a bug.

https://bugs.llvm.org/show_bug.cgi?id=35528

We don't emit the warning if your code is compiled for a target which doesn't support floating-point (-mfpu=none or -msoft-float); see https://reviews.llvm.org/D32918. But otherwise, if you're sure your code is actually correct, you can turn off the warning with -Wno-extra or something like that. (The whole thing is kind of awkward because the implementation of the interrupt attribute in clang is buggy: the frontend lies to the backend about the calling convention, so the backend can't save/restore VFP registers correctly.)

https://i.imgur.com/BFRoEUO.gif

so is there any plan to make the "interrupt" attribute not just support on functions?

I'll fix these. Give me a few weeks though.

Thank you very much for recording the bug.

Thank you very much for recording the bug.

patch to fix these: https://reviews.llvm.org/D74812