| // NOTE: Assertions have been autogenerated by utils/update_cc_test_checks.py |
| // REQUIRES: x86-registered-target |
| // RUN: %clang_cc1 -triple x86_64-pc-linux-gnu -O0 -emit-llvm %s -o - | FileCheck %s |
| |
| // CHECK-LABEL: @test0( |
| // CHECK-NEXT: entry: |
| // CHECK-NEXT: [[RET:%.*]] = alloca i32, align 4 |
| // CHECK-NEXT: [[TMP0:%.*]] = callbr i32 asm "", "=r,!i,~{dirflag},~{fpsr},~{flags}"() #[[ATTR1:[0-9]+]] |
| // CHECK-NEXT: to label [[ASM_FALLTHROUGH:%.*]] [label %z.split], !srcloc !2 |
| // CHECK: asm.fallthrough: |
| // CHECK-NEXT: store i32 [[TMP0]], ptr [[RET]], align 4 |
| // CHECK-NEXT: store i32 42, ptr [[RET]], align 4 |
| // CHECK-NEXT: br label [[Z:%.*]] |
| // CHECK: z: |
| // CHECK-NEXT: [[TMP1:%.*]] = load i32, ptr [[RET]], align 4 |
| // CHECK-NEXT: ret i32 [[TMP1]] |
| // CHECK: z.split: |
| // CHECK-NEXT: store i32 [[TMP0]], ptr [[RET]], align 4 |
| // CHECK-NEXT: br label [[Z]] |
| // |
| int test0 (void) { |
| int ret; |
| asm goto ("" : "=r"(ret):::z); |
| ret = 42; |
| z: |
| return ret; |
| } |
| |
| // CHECK-LABEL: @test1( |
| // CHECK-NEXT: entry: |
| // CHECK-NEXT: [[RET:%.*]] = alloca i32, align 4 |
| // CHECK-NEXT: [[B:%.*]] = alloca i32, align 4 |
| // CHECK-NEXT: [[TMP0:%.*]] = callbr { i32, i32 } asm "", "=r,=r,!i,~{dirflag},~{fpsr},~{flags}"() #[[ATTR1]] |
| // CHECK-NEXT: to label [[ASM_FALLTHROUGH:%.*]] [label %z.split], !srcloc !3 |
| // CHECK: asm.fallthrough: |
| // CHECK-NEXT: [[ASMRESULT:%.*]] = extractvalue { i32, i32 } [[TMP0]], 0 |
| // CHECK-NEXT: [[ASMRESULT1:%.*]] = extractvalue { i32, i32 } [[TMP0]], 1 |
| // CHECK-NEXT: store i32 [[ASMRESULT]], ptr [[RET]], align 4 |
| // CHECK-NEXT: store i32 [[ASMRESULT1]], ptr [[B]], align 4 |
| // CHECK-NEXT: store i32 42, ptr [[RET]], align 4 |
| // CHECK-NEXT: br label [[Z:%.*]] |
| // CHECK: z: |
| // CHECK-NEXT: [[TMP1:%.*]] = load i32, ptr [[RET]], align 4 |
| // CHECK-NEXT: ret i32 [[TMP1]] |
| // CHECK: z.split: |
| // CHECK-NEXT: [[ASMRESULT2:%.*]] = extractvalue { i32, i32 } [[TMP0]], 0 |
| // CHECK-NEXT: [[ASMRESULT3:%.*]] = extractvalue { i32, i32 } [[TMP0]], 1 |
| // CHECK-NEXT: store i32 [[ASMRESULT2]], ptr [[RET]], align 4 |
| // CHECK-NEXT: store i32 [[ASMRESULT3]], ptr [[B]], align 4 |
| // CHECK-NEXT: br label [[Z]] |
| // |
| int test1 (void) { |
| int ret, b; |
| asm goto ("" : "=r"(ret), "=r"(b):::z); |
| ret = 42; |
| z: |
| return ret; |
| } |
| |
| // CHECK-LABEL: @test2( |
| // CHECK-NEXT: entry: |
| // CHECK-NEXT: [[RET:%.*]] = alloca i32, align 4 |
| // CHECK-NEXT: [[B:%.*]] = alloca i32, align 4 |
| // CHECK-NEXT: [[TMP0:%.*]] = callbr { i32, i32 } asm "", "=r,=r,!i,~{dirflag},~{fpsr},~{flags}"() #[[ATTR1]] |
| // CHECK-NEXT: to label [[ASM_FALLTHROUGH:%.*]] [label %z.split], !srcloc !4 |
| // CHECK: asm.fallthrough: |
| // CHECK-NEXT: [[ASMRESULT:%.*]] = extractvalue { i32, i32 } [[TMP0]], 0 |
| // CHECK-NEXT: [[ASMRESULT1:%.*]] = extractvalue { i32, i32 } [[TMP0]], 1 |
| // CHECK-NEXT: store i32 [[ASMRESULT]], ptr [[RET]], align 4 |
| // CHECK-NEXT: store i32 [[ASMRESULT1]], ptr [[B]], align 4 |
| // CHECK-NEXT: [[TMP1:%.*]] = callbr { i32, i32 } asm "", "=r,=r,!i,~{dirflag},~{fpsr},~{flags}"() #[[ATTR1]] |
| // CHECK-NEXT: to label [[ASM_FALLTHROUGH4:%.*]] [label %z.split9], !srcloc !5 |
| // CHECK: asm.fallthrough4: |
| // CHECK-NEXT: [[ASMRESULT5:%.*]] = extractvalue { i32, i32 } [[TMP1]], 0 |
| // CHECK-NEXT: [[ASMRESULT6:%.*]] = extractvalue { i32, i32 } [[TMP1]], 1 |
| // CHECK-NEXT: store i32 [[ASMRESULT5]], ptr [[RET]], align 4 |
| // CHECK-NEXT: store i32 [[ASMRESULT6]], ptr [[B]], align 4 |
| // CHECK-NEXT: br label [[Z:%.*]] |
| // CHECK: z: |
| // CHECK-NEXT: [[TMP2:%.*]] = load i32, ptr [[RET]], align 4 |
| // CHECK-NEXT: ret i32 [[TMP2]] |
| // CHECK: z.split: |
| // CHECK-NEXT: [[ASMRESULT2:%.*]] = extractvalue { i32, i32 } [[TMP0]], 0 |
| // CHECK-NEXT: [[ASMRESULT3:%.*]] = extractvalue { i32, i32 } [[TMP0]], 1 |
| // CHECK-NEXT: store i32 [[ASMRESULT2]], ptr [[RET]], align 4 |
| // CHECK-NEXT: store i32 [[ASMRESULT3]], ptr [[B]], align 4 |
| // CHECK-NEXT: br label [[Z]] |
| // CHECK: z.split9: |
| // CHECK-NEXT: [[ASMRESULT7:%.*]] = extractvalue { i32, i32 } [[TMP1]], 0 |
| // CHECK-NEXT: [[ASMRESULT8:%.*]] = extractvalue { i32, i32 } [[TMP1]], 1 |
| // CHECK-NEXT: store i32 [[ASMRESULT7]], ptr [[RET]], align 4 |
| // CHECK-NEXT: store i32 [[ASMRESULT8]], ptr [[B]], align 4 |
| // CHECK-NEXT: br label [[Z]] |
| // |
| int test2 (void) { |
| int ret, b; |
| asm goto ("" : "=r"(ret), "=r"(b):::z); |
| asm goto ("" : "=r"(ret), "=r"(b):::z); |
| z: |
| return ret; |
| } |
| // CHECK-LABEL: @test3( |
| // CHECK-NEXT: entry: |
| // CHECK-NEXT: [[RETVAL:%.*]] = alloca i32, align 4 |
| // CHECK-NEXT: [[OUT1_ADDR:%.*]] = alloca i32, align 4 |
| // CHECK-NEXT: store i32 [[OUT1:%.*]], ptr [[OUT1_ADDR]], align 4 |
| // CHECK-NEXT: [[TMP0:%.*]] = callbr i32 asm "", "=r,!i,!i,~{dirflag},~{fpsr},~{flags}"() #[[ATTR1]] |
| // CHECK-NEXT: to label [[ASM_FALLTHROUGH:%.*]] [label [[LABEL_TRUE_SPLIT:%.*]], label %loop.split], !srcloc !6 |
| // CHECK: asm.fallthrough: |
| // CHECK-NEXT: store i32 [[TMP0]], ptr [[OUT1_ADDR]], align 4 |
| // CHECK-NEXT: store i32 0, ptr [[RETVAL]], align 4 |
| // CHECK-NEXT: br label [[RETURN:%.*]] |
| // CHECK: label_true.split: |
| // CHECK-NEXT: store i32 [[TMP0]], ptr [[OUT1_ADDR]], align 4 |
| // CHECK-NEXT: br label [[LABEL_TRUE:%.*]] |
| // CHECK: loop.split: |
| // CHECK-NEXT: store i32 [[TMP0]], ptr [[OUT1_ADDR]], align 4 |
| // CHECK-NEXT: br label [[LOOP:%.*]] |
| // CHECK: loop: |
| // CHECK-NEXT: store i32 0, ptr [[RETVAL]], align 4 |
| // CHECK-NEXT: br label [[RETURN]] |
| // CHECK: label_true: |
| // CHECK-NEXT: store i32 1, ptr [[RETVAL]], align 4 |
| // CHECK-NEXT: br label [[RETURN]] |
| // CHECK: return: |
| // CHECK-NEXT: [[TMP1:%.*]] = load i32, ptr [[RETVAL]], align 4 |
| // CHECK-NEXT: ret i32 [[TMP1]] |
| // |
| int test3 (int out1) { |
| asm goto("" : "=r"(out1)::: label_true, loop); |
| return 0; |
| loop: |
| return 0; |
| label_true: |
| return 1; |
| } |
| |
| // CHECK-LABEL: @test4( |
| // CHECK-NEXT: entry: |
| // CHECK-NEXT: [[X:%.*]] = alloca i32, align 4 |
| // CHECK-NEXT: br label [[FOO:%.*]] |
| // CHECK: foo: |
| // CHECK-NEXT: [[TMP0:%.*]] = callbr i32 asm "", "=r,!i,~{dirflag},~{fpsr},~{flags}"() #[[ATTR1]] |
| // CHECK-NEXT: to label [[ASM_FALLTHROUGH:%.*]] [label %foo.split], !srcloc !7 |
| // CHECK: asm.fallthrough: |
| // CHECK-NEXT: store i32 [[TMP0]], ptr [[X]], align 4 |
| // CHECK-NEXT: ret void |
| // CHECK: foo.split: |
| // CHECK-NEXT: store i32 [[TMP0]], ptr [[X]], align 4 |
| // CHECK-NEXT: br label [[FOO]] |
| // |
| void test4 (void) { |
| int x; |
| foo: |
| asm goto ("" : "=r"(x):::foo); |
| } |