1; RUN: llc -mtriple=thumbv8.1m.main-arm-none-eabi -enable-machine-outliner < %s | \ 2; RUN: FileCheck %s --check-prefix=BTI 3; RUN: llc -mtriple=thumbv8.1m.main-arm-none-eabi -enable-machine-outliner -mattr=+no-bti-at-return-twice < %s | FileCheck %s --check-prefix=NOBTI 4 5; C source 6; -------- 7; jmp_buf buf; 8; 9; extern void h(int a, int b, int *c); 10; 11; int f(int a, int b, int c, int d) { 12; if (setjmp(buf) != 0) 13; return -1; 14; h(a, b, &a); 15; return 2 + a * (a + b) / (c + d); 16; } 17; 18; int g(int a, int b, int c, int d) { 19; if (setjmp(buf) != 0) 20; return -1; 21; h(a, b, &a); 22; return 1 + a * (a + b) / (c + d); 23; } 24 25@buf = global [20 x i64] zeroinitializer, align 8 26 27define i32 @f(i32 %a, i32 %b, i32 %c, i32 %d) "branch-target-enforcement" { 28; BTI-LABEL: f: 29; BTI: bl OUTLINED_FUNCTION_0 30; BTI-NEXT: bti 31; NOBTI-LABEL: f: 32; NOBTI: bl OUTLINED_FUNCTION_0 33; NOBTI-NEXT: cbz r0, .LBB0_2 34entry: 35 %a.addr = alloca i32, align 4 36 store i32 %a, ptr %a.addr, align 4 37 %call = call i32 @setjmp(ptr @buf) #0 38 %cmp.not = icmp eq i32 %call, 0 39 br i1 %cmp.not, label %if.end, label %return 40 41if.end: ; preds = %entry 42 call void @h(i32 %a, i32 %b, ptr nonnull %a.addr) 43 %0 = load i32, ptr %a.addr, align 4 44 %add = add nsw i32 %0, %b 45 %mul = mul nsw i32 %add, %0 46 %add1 = add nsw i32 %d, %c 47 %div = sdiv i32 %mul, %add1 48 %add2 = add nsw i32 %div, 2 49 br label %return 50 51return: ; preds = %entry, %if.end 52 %retval.0 = phi i32 [ %add2, %if.end ], [ -1, %entry ] 53 ret i32 %retval.0 54} 55 56define i32 @g(i32 %a, i32 %b, i32 %c, i32 %d) "branch-target-enforcement" { 57; BTI-LABEL: g: 58; BTI: bl OUTLINED_FUNCTION_0 59; BTI-NEXT: bti 60; NOBTI-LABEL: g: 61; NOBTI: bl OUTLINED_FUNCTION_0 62; NOBTI-NEXT: cbz r0, .LBB1_2 63entry: 64 %a.addr = alloca i32, align 4 65 store i32 %a, ptr %a.addr, align 4 66 %call = call i32 @setjmp(ptr @buf) #0 67 %cmp.not = icmp eq i32 %call, 0 68 br i1 %cmp.not, label %if.end, label %return 69 70if.end: ; preds = %entry 71 call void @h(i32 %a, i32 %b, ptr nonnull %a.addr) 72 %0 = load i32, ptr %a.addr, align 4 73 %add = add nsw i32 %0, %b 74 %mul = mul nsw i32 %add, %0 75 %add1 = add nsw i32 %d, %c 76 %div = sdiv i32 %mul, %add1 77 %add2 = add nsw i32 %div, 1 78 br label %return 79 80return: ; preds = %entry, %if.end 81 %retval.0 = phi i32 [ %add2, %if.end ], [ -1, %entry ] 82 ret i32 %retval.0 83} 84 85declare void @h(i32, i32, ptr) 86declare i32 @setjmp(ptr) #0 87 88attributes #0 = { returns_twice } 89 90