Index: llvm/lib/Target/ARM/ARMISelLowering.cpp =================================================================== --- llvm/lib/Target/ARM/ARMISelLowering.cpp +++ llvm/lib/Target/ARM/ARMISelLowering.cpp @@ -956,6 +956,7 @@ setOperationAction(ISD::BlockAddress, MVT::i32, Custom); setOperationAction(ISD::TRAP, MVT::Other, Legal); + setOperationAction(ISD::DEBUGTRAP, MVT::Other, Legal); // Use the default implementation. setOperationAction(ISD::VASTART, MVT::Other, Custom); Index: llvm/lib/Target/ARM/ARMInstrInfo.td =================================================================== --- llvm/lib/Target/ARM/ARMInstrInfo.td +++ llvm/lib/Target/ARM/ARMInstrInfo.td @@ -221,6 +221,7 @@ def NoV4T : Predicate<"!Subtarget->hasV4TOps()">; def HasV5T : Predicate<"Subtarget->hasV5TOps()">, AssemblerPredicate<"HasV5TOps", "armv5t">; +def NoV5T : Predicate<"!Subtarget->hasV5TOps()">; def HasV5TE : Predicate<"Subtarget->hasV5TEOps()">, AssemblerPredicate<"HasV5TEOps", "armv5te">; def HasV6 : Predicate<"Subtarget->hasV6Ops()">, @@ -2200,6 +2201,9 @@ let Inst = 0xe7ffdefe; } +def : Pat<(debugtrap), (BKPT 0)>, Requires<[IsARM, HasV5T]>; +def : Pat<(debugtrap), (UDF 254)>, Requires<[IsARM, NoV5T]>; + // Address computation and loads and stores in PIC mode. let isNotDuplicable = 1 in { def PICADD : ARMPseudoInst<(outs GPR:$dst), (ins GPR:$a, pclabel:$cp, pred:$p), Index: llvm/lib/Target/ARM/ARMInstrThumb.td =================================================================== --- llvm/lib/Target/ARM/ARMInstrThumb.td +++ llvm/lib/Target/ARM/ARMInstrThumb.td @@ -1380,6 +1380,9 @@ let Inst{7-0} = imm8; } +def : Pat<(debugtrap), (tBKPT 0)>, Requires<[IsThumb, HasV5T]>; +def : Pat<(debugtrap), (tUDF 254)>, Requires<[IsThumb, NoV5T]>; + def t__brkdiv0 : TI<(outs), (ins), IIC_Br, "__brkdiv0", [(int_arm_undefined 249)]>, Encoding16, Requires<[IsThumb, IsWindows]> { Index: llvm/test/CodeGen/ARM/analyze-branch-bkpt.ll =================================================================== --- /dev/null +++ llvm/test/CodeGen/ARM/analyze-branch-bkpt.ll @@ -0,0 +1,61 @@ +; RUN: llc -o - %s -mtriple thumbv4-unknown-linux-android | FileCheck --check-prefix=V4 %s +; RUN: llc -o - %s -mtriple thumbv5-unknown-linux-android | FileCheck --check-prefix=V5 %s + +; V4: udf #254 +; V5: bkpt #0 + +define i1 @a(i32 %b) !dbg !3 { + br i1 undef, label %c, label %d, !dbg !4 + +d: ; preds = %0 + call void @llvm.debugtrap() + br label %ah, !dbg !4 + +c: ; preds = %0 + %aj = icmp ne i20 undef, 5 + br label %ah, !dbg !4 + +ah: ; preds = %c, %d + %ak = phi i1 [ false, %d ], [ %aj, %c ] + call void @llvm.dbg.value(metadata i1 %ak, metadata !7, metadata !DIExpression()), !dbg !9 + switch i32 %b, label %al [ + i32 0, label %am + i32 10, label %an + ] + +an: ; preds = %ah + %ch = select i1 %ak, i32 0, i32 5 + br label %am, !dbg !10 + +al: ; preds = %ah + br label %am, !dbg !9 + +am: ; preds = %al, %an, %ah + %1 = phi i32 [ 0, %al ], [ %ch, %an ], [ %b, %ah ] + unreachable +} + +; Function Attrs: nounwind readnone speculatable +declare void @llvm.dbg.value(metadata, metadata, metadata) #0 + +; Function Attrs: nounwind +declare void @llvm.debugtrap() #1 + +attributes #0 = { nounwind readnone speculatable } +attributes #1 = { nounwind } + +!llvm.dbg.cu = !{!0} +!llvm.module.flags = !{!2} + +!0 = distinct !DICompileUnit(language: DW_LANG_C_plus_plus, file: !1, isOptimized: false, runtimeVersion: 0, emissionKind: NoDebug) +!1 = !DIFile(filename: "a", directory: "") +!2 = !{i32 2, !"Debug Info Version", i32 3} +!3 = distinct !DISubprogram(scope: null, isLocal: false, isDefinition: true, isOptimized: false, unit: !0) +!4 = !DILocation(line: 0, scope: !5, inlinedAt: !6) +!5 = distinct !DISubprogram(scope: null, isLocal: false, isDefinition: true, isOptimized: false, unit: !0) +!6 = !DILocation(line: 0, scope: !3) +!7 = !DILocalVariable(scope: !8) +!8 = distinct !DISubprogram(scope: null, isLocal: false, isDefinition: true, isOptimized: false, unit: !0) +!9 = !DILocation(line: 0, scope: !8, inlinedAt: !6) +!10 = !DILocation(line: 0, scope: !11, inlinedAt: !6) +!11 = !DILexicalBlock(scope: !8) Index: llvm/test/CodeGen/ARM/debugtrap.ll =================================================================== --- llvm/test/CodeGen/ARM/debugtrap.ll +++ llvm/test/CodeGen/ARM/debugtrap.ll @@ -1,7 +1,10 @@ ; This test ensures the @llvm.debugtrap() call is not removed when generating ; the 'pop' instruction to restore the callee saved registers on ARM. -; RUN: llc < %s -mtriple=armv7 -O0 -filetype=asm | FileCheck %s +; RUN: llc < %s -mtriple=armv4 -O0 -filetype=asm | FileCheck --check-prefixes=CHECK,V4 %s +; RUN: llc < %s -mtriple=armv5 -O0 -filetype=asm | FileCheck --check-prefixes=CHECK,V5 %s +; RUN: llc < %s -mtriple=thumbv4 -O0 -filetype=asm | FileCheck --check-prefixes=CHECK,V4 %s +; RUN: llc < %s -mtriple=thumbv5 -O0 -filetype=asm | FileCheck --check-prefixes=CHECK,V5 %s declare void @llvm.debugtrap() nounwind declare void @foo() nounwind @@ -9,8 +12,9 @@ define void @test() nounwind { entry: ; CHECK: bl foo + ; V4-NEXT: udf #254 + ; V5-NEXT: bkpt #0 ; CHECK-NEXT: pop - ; CHECK-NEXT: .inst 0xe7ffdefe call void @foo() call void @llvm.debugtrap() ret void Index: llvm/test/CodeGen/ARM/trap.ll =================================================================== --- llvm/test/CodeGen/ARM/trap.ll +++ llvm/test/CodeGen/ARM/trap.ll @@ -59,25 +59,25 @@ define void @t2() nounwind { entry: ; DARWIN-LABEL: t2: -; DARWIN: trap +; DARWIN: udf #254 ; FUNC-LABEL: t2: ; FUNC: bl __trap ; NACL-LABEL: t2: -; NACL: .inst 0xe7fedef0 +; NACL: bkpt #0 ; ARM-LABEL: t2: -; ARM: .inst 0xe7ffdefe +; ARM: bkpt #0 ; THUMB-LABEL: t2: -; THUMB: .inst.n 0xdefe +; THUMB: bkpt #0 -; ENCODING-NACL: f0 de fe e7 trap +; ENCODING-NACL: 70 00 20 e1 bkpt #0 -; ENCODING-ARM: fe de ff e7 trap +; ENCODING-ARM: 70 00 20 e1 bkpt #0 -; ENCODING-THUMB: fe de trap +; ENCODING-THUMB: 00 be bkpt #0 call void @llvm.debugtrap() unreachable