| // NOTE: Assertions have been autogenerated by utils/update_cc_test_checks.py |
| // RUN: %clang_cc1 -triple x86_64-unknown-unknown -emit-llvm -o - %s | FileCheck %s |
| |
| // CHECK-LABEL: @add1( |
| // CHECK-NEXT: entry: |
| // CHECK-NEXT: [[A_ADDR:%.*]] = alloca half, align 2 |
| // CHECK-NEXT: [[B_ADDR:%.*]] = alloca half, align 2 |
| // CHECK-NEXT: store half [[A:%.*]], ptr [[A_ADDR]], align 2 |
| // CHECK-NEXT: store half [[B:%.*]], ptr [[B_ADDR]], align 2 |
| // CHECK-NEXT: [[TMP0:%.*]] = load half, ptr [[A_ADDR]], align 2 |
| // CHECK-NEXT: [[EXT:%.*]] = fpext half [[TMP0]] to float |
| // CHECK-NEXT: [[TMP1:%.*]] = load half, ptr [[B_ADDR]], align 2 |
| // CHECK-NEXT: [[EXT1:%.*]] = fpext half [[TMP1]] to float |
| // CHECK-NEXT: [[ADD:%.*]] = fadd float [[EXT]], [[EXT1]] |
| // CHECK-NEXT: [[UNPROMOTION:%.*]] = fptrunc float [[ADD]] to half |
| // CHECK-NEXT: ret half [[UNPROMOTION]] |
| // |
| _Float16 add1(_Float16 a, _Float16 b) { |
| return a + b; |
| } |
| |
| // CHECK-LABEL: @add2( |
| // CHECK-NEXT: entry: |
| // CHECK-NEXT: [[A_ADDR:%.*]] = alloca half, align 2 |
| // CHECK-NEXT: [[B_ADDR:%.*]] = alloca half, align 2 |
| // CHECK-NEXT: [[C_ADDR:%.*]] = alloca half, align 2 |
| // CHECK-NEXT: store half [[A:%.*]], ptr [[A_ADDR]], align 2 |
| // CHECK-NEXT: store half [[B:%.*]], ptr [[B_ADDR]], align 2 |
| // CHECK-NEXT: store half [[C:%.*]], ptr [[C_ADDR]], align 2 |
| // CHECK-NEXT: [[TMP0:%.*]] = load half, ptr [[A_ADDR]], align 2 |
| // CHECK-NEXT: [[EXT:%.*]] = fpext half [[TMP0]] to float |
| // CHECK-NEXT: [[TMP1:%.*]] = load half, ptr [[B_ADDR]], align 2 |
| // CHECK-NEXT: [[EXT1:%.*]] = fpext half [[TMP1]] to float |
| // CHECK-NEXT: [[ADD:%.*]] = fadd float [[EXT]], [[EXT1]] |
| // CHECK-NEXT: [[TMP2:%.*]] = load half, ptr [[C_ADDR]], align 2 |
| // CHECK-NEXT: [[EXT2:%.*]] = fpext half [[TMP2]] to float |
| // CHECK-NEXT: [[ADD3:%.*]] = fadd float [[ADD]], [[EXT2]] |
| // CHECK-NEXT: [[UNPROMOTION:%.*]] = fptrunc float [[ADD3]] to half |
| // CHECK-NEXT: ret half [[UNPROMOTION]] |
| // |
| _Float16 add2(_Float16 a, _Float16 b, _Float16 c) { |
| return a + b + c; |
| } |
| |
| // CHECK-LABEL: @div( |
| // CHECK-NEXT: entry: |
| // CHECK-NEXT: [[A_ADDR:%.*]] = alloca half, align 2 |
| // CHECK-NEXT: [[B_ADDR:%.*]] = alloca half, align 2 |
| // CHECK-NEXT: store half [[A:%.*]], ptr [[A_ADDR]], align 2 |
| // CHECK-NEXT: store half [[B:%.*]], ptr [[B_ADDR]], align 2 |
| // CHECK-NEXT: [[TMP0:%.*]] = load half, ptr [[A_ADDR]], align 2 |
| // CHECK-NEXT: [[EXT:%.*]] = fpext half [[TMP0]] to float |
| // CHECK-NEXT: [[TMP1:%.*]] = load half, ptr [[B_ADDR]], align 2 |
| // CHECK-NEXT: [[EXT1:%.*]] = fpext half [[TMP1]] to float |
| // CHECK-NEXT: [[DIV:%.*]] = fdiv float [[EXT]], [[EXT1]] |
| // CHECK-NEXT: [[UNPROMOTION:%.*]] = fptrunc float [[DIV]] to half |
| // CHECK-NEXT: ret half [[UNPROMOTION]] |
| // |
| _Float16 div(_Float16 a, _Float16 b) { |
| return a / b; |
| } |
| |
| // CHECK-LABEL: @mul( |
| // CHECK-NEXT: entry: |
| // CHECK-NEXT: [[A_ADDR:%.*]] = alloca half, align 2 |
| // CHECK-NEXT: [[B_ADDR:%.*]] = alloca half, align 2 |
| // CHECK-NEXT: store half [[A:%.*]], ptr [[A_ADDR]], align 2 |
| // CHECK-NEXT: store half [[B:%.*]], ptr [[B_ADDR]], align 2 |
| // CHECK-NEXT: [[TMP0:%.*]] = load half, ptr [[A_ADDR]], align 2 |
| // CHECK-NEXT: [[EXT:%.*]] = fpext half [[TMP0]] to float |
| // CHECK-NEXT: [[TMP1:%.*]] = load half, ptr [[B_ADDR]], align 2 |
| // CHECK-NEXT: [[EXT1:%.*]] = fpext half [[TMP1]] to float |
| // CHECK-NEXT: [[MUL:%.*]] = fmul float [[EXT]], [[EXT1]] |
| // CHECK-NEXT: [[UNPROMOTION:%.*]] = fptrunc float [[MUL]] to half |
| // CHECK-NEXT: ret half [[UNPROMOTION]] |
| // |
| _Float16 mul(_Float16 a, _Float16 b) { |
| return a * b; |
| } |
| |
| // CHECK-LABEL: @add_and_mul1( |
| // CHECK-NEXT: entry: |
| // CHECK-NEXT: [[A_ADDR:%.*]] = alloca half, align 2 |
| // CHECK-NEXT: [[B_ADDR:%.*]] = alloca half, align 2 |
| // CHECK-NEXT: [[C_ADDR:%.*]] = alloca half, align 2 |
| // CHECK-NEXT: [[D_ADDR:%.*]] = alloca half, align 2 |
| // CHECK-NEXT: store half [[A:%.*]], ptr [[A_ADDR]], align 2 |
| // CHECK-NEXT: store half [[B:%.*]], ptr [[B_ADDR]], align 2 |
| // CHECK-NEXT: store half [[C:%.*]], ptr [[C_ADDR]], align 2 |
| // CHECK-NEXT: store half [[D:%.*]], ptr [[D_ADDR]], align 2 |
| // CHECK-NEXT: [[TMP0:%.*]] = load half, ptr [[A_ADDR]], align 2 |
| // CHECK-NEXT: [[EXT:%.*]] = fpext half [[TMP0]] to float |
| // CHECK-NEXT: [[TMP1:%.*]] = load half, ptr [[B_ADDR]], align 2 |
| // CHECK-NEXT: [[EXT1:%.*]] = fpext half [[TMP1]] to float |
| // CHECK-NEXT: [[MUL:%.*]] = fmul float [[EXT]], [[EXT1]] |
| // CHECK-NEXT: [[TMP2:%.*]] = load half, ptr [[C_ADDR]], align 2 |
| // CHECK-NEXT: [[EXT2:%.*]] = fpext half [[TMP2]] to float |
| // CHECK-NEXT: [[TMP3:%.*]] = load half, ptr [[D_ADDR]], align 2 |
| // CHECK-NEXT: [[EXT3:%.*]] = fpext half [[TMP3]] to float |
| // CHECK-NEXT: [[MUL4:%.*]] = fmul float [[EXT2]], [[EXT3]] |
| // CHECK-NEXT: [[ADD:%.*]] = fadd float [[MUL]], [[MUL4]] |
| // CHECK-NEXT: [[UNPROMOTION:%.*]] = fptrunc float [[ADD]] to half |
| // CHECK-NEXT: ret half [[UNPROMOTION]] |
| // |
| _Float16 add_and_mul1(_Float16 a, _Float16 b, _Float16 c, _Float16 d) { |
| return a * b + c * d; |
| } |
| |
| // CHECK-LABEL: @add_and_mul2( |
| // CHECK-NEXT: entry: |
| // CHECK-NEXT: [[A_ADDR:%.*]] = alloca half, align 2 |
| // CHECK-NEXT: [[B_ADDR:%.*]] = alloca half, align 2 |
| // CHECK-NEXT: [[C_ADDR:%.*]] = alloca half, align 2 |
| // CHECK-NEXT: store half [[A:%.*]], ptr [[A_ADDR]], align 2 |
| // CHECK-NEXT: store half [[B:%.*]], ptr [[B_ADDR]], align 2 |
| // CHECK-NEXT: store half [[C:%.*]], ptr [[C_ADDR]], align 2 |
| // CHECK-NEXT: [[TMP0:%.*]] = load half, ptr [[A_ADDR]], align 2 |
| // CHECK-NEXT: [[EXT:%.*]] = fpext half [[TMP0]] to float |
| // CHECK-NEXT: [[TMP1:%.*]] = load half, ptr [[B_ADDR]], align 2 |
| // CHECK-NEXT: [[EXT1:%.*]] = fpext half [[TMP1]] to float |
| // CHECK-NEXT: [[MUL:%.*]] = fmul float 6.000000e+00, [[EXT1]] |
| // CHECK-NEXT: [[SUB:%.*]] = fsub float [[EXT]], [[MUL]] |
| // CHECK-NEXT: [[TMP2:%.*]] = load half, ptr [[C_ADDR]], align 2 |
| // CHECK-NEXT: [[EXT2:%.*]] = fpext half [[TMP2]] to float |
| // CHECK-NEXT: [[ADD:%.*]] = fadd float [[SUB]], [[EXT2]] |
| // CHECK-NEXT: [[UNPROMOTION:%.*]] = fptrunc float [[ADD]] to half |
| // CHECK-NEXT: ret half [[UNPROMOTION]] |
| // |
| _Float16 add_and_mul2(_Float16 a, _Float16 b, _Float16 c) { |
| return (a - 6 * b) + c; |
| } |
| |
| // CHECK-LABEL: @addcompound( |
| // CHECK-NEXT: entry: |
| // CHECK-NEXT: [[A_ADDR:%.*]] = alloca half, align 2 |
| // CHECK-NEXT: [[C_ADDR:%.*]] = alloca half, align 2 |
| // CHECK-NEXT: store half [[A:%.*]], ptr [[A_ADDR]], align 2 |
| // CHECK-NEXT: store half [[C:%.*]], ptr [[C_ADDR]], align 2 |
| // CHECK-NEXT: [[TMP0:%.*]] = load half, ptr [[A_ADDR]], align 2 |
| // CHECK-NEXT: [[EXT:%.*]] = fpext half [[TMP0]] to float |
| // CHECK-NEXT: [[TMP1:%.*]] = load half, ptr [[C_ADDR]], align 2 |
| // CHECK-NEXT: [[CONV:%.*]] = fpext half [[TMP1]] to float |
| // CHECK-NEXT: [[ADD:%.*]] = fadd float [[CONV]], [[EXT]] |
| // CHECK-NEXT: [[CONV1:%.*]] = fptrunc float [[ADD]] to half |
| // CHECK-NEXT: store half [[CONV1]], ptr [[C_ADDR]], align 2 |
| // CHECK-NEXT: [[TMP2:%.*]] = load half, ptr [[C_ADDR]], align 2 |
| // CHECK-NEXT: ret half [[TMP2]] |
| // |
| _Float16 addcompound(_Float16 a, _Float16 c) { |
| c += a; |
| return c; |
| } |
| |
| // CHECK-LABEL: @mulcompound_int_float16( |
| // CHECK-NEXT: entry: |
| // CHECK-NEXT: [[A_ADDR:%.*]] = alloca i32, align 4 |
| // CHECK-NEXT: [[C_ADDR:%.*]] = alloca half, align 2 |
| // CHECK-NEXT: store i32 [[A:%.*]], ptr [[A_ADDR]], align 4 |
| // CHECK-NEXT: store half [[C:%.*]], ptr [[C_ADDR]], align 2 |
| // CHECK-NEXT: [[TMP0:%.*]] = load half, ptr [[C_ADDR]], align 2 |
| // CHECK-NEXT: [[EXT:%.*]] = fpext half [[TMP0]] to float |
| // CHECK-NEXT: [[TMP1:%.*]] = load i32, ptr [[A_ADDR]], align 4 |
| // CHECK-NEXT: [[CONV:%.*]] = sitofp i32 [[TMP1]] to float |
| // CHECK-NEXT: [[MUL:%.*]] = fmul float [[CONV]], [[EXT]] |
| // CHECK-NEXT: [[CONV1:%.*]] = fptosi float [[MUL]] to i32 |
| // CHECK-NEXT: store i32 [[CONV1]], ptr [[A_ADDR]], align 4 |
| // CHECK-NEXT: [[TMP2:%.*]] = load half, ptr [[C_ADDR]], align 2 |
| // CHECK-NEXT: ret half [[TMP2]] |
| // |
| _Float16 mulcompound_int_float16(int a, _Float16 c) { |
| a *= c; |
| return c; |
| } |
| |
| // CHECK-LABEL: @mulcompound_float_float16c( |
| // CHECK-NEXT: entry: |
| // CHECK-NEXT: [[C:%.*]] = alloca { half, half }, align 2 |
| // CHECK-NEXT: [[A_ADDR:%.*]] = alloca float, align 4 |
| // CHECK-NEXT: store <2 x half> [[C_COERCE:%.*]], ptr [[C]], align 2 |
| // CHECK-NEXT: store float [[A:%.*]], ptr [[A_ADDR]], align 4 |
| // CHECK-NEXT: [[C_REALP:%.*]] = getelementptr inbounds { half, half }, ptr [[C]], i32 0, i32 0 |
| // CHECK-NEXT: [[C_REAL:%.*]] = load half, ptr [[C_REALP]], align 2 |
| // CHECK-NEXT: [[C_IMAGP:%.*]] = getelementptr inbounds { half, half }, ptr [[C]], i32 0, i32 1 |
| // CHECK-NEXT: [[C_IMAG:%.*]] = load half, ptr [[C_IMAGP]], align 2 |
| // CHECK-NEXT: [[CONV:%.*]] = fpext half [[C_REAL]] to float |
| // CHECK-NEXT: [[CONV1:%.*]] = fpext half [[C_IMAG]] to float |
| // CHECK-NEXT: [[TMP0:%.*]] = load float, ptr [[A_ADDR]], align 4 |
| // CHECK-NEXT: [[MUL_RL:%.*]] = fmul float [[TMP0]], [[CONV]] |
| // CHECK-NEXT: [[MUL_IR:%.*]] = fmul float [[TMP0]], [[CONV1]] |
| // CHECK-NEXT: store float [[MUL_RL]], ptr [[A_ADDR]], align 4 |
| // CHECK-NEXT: [[C_REALP2:%.*]] = getelementptr inbounds { half, half }, ptr [[C]], i32 0, i32 0 |
| // CHECK-NEXT: [[C_REAL3:%.*]] = load half, ptr [[C_REALP2]], align 2 |
| // CHECK-NEXT: ret half [[C_REAL3]] |
| // |
| _Float16 mulcompound_float_float16c(float a, _Float16 _Complex c) { |
| a *= c; |
| return c; |
| } |
| |
| // CHECK-LABEL: @RealOp( |
| // CHECK-NEXT: entry: |
| // CHECK-NEXT: [[A_ADDR:%.*]] = alloca half, align 2 |
| // CHECK-NEXT: store half [[A:%.*]], ptr [[A_ADDR]], align 2 |
| // CHECK-NEXT: [[TMP0:%.*]] = load half, ptr [[A_ADDR]], align 2 |
| // CHECK-NEXT: [[EXT:%.*]] = fpext half [[TMP0]] to float |
| // CHECK-NEXT: [[UNPROMOTION:%.*]] = fptrunc float [[EXT]] to half |
| // CHECK-NEXT: ret half [[UNPROMOTION]] |
| // |
| _Float16 RealOp(_Float16 a) { |
| return __real a; |
| } |
| |
| // CHECK-LABEL: @RealOp_c( |
| // CHECK-NEXT: entry: |
| // CHECK-NEXT: [[A:%.*]] = alloca { half, half }, align 2 |
| // CHECK-NEXT: store <2 x half> [[A_COERCE:%.*]], ptr [[A]], align 2 |
| // CHECK-NEXT: [[A_REALP:%.*]] = getelementptr inbounds { half, half }, ptr [[A]], i32 0, i32 0 |
| // CHECK-NEXT: [[A_REAL:%.*]] = load half, ptr [[A_REALP]], align 2 |
| // CHECK-NEXT: [[EXT:%.*]] = fpext half [[A_REAL]] to float |
| // CHECK-NEXT: [[UNPROMOTION:%.*]] = fptrunc float [[EXT]] to half |
| // CHECK-NEXT: ret half [[UNPROMOTION]] |
| // |
| _Float16 RealOp_c(_Float16 _Complex a) { |
| return __real a; |
| } |
| |
| // CHECK-LABEL: @ImagOp( |
| // CHECK-NEXT: entry: |
| // CHECK-NEXT: [[A_ADDR:%.*]] = alloca half, align 2 |
| // CHECK-NEXT: store half [[A:%.*]], ptr [[A_ADDR]], align 2 |
| // CHECK-NEXT: [[TMP0:%.*]] = load half, ptr [[A_ADDR]], align 2 |
| // CHECK-NEXT: [[EXT:%.*]] = fpext half [[TMP0]] to float |
| // CHECK-NEXT: ret half 0xH0000 |
| // |
| _Float16 ImagOp(_Float16 a) { |
| return __imag a; |
| } |
| |
| // CHECK-LABEL: @ImagOp_c( |
| // CHECK-NEXT: entry: |
| // CHECK-NEXT: [[A:%.*]] = alloca { half, half }, align 2 |
| // CHECK-NEXT: store <2 x half> [[A_COERCE:%.*]], ptr [[A]], align 2 |
| // CHECK-NEXT: [[A_IMAGP:%.*]] = getelementptr inbounds { half, half }, ptr [[A]], i32 0, i32 1 |
| // CHECK-NEXT: [[A_IMAG:%.*]] = load half, ptr [[A_IMAGP]], align 2 |
| // CHECK-NEXT: [[EXT:%.*]] = fpext half [[A_IMAG]] to float |
| // CHECK-NEXT: [[UNPROMOTION:%.*]] = fptrunc float [[EXT]] to half |
| // CHECK-NEXT: ret half [[UNPROMOTION]] |
| // |
| _Float16 ImagOp_c(_Float16 _Complex a) { |
| return __imag a; |
| } |
| |
| // CHECK-LABEL: @MinusOp_r( |
| // CHECK-NEXT: entry: |
| // CHECK-NEXT: [[A_ADDR:%.*]] = alloca half, align 2 |
| // CHECK-NEXT: store half [[A:%.*]], ptr [[A_ADDR]], align 2 |
| // CHECK-NEXT: [[TMP0:%.*]] = load half, ptr [[A_ADDR]], align 2 |
| // CHECK-NEXT: [[EXT:%.*]] = fpext half [[TMP0]] to float |
| // CHECK-NEXT: [[FNEG:%.*]] = fneg float [[EXT]] |
| // CHECK-NEXT: [[UNPROMOTION:%.*]] = fptrunc float [[FNEG]] to half |
| // CHECK-NEXT: ret half [[UNPROMOTION]] |
| // |
| _Float16 MinusOp_r(_Float16 a) { |
| return -a; |
| } |
| |
| // CHECK-LABEL: @MinusOp_c( |
| // CHECK-NEXT: entry: |
| // CHECK-NEXT: [[A:%.*]] = alloca { half, half }, align 2 |
| // CHECK-NEXT: store <2 x half> [[A_COERCE:%.*]], ptr [[A]], align 2 |
| // CHECK-NEXT: [[A_REALP:%.*]] = getelementptr inbounds { half, half }, ptr [[A]], i32 0, i32 0 |
| // CHECK-NEXT: [[A_REAL:%.*]] = load half, ptr [[A_REALP]], align 2 |
| // CHECK-NEXT: [[A_IMAGP:%.*]] = getelementptr inbounds { half, half }, ptr [[A]], i32 0, i32 1 |
| // CHECK-NEXT: [[A_IMAG:%.*]] = load half, ptr [[A_IMAGP]], align 2 |
| // CHECK-NEXT: [[EXT:%.*]] = fpext half [[A_REAL]] to float |
| // CHECK-NEXT: [[EXT1:%.*]] = fpext half [[A_IMAG]] to float |
| // CHECK-NEXT: [[NEG_R:%.*]] = fneg float [[EXT]] |
| // CHECK-NEXT: [[NEG_I:%.*]] = fneg float [[EXT1]] |
| // CHECK-NEXT: [[UNPROMOTION:%.*]] = fptrunc float [[NEG_R]] to half |
| // CHECK-NEXT: [[UNPROMOTION2:%.*]] = fptrunc float [[NEG_I]] to half |
| // CHECK-NEXT: ret half [[UNPROMOTION]] |
| // |
| _Float16 MinusOp_c(_Float16 _Complex a) { |
| return -a; |
| } |
| |
| // CHECK-LABEL: @PlusOp_r( |
| // CHECK-NEXT: entry: |
| // CHECK-NEXT: [[A_ADDR:%.*]] = alloca half, align 2 |
| // CHECK-NEXT: store half [[A:%.*]], ptr [[A_ADDR]], align 2 |
| // CHECK-NEXT: [[TMP0:%.*]] = load half, ptr [[A_ADDR]], align 2 |
| // CHECK-NEXT: [[EXT:%.*]] = fpext half [[TMP0]] to float |
| // CHECK-NEXT: [[UNPROMOTION:%.*]] = fptrunc float [[EXT]] to half |
| // CHECK-NEXT: ret half [[UNPROMOTION]] |
| // |
| _Float16 PlusOp_r(_Float16 a) { |
| return +a; |
| } |
| |
| // CHECK-LABEL: @PlusOp_c( |
| // CHECK-NEXT: entry: |
| // CHECK-NEXT: [[A:%.*]] = alloca { half, half }, align 2 |
| // CHECK-NEXT: store <2 x half> [[A_COERCE:%.*]], ptr [[A]], align 2 |
| // CHECK-NEXT: [[A_REALP:%.*]] = getelementptr inbounds { half, half }, ptr [[A]], i32 0, i32 0 |
| // CHECK-NEXT: [[A_REAL:%.*]] = load half, ptr [[A_REALP]], align 2 |
| // CHECK-NEXT: [[A_IMAGP:%.*]] = getelementptr inbounds { half, half }, ptr [[A]], i32 0, i32 1 |
| // CHECK-NEXT: [[A_IMAG:%.*]] = load half, ptr [[A_IMAGP]], align 2 |
| // CHECK-NEXT: [[EXT:%.*]] = fpext half [[A_REAL]] to float |
| // CHECK-NEXT: [[EXT1:%.*]] = fpext half [[A_IMAG]] to float |
| // CHECK-NEXT: [[UNPROMOTION:%.*]] = fptrunc float [[EXT]] to half |
| // CHECK-NEXT: [[UNPROMOTION2:%.*]] = fptrunc float [[EXT1]] to half |
| // CHECK-NEXT: ret half [[UNPROMOTION]] |
| // |
| _Float16 PlusOp_c(_Float16 _Complex a) { |
| return +a; |
| } |
| |
| // CHECK-LABEL: @MinusOp_r_r( |
| // CHECK-NEXT: entry: |
| // CHECK-NEXT: [[A_ADDR:%.*]] = alloca half, align 2 |
| // CHECK-NEXT: [[C_ADDR:%.*]] = alloca half, align 2 |
| // CHECK-NEXT: store half [[A:%.*]], ptr [[A_ADDR]], align 2 |
| // CHECK-NEXT: store half [[C:%.*]], ptr [[C_ADDR]], align 2 |
| // CHECK-NEXT: [[TMP0:%.*]] = load half, ptr [[A_ADDR]], align 2 |
| // CHECK-NEXT: [[EXT:%.*]] = fpext half [[TMP0]] to float |
| // CHECK-NEXT: [[TMP1:%.*]] = load half, ptr [[C_ADDR]], align 2 |
| // CHECK-NEXT: [[EXT1:%.*]] = fpext half [[TMP1]] to float |
| // CHECK-NEXT: [[FNEG:%.*]] = fneg float [[EXT1]] |
| // CHECK-NEXT: [[ADD:%.*]] = fadd float [[EXT]], [[FNEG]] |
| // CHECK-NEXT: [[UNPROMOTION:%.*]] = fptrunc float [[ADD]] to half |
| // CHECK-NEXT: ret half [[UNPROMOTION]] |
| // |
| _Float16 MinusOp_r_r(_Float16 a, _Float16 c) { |
| return a + -c; |
| } |
| |
| // CHECK-LABEL: @MinusOp_c_r( |
| // CHECK-NEXT: entry: |
| // CHECK-NEXT: [[A:%.*]] = alloca { half, half }, align 2 |
| // CHECK-NEXT: [[C_ADDR:%.*]] = alloca half, align 2 |
| // CHECK-NEXT: store <2 x half> [[A_COERCE:%.*]], ptr [[A]], align 2 |
| // CHECK-NEXT: store half [[C:%.*]], ptr [[C_ADDR]], align 2 |
| // CHECK-NEXT: [[A_REALP:%.*]] = getelementptr inbounds { half, half }, ptr [[A]], i32 0, i32 0 |
| // CHECK-NEXT: [[A_REAL:%.*]] = load half, ptr [[A_REALP]], align 2 |
| // CHECK-NEXT: [[A_IMAGP:%.*]] = getelementptr inbounds { half, half }, ptr [[A]], i32 0, i32 1 |
| // CHECK-NEXT: [[A_IMAG:%.*]] = load half, ptr [[A_IMAGP]], align 2 |
| // CHECK-NEXT: [[EXT:%.*]] = fpext half [[A_REAL]] to float |
| // CHECK-NEXT: [[EXT1:%.*]] = fpext half [[A_IMAG]] to float |
| // CHECK-NEXT: [[TMP0:%.*]] = load half, ptr [[C_ADDR]], align 2 |
| // CHECK-NEXT: [[EXT2:%.*]] = fpext half [[TMP0]] to float |
| // CHECK-NEXT: [[FNEG:%.*]] = fneg float [[EXT2]] |
| // CHECK-NEXT: [[ADD_R:%.*]] = fadd float [[EXT]], [[FNEG]] |
| // CHECK-NEXT: [[UNPROMOTION:%.*]] = fptrunc float [[ADD_R]] to half |
| // CHECK-NEXT: [[UNPROMOTION3:%.*]] = fptrunc float [[EXT1]] to half |
| // CHECK-NEXT: ret half [[UNPROMOTION]] |
| // |
| _Float16 MinusOp_c_r(_Float16 _Complex a, _Float16 c) { |
| return a + -c; |
| } |
| |
| // CHECK-LABEL: @MinusOp_r_c( |
| // CHECK-NEXT: entry: |
| // CHECK-NEXT: [[C:%.*]] = alloca { half, half }, align 2 |
| // CHECK-NEXT: [[A_ADDR:%.*]] = alloca half, align 2 |
| // CHECK-NEXT: store <2 x half> [[C_COERCE:%.*]], ptr [[C]], align 2 |
| // CHECK-NEXT: store half [[A:%.*]], ptr [[A_ADDR]], align 2 |
| // CHECK-NEXT: [[TMP0:%.*]] = load half, ptr [[A_ADDR]], align 2 |
| // CHECK-NEXT: [[EXT:%.*]] = fpext half [[TMP0]] to float |
| // CHECK-NEXT: [[C_REALP:%.*]] = getelementptr inbounds { half, half }, ptr [[C]], i32 0, i32 0 |
| // CHECK-NEXT: [[C_REAL:%.*]] = load half, ptr [[C_REALP]], align 2 |
| // CHECK-NEXT: [[C_IMAGP:%.*]] = getelementptr inbounds { half, half }, ptr [[C]], i32 0, i32 1 |
| // CHECK-NEXT: [[C_IMAG:%.*]] = load half, ptr [[C_IMAGP]], align 2 |
| // CHECK-NEXT: [[EXT1:%.*]] = fpext half [[C_REAL]] to float |
| // CHECK-NEXT: [[EXT2:%.*]] = fpext half [[C_IMAG]] to float |
| // CHECK-NEXT: [[NEG_R:%.*]] = fneg float [[EXT1]] |
| // CHECK-NEXT: [[NEG_I:%.*]] = fneg float [[EXT2]] |
| // CHECK-NEXT: [[ADD_R:%.*]] = fadd float [[EXT]], [[NEG_R]] |
| // CHECK-NEXT: [[UNPROMOTION:%.*]] = fptrunc float [[ADD_R]] to half |
| // CHECK-NEXT: [[UNPROMOTION3:%.*]] = fptrunc float [[NEG_I]] to half |
| // CHECK-NEXT: ret half [[UNPROMOTION]] |
| // |
| _Float16 MinusOp_r_c(_Float16 a, _Float16 _Complex c) { |
| return a + -c; |
| } |
| |
| // CHECK-LABEL: @MinusOp_c_c( |
| // CHECK-NEXT: entry: |
| // CHECK-NEXT: [[A:%.*]] = alloca { half, half }, align 2 |
| // CHECK-NEXT: [[C:%.*]] = alloca { half, half }, align 2 |
| // CHECK-NEXT: store <2 x half> [[A_COERCE:%.*]], ptr [[A]], align 2 |
| // CHECK-NEXT: store <2 x half> [[C_COERCE:%.*]], ptr [[C]], align 2 |
| // CHECK-NEXT: [[A_REALP:%.*]] = getelementptr inbounds { half, half }, ptr [[A]], i32 0, i32 0 |
| // CHECK-NEXT: [[A_REAL:%.*]] = load half, ptr [[A_REALP]], align 2 |
| // CHECK-NEXT: [[A_IMAGP:%.*]] = getelementptr inbounds { half, half }, ptr [[A]], i32 0, i32 1 |
| // CHECK-NEXT: [[A_IMAG:%.*]] = load half, ptr [[A_IMAGP]], align 2 |
| // CHECK-NEXT: [[EXT:%.*]] = fpext half [[A_REAL]] to float |
| // CHECK-NEXT: [[EXT1:%.*]] = fpext half [[A_IMAG]] to float |
| // CHECK-NEXT: [[C_REALP:%.*]] = getelementptr inbounds { half, half }, ptr [[C]], i32 0, i32 0 |
| // CHECK-NEXT: [[C_REAL:%.*]] = load half, ptr [[C_REALP]], align 2 |
| // CHECK-NEXT: [[C_IMAGP:%.*]] = getelementptr inbounds { half, half }, ptr [[C]], i32 0, i32 1 |
| // CHECK-NEXT: [[C_IMAG:%.*]] = load half, ptr [[C_IMAGP]], align 2 |
| // CHECK-NEXT: [[EXT2:%.*]] = fpext half [[C_REAL]] to float |
| // CHECK-NEXT: [[EXT3:%.*]] = fpext half [[C_IMAG]] to float |
| // CHECK-NEXT: [[NEG_R:%.*]] = fneg float [[EXT2]] |
| // CHECK-NEXT: [[NEG_I:%.*]] = fneg float [[EXT3]] |
| // CHECK-NEXT: [[ADD_R:%.*]] = fadd float [[EXT]], [[NEG_R]] |
| // CHECK-NEXT: [[ADD_I:%.*]] = fadd float [[EXT1]], [[NEG_I]] |
| // CHECK-NEXT: [[UNPROMOTION:%.*]] = fptrunc float [[ADD_R]] to half |
| // CHECK-NEXT: [[UNPROMOTION4:%.*]] = fptrunc float [[ADD_I]] to half |
| // CHECK-NEXT: ret half [[UNPROMOTION]] |
| // |
| _Float16 MinusOp_c_c(_Float16 _Complex a, _Float16 _Complex c) { |
| return a + -c; |
| } |
| |
| // CHECK-LABEL: @PlusOp_r_r( |
| // CHECK-NEXT: entry: |
| // CHECK-NEXT: [[A_ADDR:%.*]] = alloca half, align 2 |
| // CHECK-NEXT: [[C_ADDR:%.*]] = alloca half, align 2 |
| // CHECK-NEXT: store half [[A:%.*]], ptr [[A_ADDR]], align 2 |
| // CHECK-NEXT: store half [[C:%.*]], ptr [[C_ADDR]], align 2 |
| // CHECK-NEXT: [[TMP0:%.*]] = load half, ptr [[A_ADDR]], align 2 |
| // CHECK-NEXT: [[EXT:%.*]] = fpext half [[TMP0]] to float |
| // CHECK-NEXT: [[TMP1:%.*]] = load half, ptr [[C_ADDR]], align 2 |
| // CHECK-NEXT: [[EXT1:%.*]] = fpext half [[TMP1]] to float |
| // CHECK-NEXT: [[SUB:%.*]] = fsub float [[EXT]], [[EXT1]] |
| // CHECK-NEXT: [[UNPROMOTION:%.*]] = fptrunc float [[SUB]] to half |
| // CHECK-NEXT: ret half [[UNPROMOTION]] |
| // |
| _Float16 PlusOp_r_r(_Float16 a, _Float16 c) { |
| return a - +c; |
| } |
| |
| // CHECK-LABEL: @PlusOp_c_r( |
| // CHECK-NEXT: entry: |
| // CHECK-NEXT: [[A:%.*]] = alloca { half, half }, align 2 |
| // CHECK-NEXT: [[C_ADDR:%.*]] = alloca half, align 2 |
| // CHECK-NEXT: store <2 x half> [[A_COERCE:%.*]], ptr [[A]], align 2 |
| // CHECK-NEXT: store half [[C:%.*]], ptr [[C_ADDR]], align 2 |
| // CHECK-NEXT: [[A_REALP:%.*]] = getelementptr inbounds { half, half }, ptr [[A]], i32 0, i32 0 |
| // CHECK-NEXT: [[A_REAL:%.*]] = load half, ptr [[A_REALP]], align 2 |
| // CHECK-NEXT: [[A_IMAGP:%.*]] = getelementptr inbounds { half, half }, ptr [[A]], i32 0, i32 1 |
| // CHECK-NEXT: [[A_IMAG:%.*]] = load half, ptr [[A_IMAGP]], align 2 |
| // CHECK-NEXT: [[EXT:%.*]] = fpext half [[A_REAL]] to float |
| // CHECK-NEXT: [[EXT1:%.*]] = fpext half [[A_IMAG]] to float |
| // CHECK-NEXT: [[TMP0:%.*]] = load half, ptr [[C_ADDR]], align 2 |
| // CHECK-NEXT: [[EXT2:%.*]] = fpext half [[TMP0]] to float |
| // CHECK-NEXT: [[SUB_R:%.*]] = fsub float [[EXT]], [[EXT2]] |
| // CHECK-NEXT: [[UNPROMOTION:%.*]] = fptrunc float [[SUB_R]] to half |
| // CHECK-NEXT: [[UNPROMOTION3:%.*]] = fptrunc float [[EXT1]] to half |
| // CHECK-NEXT: ret half [[UNPROMOTION]] |
| // |
| _Float16 PlusOp_c_r(_Float16 _Complex a, _Float16 c) { |
| return a - +c; |
| } |
| |
| // CHECK-LABEL: @PlusOp_r_c( |
| // CHECK-NEXT: entry: |
| // CHECK-NEXT: [[C:%.*]] = alloca { half, half }, align 2 |
| // CHECK-NEXT: [[A_ADDR:%.*]] = alloca half, align 2 |
| // CHECK-NEXT: store <2 x half> [[C_COERCE:%.*]], ptr [[C]], align 2 |
| // CHECK-NEXT: store half [[A:%.*]], ptr [[A_ADDR]], align 2 |
| // CHECK-NEXT: [[TMP0:%.*]] = load half, ptr [[A_ADDR]], align 2 |
| // CHECK-NEXT: [[EXT:%.*]] = fpext half [[TMP0]] to float |
| // CHECK-NEXT: [[C_REALP:%.*]] = getelementptr inbounds { half, half }, ptr [[C]], i32 0, i32 0 |
| // CHECK-NEXT: [[C_REAL:%.*]] = load half, ptr [[C_REALP]], align 2 |
| // CHECK-NEXT: [[C_IMAGP:%.*]] = getelementptr inbounds { half, half }, ptr [[C]], i32 0, i32 1 |
| // CHECK-NEXT: [[C_IMAG:%.*]] = load half, ptr [[C_IMAGP]], align 2 |
| // CHECK-NEXT: [[EXT1:%.*]] = fpext half [[C_REAL]] to float |
| // CHECK-NEXT: [[EXT2:%.*]] = fpext half [[C_IMAG]] to float |
| // CHECK-NEXT: [[SUB_R:%.*]] = fsub float [[EXT]], [[EXT1]] |
| // CHECK-NEXT: [[SUB_I:%.*]] = fneg float [[EXT2]] |
| // CHECK-NEXT: [[UNPROMOTION:%.*]] = fptrunc float [[SUB_R]] to half |
| // CHECK-NEXT: [[UNPROMOTION3:%.*]] = fptrunc float [[SUB_I]] to half |
| // CHECK-NEXT: ret half [[UNPROMOTION]] |
| // |
| _Float16 PlusOp_r_c(_Float16 a, _Float16 _Complex c) { |
| return a - +c; |
| } |
| |
| // CHECK-LABEL: @PlusOp_c_c( |
| // CHECK-NEXT: entry: |
| // CHECK-NEXT: [[A:%.*]] = alloca { half, half }, align 2 |
| // CHECK-NEXT: [[C:%.*]] = alloca { half, half }, align 2 |
| // CHECK-NEXT: store <2 x half> [[A_COERCE:%.*]], ptr [[A]], align 2 |
| // CHECK-NEXT: store <2 x half> [[C_COERCE:%.*]], ptr [[C]], align 2 |
| // CHECK-NEXT: [[A_REALP:%.*]] = getelementptr inbounds { half, half }, ptr [[A]], i32 0, i32 0 |
| // CHECK-NEXT: [[A_REAL:%.*]] = load half, ptr [[A_REALP]], align 2 |
| // CHECK-NEXT: [[A_IMAGP:%.*]] = getelementptr inbounds { half, half }, ptr [[A]], i32 0, i32 1 |
| // CHECK-NEXT: [[A_IMAG:%.*]] = load half, ptr [[A_IMAGP]], align 2 |
| // CHECK-NEXT: [[EXT:%.*]] = fpext half [[A_REAL]] to float |
| // CHECK-NEXT: [[EXT1:%.*]] = fpext half [[A_IMAG]] to float |
| // CHECK-NEXT: [[C_REALP:%.*]] = getelementptr inbounds { half, half }, ptr [[C]], i32 0, i32 0 |
| // CHECK-NEXT: [[C_REAL:%.*]] = load half, ptr [[C_REALP]], align 2 |
| // CHECK-NEXT: [[C_IMAGP:%.*]] = getelementptr inbounds { half, half }, ptr [[C]], i32 0, i32 1 |
| // CHECK-NEXT: [[C_IMAG:%.*]] = load half, ptr [[C_IMAGP]], align 2 |
| // CHECK-NEXT: [[EXT2:%.*]] = fpext half [[C_REAL]] to float |
| // CHECK-NEXT: [[EXT3:%.*]] = fpext half [[C_IMAG]] to float |
| // CHECK-NEXT: [[SUB_R:%.*]] = fsub float [[EXT]], [[EXT2]] |
| // CHECK-NEXT: [[SUB_I:%.*]] = fsub float [[EXT1]], [[EXT3]] |
| // CHECK-NEXT: [[UNPROMOTION:%.*]] = fptrunc float [[SUB_R]] to half |
| // CHECK-NEXT: [[UNPROMOTION4:%.*]] = fptrunc float [[SUB_I]] to half |
| // CHECK-NEXT: ret half [[UNPROMOTION]] |
| // |
| _Float16 PlusOp_c_c(_Float16 _Complex a, _Float16 _Complex c) { |
| return a - +c; |
| } |