diff options
Diffstat (limited to 'llvm')
| -rw-r--r-- | llvm/lib/Target/PowerPC/MCTargetDesc/PPCMCCodeEmitter.cpp | 2 | ||||
| -rw-r--r-- | llvm/lib/Target/PowerPC/PPCInstrInfo.td | 5 | ||||
| -rw-r--r-- | llvm/test/CodeGen/PowerPC/2016-04-28-setjmp.ll | 48 |
3 files changed, 54 insertions, 1 deletions
diff --git a/llvm/lib/Target/PowerPC/MCTargetDesc/PPCMCCodeEmitter.cpp b/llvm/lib/Target/PowerPC/MCTargetDesc/PPCMCCodeEmitter.cpp index 0f6385e0a67..e7b2d8369f2 100644 --- a/llvm/lib/Target/PowerPC/MCTargetDesc/PPCMCCodeEmitter.cpp +++ b/llvm/lib/Target/PowerPC/MCTargetDesc/PPCMCCodeEmitter.cpp @@ -113,6 +113,8 @@ public: // Output the constant in big/little endian byte order. unsigned Size = Desc.getSize(); switch (Size) { + case 0: + break; case 4: if (IsLittleEndian) { support::endian::Writer<support::little>(OS).write<uint32_t>(Bits); diff --git a/llvm/lib/Target/PowerPC/PPCInstrInfo.td b/llvm/lib/Target/PowerPC/PPCInstrInfo.td index 32558d35513..838889660a3 100644 --- a/llvm/lib/Target/PowerPC/PPCInstrInfo.td +++ b/llvm/lib/Target/PowerPC/PPCInstrInfo.td @@ -1397,7 +1397,10 @@ let hasSideEffects = 1, isBarrier = 1, usesCustomInserter = 1 in { Requires<[In32BitMode]>; } -let isBranch = 1, isTerminator = 1 in { +// This pseudo is never removed from the function, as it serves as +// a terminator. Size is set to 0 to prevent the builtin assembler +// from emitting it. +let isBranch = 1, isTerminator = 1, Size = 0 in { def EH_SjLj_Setup : Pseudo<(outs), (ins directbrtarget:$dst), "#EH_SjLj_Setup\t$dst", []>; } diff --git a/llvm/test/CodeGen/PowerPC/2016-04-28-setjmp.ll b/llvm/test/CodeGen/PowerPC/2016-04-28-setjmp.ll new file mode 100644 index 00000000000..09c0fa7ba97 --- /dev/null +++ b/llvm/test/CodeGen/PowerPC/2016-04-28-setjmp.ll @@ -0,0 +1,48 @@ +; RUN: llc -filetype=obj <%s | llvm-objdump --disassemble - | FileCheck %s +target datalayout = "e-m:e-i64:64-n32:64" +target triple = "powerpc64le-unknown-linux-gnu" + +@ptr = common global i8* null, align 8 + +; Verify there's no junk between these two instructions from misemitted +; EH_SjLj_Setup. + +; CHECK: li 3, 1 +; CHECK-NEXT: b .+4 + +define void @h() nounwind { + %1 = load i8**, i8*** bitcast (i8** @ptr to i8***), align 8 + %2 = tail call i8* @llvm.frameaddress(i32 0) + store i8* %2, i8** %1, align 8 + %3 = tail call i8* @llvm.stacksave() + %4 = getelementptr inbounds i8*, i8** %1, i64 2 + store i8* %3, i8** %4, align 8 + %5 = bitcast i8** %1 to i8* + %6 = tail call i32 @llvm.eh.sjlj.setjmp(i8* %5) + %7 = icmp eq i32 %6, 0 + br i1 %7, label %9, label %8 + +; <label>:8: ; preds = %0 + tail call void @g() + br label %10 + +; <label>:9: ; preds = %0 + tail call void @f() + br label %10 + +; <label>:10: ; preds = %9, %8 + ret void +} + +; Function Attrs: nounwind readnone +declare i8* @llvm.frameaddress(i32) + +; Function Attrs: nounwind +declare i8* @llvm.stacksave() + +; Function Attrs: nounwind +declare i32 @llvm.eh.sjlj.setjmp(i8*) + +declare void @g() + +declare void @f() |

