| // NOTE: Assertions have been autogenerated by utils/update_cc_test_checks.py UTC_ARGS: --version 6 | |
| // RUN: %clang_cc1 %s -emit-llvm -o - -triple=aarch64-linux-gnu | FileCheck %s --check-prefix=CHECK-C | |
| // RUN: %clang_cc1 -x c++ -std=c++11 %s -emit-llvm -o - -triple=aarch64-linux-gnu | FileCheck %s --check-prefix=CHECK-CPP | |
| _Atomic(float) f; | |
| _Atomic(double) d; | |
| _Atomic(__bf16) bf; | |
| _Atomic(_Float16) h; | |
| // CHECK-C-LABEL: define dso_local void @test_float_add( | |
| // CHECK-C-SAME: float noundef [[VAL:%.*]]) #[[ATTR0:[0-9]+]] { | |
| // CHECK-C-NEXT: [[ENTRY:.*:]] | |
| // CHECK-C-NEXT: [[VAL_ADDR:%.*]] = alloca float, align 4 | |
| // CHECK-C-NEXT: store float [[VAL]], ptr [[VAL_ADDR]], align 4 | |
| // CHECK-C-NEXT: [[TMP0:%.*]] = load float, ptr [[VAL_ADDR]], align 4 | |
| // CHECK-C-NEXT: [[TMP1:%.*]] = atomicrmw fadd ptr @f, float [[TMP0]] seq_cst, align 4 | |
| // CHECK-C-NEXT: [[TMP2:%.*]] = fadd float [[TMP1]], [[TMP0]] | |
| // CHECK-C-NEXT: ret void | |
| // | |
| // CHECK-CPP-LABEL: define dso_local void @_Z14test_float_addf( | |
| // CHECK-CPP-SAME: float noundef [[VAL:%.*]]) #[[ATTR0:[0-9]+]] { | |
| // CHECK-CPP-NEXT: [[ENTRY:.*:]] | |
| // CHECK-CPP-NEXT: [[VAL_ADDR:%.*]] = alloca float, align 4 | |
| // CHECK-CPP-NEXT: store float [[VAL]], ptr [[VAL_ADDR]], align 4 | |
| // CHECK-CPP-NEXT: [[TMP0:%.*]] = load float, ptr [[VAL_ADDR]], align 4 | |
| // CHECK-CPP-NEXT: [[TMP1:%.*]] = atomicrmw fadd ptr @f, float [[TMP0]] seq_cst, align 4 | |
| // CHECK-CPP-NEXT: [[TMP2:%.*]] = fadd float [[TMP1]], [[TMP0]] | |
| // CHECK-CPP-NEXT: ret void | |
| // | |
| void test_float_add(float val) { | |
| f += val; | |
| } | |
| // CHECK-C-LABEL: define dso_local void @test_float_compound_add( | |
| // CHECK-C-SAME: float [[VAL:%.*]]) #[[ATTR0]] { | |
| // CHECK-C-NEXT: [[ENTRY:.*:]] | |
| // CHECK-C-NEXT: [[VAL_ADDR:%.*]] = alloca float, align 4 | |
| // CHECK-C-NEXT: store float [[VAL]], ptr [[VAL_ADDR]], align 4 | |
| // CHECK-C-NEXT: [[ATOMIC_LOAD:%.*]] = load atomic float, ptr [[VAL_ADDR]] seq_cst, align 4 | |
| // CHECK-C-NEXT: [[TMP0:%.*]] = atomicrmw fadd ptr @f, float [[ATOMIC_LOAD]] seq_cst, align 4 | |
| // CHECK-C-NEXT: [[TMP1:%.*]] = fadd float [[TMP0]], [[ATOMIC_LOAD]] | |
| // CHECK-C-NEXT: ret void | |
| // | |
| // CHECK-CPP-LABEL: define dso_local void @_Z23test_float_compound_addU7_Atomicf( | |
| // CHECK-CPP-SAME: float [[VAL:%.*]]) #[[ATTR0]] { | |
| // CHECK-CPP-NEXT: [[ENTRY:.*:]] | |
| // CHECK-CPP-NEXT: [[VAL_ADDR:%.*]] = alloca float, align 4 | |
| // CHECK-CPP-NEXT: store float [[VAL]], ptr [[VAL_ADDR]], align 4 | |
| // CHECK-CPP-NEXT: [[ATOMIC_LOAD:%.*]] = load atomic float, ptr [[VAL_ADDR]] seq_cst, align 4 | |
| // CHECK-CPP-NEXT: [[TMP0:%.*]] = atomicrmw fadd ptr @f, float [[ATOMIC_LOAD]] seq_cst, align 4 | |
| // CHECK-CPP-NEXT: [[TMP1:%.*]] = fadd float [[TMP0]], [[ATOMIC_LOAD]] | |
| // CHECK-CPP-NEXT: ret void | |
| // | |
| void test_float_compound_add(_Atomic(float) val){ | |
| f += val; | |
| } | |
| // CHECK-C-LABEL: define dso_local void @test_float_read_add( | |
| // CHECK-C-SAME: float [[VAL:%.*]]) #[[ATTR0]] { | |
| // CHECK-C-NEXT: [[ENTRY:.*:]] | |
| // CHECK-C-NEXT: [[VAL_ADDR:%.*]] = alloca float, align 4 | |
| // CHECK-C-NEXT: store float [[VAL]], ptr [[VAL_ADDR]], align 4 | |
| // CHECK-C-NEXT: [[ATOMIC_LOAD:%.*]] = load atomic float, ptr @f seq_cst, align 4 | |
| // CHECK-C-NEXT: [[ATOMIC_LOAD1:%.*]] = load atomic float, ptr [[VAL_ADDR]] seq_cst, align 4 | |
| // CHECK-C-NEXT: [[ADD:%.*]] = fadd float [[ATOMIC_LOAD]], [[ATOMIC_LOAD1]] | |
| // CHECK-C-NEXT: store atomic float [[ADD]], ptr @f seq_cst, align 4 | |
| // CHECK-C-NEXT: ret void | |
| // | |
| // CHECK-CPP-LABEL: define dso_local void @_Z19test_float_read_addU7_Atomicf( | |
| // CHECK-CPP-SAME: float [[VAL:%.*]]) #[[ATTR0]] { | |
| // CHECK-CPP-NEXT: [[ENTRY:.*:]] | |
| // CHECK-CPP-NEXT: [[VAL_ADDR:%.*]] = alloca float, align 4 | |
| // CHECK-CPP-NEXT: store float [[VAL]], ptr [[VAL_ADDR]], align 4 | |
| // CHECK-CPP-NEXT: [[ATOMIC_LOAD:%.*]] = load atomic float, ptr @f seq_cst, align 4 | |
| // CHECK-CPP-NEXT: [[ATOMIC_LOAD1:%.*]] = load atomic float, ptr [[VAL_ADDR]] seq_cst, align 4 | |
| // CHECK-CPP-NEXT: [[ADD:%.*]] = fadd float [[ATOMIC_LOAD]], [[ATOMIC_LOAD1]] | |
| // CHECK-CPP-NEXT: store atomic float [[ADD]], ptr @f seq_cst, align 4 | |
| // CHECK-CPP-NEXT: ret void | |
| // | |
| void test_float_read_add(_Atomic(float) val){ | |
| f = f + val; | |
| } | |
| // CHECK-C-LABEL: define dso_local void @test_double_add( | |
| // CHECK-C-SAME: double noundef [[VAL:%.*]]) #[[ATTR0]] { | |
| // CHECK-C-NEXT: [[ENTRY:.*:]] | |
| // CHECK-C-NEXT: [[VAL_ADDR:%.*]] = alloca double, align 8 | |
| // CHECK-C-NEXT: store double [[VAL]], ptr [[VAL_ADDR]], align 8 | |
| // CHECK-C-NEXT: [[TMP0:%.*]] = load double, ptr [[VAL_ADDR]], align 8 | |
| // CHECK-C-NEXT: [[TMP1:%.*]] = atomicrmw fadd ptr @d, double [[TMP0]] seq_cst, align 8 | |
| // CHECK-C-NEXT: [[TMP2:%.*]] = fadd double [[TMP1]], [[TMP0]] | |
| // CHECK-C-NEXT: ret void | |
| // | |
| // CHECK-CPP-LABEL: define dso_local void @_Z15test_double_addd( | |
| // CHECK-CPP-SAME: double noundef [[VAL:%.*]]) #[[ATTR0]] { | |
| // CHECK-CPP-NEXT: [[ENTRY:.*:]] | |
| // CHECK-CPP-NEXT: [[VAL_ADDR:%.*]] = alloca double, align 8 | |
| // CHECK-CPP-NEXT: store double [[VAL]], ptr [[VAL_ADDR]], align 8 | |
| // CHECK-CPP-NEXT: [[TMP0:%.*]] = load double, ptr [[VAL_ADDR]], align 8 | |
| // CHECK-CPP-NEXT: [[TMP1:%.*]] = atomicrmw fadd ptr @d, double [[TMP0]] seq_cst, align 8 | |
| // CHECK-CPP-NEXT: [[TMP2:%.*]] = fadd double [[TMP1]], [[TMP0]] | |
| // CHECK-CPP-NEXT: ret void | |
| // | |
| void test_double_add(double val) { | |
| d += val; | |
| } | |
| // CHECK-LLVM-LABEL: define dso_local void @test_bf16_add( | |
| // CHECK-LLVM-SAME: bfloat noundef [[VAL:%.*]]) #[[ATTR0]] { | |
| // CHECK-LLVM-NEXT: [[ENTRY:.*:]] | |
| // CHECK-LLVM-NEXT: [[VAL_ADDR:%.*]] = alloca bfloat, align 2 | |
| // CHECK-LLVM-NEXT: store bfloat [[VAL]], ptr [[VAL_ADDR]], align 2 | |
| // CHECK-LLVM-NEXT: [[TMP0:%.*]] = load bfloat, ptr [[VAL_ADDR]], align 2 | |
| // CHECK-LLVM-NEXT: [[EXT:%.*]] = fpext bfloat [[TMP0]] to float | |
| // CHECK-LLVM-NEXT: [[CONV:%.*]] = fptrunc float [[EXT]] to bfloat | |
| // CHECK-LLVM-NEXT: [[TMP1:%.*]] = atomicrmw fadd ptr @bf, bfloat [[CONV]] seq_cst, align 2 | |
| // CHECK-LLVM-NEXT: [[TMP2:%.*]] = fadd bfloat [[TMP1]], [[CONV]] | |
| // CHECK-LLVM-NEXT: ret void | |
| // CHECK-C-LABEL: define dso_local void @test_bf16_add( | |
| // CHECK-C-SAME: bfloat noundef [[VAL:%.*]]) #[[ATTR0]] { | |
| // CHECK-C-NEXT: [[ENTRY:.*:]] | |
| // CHECK-C-NEXT: [[VAL_ADDR:%.*]] = alloca bfloat, align 2 | |
| // CHECK-C-NEXT: store bfloat [[VAL]], ptr [[VAL_ADDR]], align 2 | |
| // CHECK-C-NEXT: [[TMP0:%.*]] = load bfloat, ptr [[VAL_ADDR]], align 2 | |
| // CHECK-C-NEXT: [[EXT:%.*]] = fpext bfloat [[TMP0]] to float | |
| // CHECK-C-NEXT: [[CONV:%.*]] = fptrunc float [[EXT]] to bfloat | |
| // CHECK-C-NEXT: [[TMP1:%.*]] = atomicrmw fadd ptr @bf, bfloat [[CONV]] seq_cst, align 2 | |
| // CHECK-C-NEXT: [[TMP2:%.*]] = fadd bfloat [[TMP1]], [[CONV]] | |
| // CHECK-C-NEXT: ret void | |
| // | |
| // CHECK-CPP-LABEL: define dso_local void @_Z13test_bf16_addu6__bf16( | |
| // CHECK-CPP-SAME: bfloat noundef [[VAL:%.*]]) #[[ATTR0]] { | |
| // CHECK-CPP-NEXT: [[ENTRY:.*:]] | |
| // CHECK-CPP-NEXT: [[VAL_ADDR:%.*]] = alloca bfloat, align 2 | |
| // CHECK-CPP-NEXT: store bfloat [[VAL]], ptr [[VAL_ADDR]], align 2 | |
| // CHECK-CPP-NEXT: [[TMP0:%.*]] = load bfloat, ptr [[VAL_ADDR]], align 2 | |
| // CHECK-CPP-NEXT: [[EXT:%.*]] = fpext bfloat [[TMP0]] to float | |
| // CHECK-CPP-NEXT: [[CONV:%.*]] = fptrunc float [[EXT]] to bfloat | |
| // CHECK-CPP-NEXT: [[TMP1:%.*]] = atomicrmw fadd ptr @bf, bfloat [[CONV]] seq_cst, align 2 | |
| // CHECK-CPP-NEXT: [[TMP2:%.*]] = fadd bfloat [[TMP1]], [[CONV]] | |
| // CHECK-CPP-NEXT: ret void | |
| // | |
| void test_bf16_add(__bf16 val){ | |
| bf += val; | |
| } | |
| // CHECK-C-LABEL: define dso_local void @test_f16_add( | |
| // CHECK-C-SAME: half noundef [[VAL:%.*]]) #[[ATTR0]] { | |
| // CHECK-C-NEXT: [[ENTRY:.*:]] | |
| // CHECK-C-NEXT: [[VAL_ADDR:%.*]] = alloca half, align 2 | |
| // CHECK-C-NEXT: store half [[VAL]], ptr [[VAL_ADDR]], align 2 | |
| // CHECK-C-NEXT: [[TMP0:%.*]] = load half, ptr [[VAL_ADDR]], align 2 | |
| // CHECK-C-NEXT: [[TMP1:%.*]] = atomicrmw fadd ptr @h, half [[TMP0]] seq_cst, align 2 | |
| // CHECK-C-NEXT: [[TMP2:%.*]] = fadd half [[TMP1]], [[TMP0]] | |
| // CHECK-C-NEXT: ret void | |
| // | |
| // CHECK-CPP-LABEL: define dso_local void @_Z12test_f16_addDF16_( | |
| // CHECK-CPP-SAME: half noundef [[VAL:%.*]]) #[[ATTR0]] { | |
| // CHECK-CPP-NEXT: [[ENTRY:.*:]] | |
| // CHECK-CPP-NEXT: [[VAL_ADDR:%.*]] = alloca half, align 2 | |
| // CHECK-CPP-NEXT: store half [[VAL]], ptr [[VAL_ADDR]], align 2 | |
| // CHECK-CPP-NEXT: [[TMP0:%.*]] = load half, ptr [[VAL_ADDR]], align 2 | |
| // CHECK-CPP-NEXT: [[TMP1:%.*]] = atomicrmw fadd ptr @h, half [[TMP0]] seq_cst, align 2 | |
| // CHECK-CPP-NEXT: [[TMP2:%.*]] = fadd half [[TMP1]], [[TMP0]] | |
| // CHECK-CPP-NEXT: ret void | |
| // | |
| void test_f16_add(_Float16 val){ | |
| h += val; | |
| } | |
| // CHECK-C-LABEL: define dso_local void @test_float_sub( | |
| // CHECK-C-SAME: float noundef [[VAL:%.*]]) #[[ATTR0]] { | |
| // CHECK-C-NEXT: [[ENTRY:.*:]] | |
| // CHECK-C-NEXT: [[VAL_ADDR:%.*]] = alloca float, align 4 | |
| // CHECK-C-NEXT: store float [[VAL]], ptr [[VAL_ADDR]], align 4 | |
| // CHECK-C-NEXT: [[TMP0:%.*]] = load float, ptr [[VAL_ADDR]], align 4 | |
| // CHECK-C-NEXT: [[TMP1:%.*]] = atomicrmw fsub ptr @f, float [[TMP0]] seq_cst, align 4 | |
| // CHECK-C-NEXT: [[TMP2:%.*]] = fsub float [[TMP1]], [[TMP0]] | |
| // CHECK-C-NEXT: ret void | |
| // | |
| // CHECK-CPP-LABEL: define dso_local void @_Z14test_float_subf( | |
| // CHECK-CPP-SAME: float noundef [[VAL:%.*]]) #[[ATTR0]] { | |
| // CHECK-CPP-NEXT: [[ENTRY:.*:]] | |
| // CHECK-CPP-NEXT: [[VAL_ADDR:%.*]] = alloca float, align 4 | |
| // CHECK-CPP-NEXT: store float [[VAL]], ptr [[VAL_ADDR]], align 4 | |
| // CHECK-CPP-NEXT: [[TMP0:%.*]] = load float, ptr [[VAL_ADDR]], align 4 | |
| // CHECK-CPP-NEXT: [[TMP1:%.*]] = atomicrmw fsub ptr @f, float [[TMP0]] seq_cst, align 4 | |
| // CHECK-CPP-NEXT: [[TMP2:%.*]] = fsub float [[TMP1]], [[TMP0]] | |
| // CHECK-CPP-NEXT: ret void | |
| // | |
| void test_float_sub(float val) { | |
| f -= val; | |
| } | |
| // CHECK-C-LABEL: define dso_local void @test_double_sub( | |
| // CHECK-C-SAME: double noundef [[VAL:%.*]]) #[[ATTR0]] { | |
| // CHECK-C-NEXT: [[ENTRY:.*:]] | |
| // CHECK-C-NEXT: [[VAL_ADDR:%.*]] = alloca double, align 8 | |
| // CHECK-C-NEXT: store double [[VAL]], ptr [[VAL_ADDR]], align 8 | |
| // CHECK-C-NEXT: [[TMP0:%.*]] = load double, ptr [[VAL_ADDR]], align 8 | |
| // CHECK-C-NEXT: [[TMP1:%.*]] = atomicrmw fsub ptr @d, double [[TMP0]] seq_cst, align 8 | |
| // CHECK-C-NEXT: [[TMP2:%.*]] = fsub double [[TMP1]], [[TMP0]] | |
| // CHECK-C-NEXT: ret void | |
| // | |
| // CHECK-CPP-LABEL: define dso_local void @_Z15test_double_subd( | |
| // CHECK-CPP-SAME: double noundef [[VAL:%.*]]) #[[ATTR0]] { | |
| // CHECK-CPP-NEXT: [[ENTRY:.*:]] | |
| // CHECK-CPP-NEXT: [[VAL_ADDR:%.*]] = alloca double, align 8 | |
| // CHECK-CPP-NEXT: store double [[VAL]], ptr [[VAL_ADDR]], align 8 | |
| // CHECK-CPP-NEXT: [[TMP0:%.*]] = load double, ptr [[VAL_ADDR]], align 8 | |
| // CHECK-CPP-NEXT: [[TMP1:%.*]] = atomicrmw fsub ptr @d, double [[TMP0]] seq_cst, align 8 | |
| // CHECK-CPP-NEXT: [[TMP2:%.*]] = fsub double [[TMP1]], [[TMP0]] | |
| // CHECK-CPP-NEXT: ret void | |
| // | |
| void test_double_sub(double val){ | |
| d -= val; | |
| } | |
| // CHECK-C-LABEL: define dso_local void @test_bf16_sub( | |
| // CHECK-C-SAME: bfloat noundef [[VAL:%.*]]) #[[ATTR0]] { | |
| // CHECK-C-NEXT: [[ENTRY:.*:]] | |
| // CHECK-C-NEXT: [[VAL_ADDR:%.*]] = alloca bfloat, align 2 | |
| // CHECK-C-NEXT: store bfloat [[VAL]], ptr [[VAL_ADDR]], align 2 | |
| // CHECK-C-NEXT: [[TMP0:%.*]] = load bfloat, ptr [[VAL_ADDR]], align 2 | |
| // CHECK-C-NEXT: [[EXT:%.*]] = fpext bfloat [[TMP0]] to float | |
| // CHECK-C-NEXT: [[CONV:%.*]] = fptrunc float [[EXT]] to bfloat | |
| // CHECK-C-NEXT: [[TMP1:%.*]] = atomicrmw fsub ptr @bf, bfloat [[CONV]] seq_cst, align 2 | |
| // CHECK-C-NEXT: [[TMP2:%.*]] = fsub bfloat [[TMP1]], [[CONV]] | |
| // CHECK-C-NEXT: ret void | |
| // | |
| // CHECK-CPP-LABEL: define dso_local void @_Z13test_bf16_subu6__bf16( | |
| // CHECK-CPP-SAME: bfloat noundef [[VAL:%.*]]) #[[ATTR0]] { | |
| // CHECK-CPP-NEXT: [[ENTRY:.*:]] | |
| // CHECK-CPP-NEXT: [[VAL_ADDR:%.*]] = alloca bfloat, align 2 | |
| // CHECK-CPP-NEXT: store bfloat [[VAL]], ptr [[VAL_ADDR]], align 2 | |
| // CHECK-CPP-NEXT: [[TMP0:%.*]] = load bfloat, ptr [[VAL_ADDR]], align 2 | |
| // CHECK-CPP-NEXT: [[EXT:%.*]] = fpext bfloat [[TMP0]] to float | |
| // CHECK-CPP-NEXT: [[CONV:%.*]] = fptrunc float [[EXT]] to bfloat | |
| // CHECK-CPP-NEXT: [[TMP1:%.*]] = atomicrmw fsub ptr @bf, bfloat [[CONV]] seq_cst, align 2 | |
| // CHECK-CPP-NEXT: [[TMP2:%.*]] = fsub bfloat [[TMP1]], [[CONV]] | |
| // CHECK-CPP-NEXT: ret void | |
| // | |
| void test_bf16_sub(__bf16 val){ | |
| bf -= val; | |
| } | |
| // CHECK-C-LABEL: define dso_local void @test_f16_sub( | |
| // CHECK-C-SAME: half noundef [[VAL:%.*]]) #[[ATTR0]] { | |
| // CHECK-C-NEXT: [[ENTRY:.*:]] | |
| // CHECK-C-NEXT: [[VAL_ADDR:%.*]] = alloca half, align 2 | |
| // CHECK-C-NEXT: store half [[VAL]], ptr [[VAL_ADDR]], align 2 | |
| // CHECK-C-NEXT: [[TMP0:%.*]] = load half, ptr [[VAL_ADDR]], align 2 | |
| // CHECK-C-NEXT: [[TMP1:%.*]] = atomicrmw fsub ptr @h, half [[TMP0]] seq_cst, align 2 | |
| // CHECK-C-NEXT: [[TMP2:%.*]] = fsub half [[TMP1]], [[TMP0]] | |
| // CHECK-C-NEXT: ret void | |
| // | |
| // CHECK-CPP-LABEL: define dso_local void @_Z12test_f16_subDF16_( | |
| // CHECK-CPP-SAME: half noundef [[VAL:%.*]]) #[[ATTR0]] { | |
| // CHECK-CPP-NEXT: [[ENTRY:.*:]] | |
| // CHECK-CPP-NEXT: [[VAL_ADDR:%.*]] = alloca half, align 2 | |
| // CHECK-CPP-NEXT: store half [[VAL]], ptr [[VAL_ADDR]], align 2 | |
| // CHECK-CPP-NEXT: [[TMP0:%.*]] = load half, ptr [[VAL_ADDR]], align 2 | |
| // CHECK-CPP-NEXT: [[TMP1:%.*]] = atomicrmw fsub ptr @h, half [[TMP0]] seq_cst, align 2 | |
| // CHECK-CPP-NEXT: [[TMP2:%.*]] = fsub half [[TMP1]], [[TMP0]] | |
| // CHECK-CPP-NEXT: ret void | |
| // | |
| void test_f16_sub(_Float16 val){ | |
| h -= val; | |
| } |