Use the DataLayout-aware TargetFolder instead of ConstantFolder in Clang's CGBuilder. The primary impact of this change is that GEP constant expressions are now emitted in canonical `getelementptr i8` form. This is in preparation for the migration to ptradd, which requires this form. Part of the test updates were performed by Claude Code and reviewed by me.
599 lines
35 KiB
C
599 lines
35 KiB
C
// NOTE: Assertions have been autogenerated by utils/update_cc_test_checks.py UTC_ARGS: --version 6
|
|
// RUN: %clang_cc1 %s -emit-llvm -triple x86_64-unknown-unknown -o - | FileCheck %s
|
|
|
|
// CHECK-LABEL: define dso_local i32 @main(
|
|
// CHECK-SAME: ) #[[ATTR0:[0-9]+]] {
|
|
// CHECK-NEXT: [[ENTRY:.*]]:
|
|
// CHECK-NEXT: [[RETVAL:%.*]] = alloca i32, align 4
|
|
// CHECK-NEXT: [[A:%.*]] = alloca { double, double }, align 8
|
|
// CHECK-NEXT: [[B:%.*]] = alloca { double, double }, align 8
|
|
// CHECK-NEXT: store i32 0, ptr [[RETVAL]], align 4
|
|
// CHECK-NEXT: [[A_REALP:%.*]] = getelementptr inbounds nuw { double, double }, ptr [[A]], i32 0, i32 0
|
|
// CHECK-NEXT: [[A_IMAGP:%.*]] = getelementptr inbounds nuw { double, double }, ptr [[A]], i32 0, i32 1
|
|
// CHECK-NEXT: store double 5.000000e+00, ptr [[A_REALP]], align 8
|
|
// CHECK-NEXT: store double 0.000000e+00, ptr [[A_IMAGP]], align 8
|
|
// CHECK-NEXT: [[B_REALP:%.*]] = getelementptr inbounds nuw { double, double }, ptr [[B]], i32 0, i32 0
|
|
// CHECK-NEXT: [[B_IMAGP:%.*]] = getelementptr inbounds nuw { double, double }, ptr [[B]], i32 0, i32 1
|
|
// CHECK-NEXT: store double 4.200000e+01, ptr [[B_REALP]], align 8
|
|
// CHECK-NEXT: store double 0.000000e+00, ptr [[B_IMAGP]], align 8
|
|
// CHECK-NEXT: [[A_REALP1:%.*]] = getelementptr inbounds nuw { double, double }, ptr [[A]], i32 0, i32 0
|
|
// CHECK-NEXT: [[A_REAL:%.*]] = load double, ptr [[A_REALP1]], align 8
|
|
// CHECK-NEXT: [[A_IMAGP2:%.*]] = getelementptr inbounds nuw { double, double }, ptr [[A]], i32 0, i32 1
|
|
// CHECK-NEXT: [[A_IMAG:%.*]] = load double, ptr [[A_IMAGP2]], align 8
|
|
// CHECK-NEXT: [[B_REALP3:%.*]] = getelementptr inbounds nuw { double, double }, ptr [[B]], i32 0, i32 0
|
|
// CHECK-NEXT: [[B_REAL:%.*]] = load double, ptr [[B_REALP3]], align 8
|
|
// CHECK-NEXT: [[B_IMAGP4:%.*]] = getelementptr inbounds nuw { double, double }, ptr [[B]], i32 0, i32 1
|
|
// CHECK-NEXT: [[B_IMAG:%.*]] = load double, ptr [[B_IMAGP4]], align 8
|
|
// CHECK-NEXT: [[MUL_AC:%.*]] = fmul double [[A_REAL]], [[B_REAL]]
|
|
// CHECK-NEXT: [[MUL_BD:%.*]] = fmul double [[A_IMAG]], [[B_IMAG]]
|
|
// CHECK-NEXT: [[MUL_AD:%.*]] = fmul double [[A_REAL]], [[B_IMAG]]
|
|
// CHECK-NEXT: [[MUL_BC:%.*]] = fmul double [[A_IMAG]], [[B_REAL]]
|
|
// CHECK-NEXT: [[MUL_R:%.*]] = fsub double [[MUL_AC]], [[MUL_BD]]
|
|
// CHECK-NEXT: [[MUL_I:%.*]] = fadd double [[MUL_AD]], [[MUL_BC]]
|
|
// CHECK-NEXT: [[ISNAN_CMP:%.*]] = fcmp uno double [[MUL_R]], [[MUL_R]]
|
|
// CHECK-NEXT: br i1 [[ISNAN_CMP]], label %[[COMPLEX_MUL_IMAG_NAN:.*]], label %[[COMPLEX_MUL_CONT:.*]], !prof [[PROF2:![0-9]+]]
|
|
// CHECK: [[COMPLEX_MUL_IMAG_NAN]]:
|
|
// CHECK-NEXT: [[ISNAN_CMP5:%.*]] = fcmp uno double [[MUL_I]], [[MUL_I]]
|
|
// CHECK-NEXT: br i1 [[ISNAN_CMP5]], label %[[COMPLEX_MUL_LIBCALL:.*]], label %[[COMPLEX_MUL_CONT]], !prof [[PROF2]]
|
|
// CHECK: [[COMPLEX_MUL_LIBCALL]]:
|
|
// CHECK-NEXT: [[CALL:%.*]] = call { double, double } @__muldc3(double noundef [[A_REAL]], double noundef [[A_IMAG]], double noundef [[B_REAL]], double noundef [[B_IMAG]]) #[[ATTR4:[0-9]+]]
|
|
// CHECK-NEXT: [[TMP0:%.*]] = extractvalue { double, double } [[CALL]], 0
|
|
// CHECK-NEXT: [[TMP1:%.*]] = extractvalue { double, double } [[CALL]], 1
|
|
// CHECK-NEXT: br label %[[COMPLEX_MUL_CONT]]
|
|
// CHECK: [[COMPLEX_MUL_CONT]]:
|
|
// CHECK-NEXT: [[REAL_MUL_PHI:%.*]] = phi double [ [[MUL_R]], %[[ENTRY]] ], [ [[MUL_R]], %[[COMPLEX_MUL_IMAG_NAN]] ], [ [[TMP0]], %[[COMPLEX_MUL_LIBCALL]] ]
|
|
// CHECK-NEXT: [[IMAG_MUL_PHI:%.*]] = phi double [ [[MUL_I]], %[[ENTRY]] ], [ [[MUL_I]], %[[COMPLEX_MUL_IMAG_NAN]] ], [ [[TMP1]], %[[COMPLEX_MUL_LIBCALL]] ]
|
|
// CHECK-NEXT: [[B_REALP6:%.*]] = getelementptr inbounds nuw { double, double }, ptr [[B]], i32 0, i32 0
|
|
// CHECK-NEXT: [[B_REAL7:%.*]] = load double, ptr [[B_REALP6]], align 8
|
|
// CHECK-NEXT: [[B_IMAGP8:%.*]] = getelementptr inbounds nuw { double, double }, ptr [[B]], i32 0, i32 1
|
|
// CHECK-NEXT: [[B_IMAG9:%.*]] = load double, ptr [[B_IMAGP8]], align 8
|
|
// CHECK-NEXT: [[A_REALP10:%.*]] = getelementptr inbounds nuw { double, double }, ptr [[A]], i32 0, i32 0
|
|
// CHECK-NEXT: [[A_REAL11:%.*]] = load double, ptr [[A_REALP10]], align 8
|
|
// CHECK-NEXT: [[A_IMAGP12:%.*]] = getelementptr inbounds nuw { double, double }, ptr [[A]], i32 0, i32 1
|
|
// CHECK-NEXT: [[A_IMAG13:%.*]] = load double, ptr [[A_IMAGP12]], align 8
|
|
// CHECK-NEXT: [[MUL_AC14:%.*]] = fmul double [[B_REAL7]], [[A_REAL11]]
|
|
// CHECK-NEXT: [[MUL_BD15:%.*]] = fmul double [[B_IMAG9]], [[A_IMAG13]]
|
|
// CHECK-NEXT: [[MUL_AD16:%.*]] = fmul double [[B_REAL7]], [[A_IMAG13]]
|
|
// CHECK-NEXT: [[MUL_BC17:%.*]] = fmul double [[B_IMAG9]], [[A_REAL11]]
|
|
// CHECK-NEXT: [[MUL_R18:%.*]] = fsub double [[MUL_AC14]], [[MUL_BD15]]
|
|
// CHECK-NEXT: [[MUL_I19:%.*]] = fadd double [[MUL_AD16]], [[MUL_BC17]]
|
|
// CHECK-NEXT: [[ISNAN_CMP20:%.*]] = fcmp uno double [[MUL_R18]], [[MUL_R18]]
|
|
// CHECK-NEXT: br i1 [[ISNAN_CMP20]], label %[[COMPLEX_MUL_IMAG_NAN21:.*]], label %[[COMPLEX_MUL_CONT25:.*]], !prof [[PROF2]]
|
|
// CHECK: [[COMPLEX_MUL_IMAG_NAN21]]:
|
|
// CHECK-NEXT: [[ISNAN_CMP22:%.*]] = fcmp uno double [[MUL_I19]], [[MUL_I19]]
|
|
// CHECK-NEXT: br i1 [[ISNAN_CMP22]], label %[[COMPLEX_MUL_LIBCALL23:.*]], label %[[COMPLEX_MUL_CONT25]], !prof [[PROF2]]
|
|
// CHECK: [[COMPLEX_MUL_LIBCALL23]]:
|
|
// CHECK-NEXT: [[CALL24:%.*]] = call { double, double } @__muldc3(double noundef [[B_REAL7]], double noundef [[B_IMAG9]], double noundef [[A_REAL11]], double noundef [[A_IMAG13]]) #[[ATTR4]]
|
|
// CHECK-NEXT: [[TMP2:%.*]] = extractvalue { double, double } [[CALL24]], 0
|
|
// CHECK-NEXT: [[TMP3:%.*]] = extractvalue { double, double } [[CALL24]], 1
|
|
// CHECK-NEXT: br label %[[COMPLEX_MUL_CONT25]]
|
|
// CHECK: [[COMPLEX_MUL_CONT25]]:
|
|
// CHECK-NEXT: [[REAL_MUL_PHI26:%.*]] = phi double [ [[MUL_R18]], %[[COMPLEX_MUL_CONT]] ], [ [[MUL_R18]], %[[COMPLEX_MUL_IMAG_NAN21]] ], [ [[TMP2]], %[[COMPLEX_MUL_LIBCALL23]] ]
|
|
// CHECK-NEXT: [[IMAG_MUL_PHI27:%.*]] = phi double [ [[MUL_I19]], %[[COMPLEX_MUL_CONT]] ], [ [[MUL_I19]], %[[COMPLEX_MUL_IMAG_NAN21]] ], [ [[TMP3]], %[[COMPLEX_MUL_LIBCALL23]] ]
|
|
// CHECK-NEXT: [[CMP_R:%.*]] = fcmp une double [[REAL_MUL_PHI]], [[REAL_MUL_PHI26]]
|
|
// CHECK-NEXT: [[CMP_I:%.*]] = fcmp une double [[IMAG_MUL_PHI]], [[IMAG_MUL_PHI27]]
|
|
// CHECK-NEXT: [[OR_RI:%.*]] = or i1 [[CMP_R]], [[CMP_I]]
|
|
// CHECK-NEXT: [[CONV:%.*]] = zext i1 [[OR_RI]] to i32
|
|
// CHECK-NEXT: ret i32 [[CONV]]
|
|
//
|
|
int main(void)
|
|
{
|
|
double _Complex a = 5;
|
|
double _Complex b = 42;
|
|
|
|
return a * b != b * a;
|
|
}
|
|
|
|
_Complex double bar(int);
|
|
void test(_Complex double*);
|
|
void takecomplex(_Complex double);
|
|
|
|
// CHECK-LABEL: define dso_local void @test2(
|
|
// CHECK-SAME: i32 noundef [[C:%.*]]) #[[ATTR0]] {
|
|
// CHECK-NEXT: [[ENTRY:.*:]]
|
|
// CHECK-NEXT: [[C_ADDR:%.*]] = alloca i32, align 4
|
|
// CHECK-NEXT: [[X:%.*]] = alloca { double, double }, align 8
|
|
// CHECK-NEXT: [[COERCE:%.*]] = alloca { double, double }, align 8
|
|
// CHECK-NEXT: store i32 [[C]], ptr [[C_ADDR]], align 4
|
|
// CHECK-NEXT: [[CALL:%.*]] = call { double, double } @bar(i32 noundef 1)
|
|
// CHECK-NEXT: [[TMP0:%.*]] = extractvalue { double, double } [[CALL]], 0
|
|
// CHECK-NEXT: [[TMP1:%.*]] = extractvalue { double, double } [[CALL]], 1
|
|
// CHECK-NEXT: [[X_REALP:%.*]] = getelementptr inbounds nuw { double, double }, ptr [[X]], i32 0, i32 0
|
|
// CHECK-NEXT: [[X_IMAGP:%.*]] = getelementptr inbounds nuw { double, double }, ptr [[X]], i32 0, i32 1
|
|
// CHECK-NEXT: store double [[TMP0]], ptr [[X_REALP]], align 8
|
|
// CHECK-NEXT: store double [[TMP1]], ptr [[X_IMAGP]], align 8
|
|
// CHECK-NEXT: call void @test(ptr noundef [[X]])
|
|
// CHECK-NEXT: [[X_REALP1:%.*]] = getelementptr inbounds nuw { double, double }, ptr [[X]], i32 0, i32 0
|
|
// CHECK-NEXT: [[X_REAL:%.*]] = load double, ptr [[X_REALP1]], align 8
|
|
// CHECK-NEXT: [[X_IMAGP2:%.*]] = getelementptr inbounds nuw { double, double }, ptr [[X]], i32 0, i32 1
|
|
// CHECK-NEXT: [[X_IMAG:%.*]] = load double, ptr [[X_IMAGP2]], align 8
|
|
// CHECK-NEXT: [[COERCE_REALP:%.*]] = getelementptr inbounds nuw { double, double }, ptr [[COERCE]], i32 0, i32 0
|
|
// CHECK-NEXT: [[COERCE_IMAGP:%.*]] = getelementptr inbounds nuw { double, double }, ptr [[COERCE]], i32 0, i32 1
|
|
// CHECK-NEXT: store double [[X_REAL]], ptr [[COERCE_REALP]], align 8
|
|
// CHECK-NEXT: store double [[X_IMAG]], ptr [[COERCE_IMAGP]], align 8
|
|
// CHECK-NEXT: [[TMP2:%.*]] = getelementptr inbounds nuw { double, double }, ptr [[COERCE]], i32 0, i32 0
|
|
// CHECK-NEXT: [[TMP3:%.*]] = load double, ptr [[TMP2]], align 8
|
|
// CHECK-NEXT: [[TMP4:%.*]] = getelementptr inbounds nuw { double, double }, ptr [[COERCE]], i32 0, i32 1
|
|
// CHECK-NEXT: [[TMP5:%.*]] = load double, ptr [[TMP4]], align 8
|
|
// CHECK-NEXT: call void @takecomplex(double noundef [[TMP3]], double noundef [[TMP5]])
|
|
// CHECK-NEXT: ret void
|
|
//
|
|
void test2(int c) {
|
|
_Complex double X;
|
|
X = bar(1);
|
|
test(&X);
|
|
takecomplex(X);
|
|
}
|
|
|
|
_Complex double g1, g2;
|
|
_Complex float cf;
|
|
double D;
|
|
|
|
// CHECK-LABEL: define dso_local void @test3(
|
|
// CHECK-SAME: ) #[[ATTR0]] {
|
|
// CHECK-NEXT: [[ENTRY:.*]]:
|
|
// CHECK-NEXT: [[GR:%.*]] = alloca double, align 8
|
|
// CHECK-NEXT: [[G1_REAL:%.*]] = load double, ptr @g1, align 8
|
|
// CHECK-NEXT: [[G1_IMAG:%.*]] = load double, ptr getelementptr inbounds nuw (i8, ptr @g1, i64 8), align 8
|
|
// CHECK-NEXT: [[G2_REAL:%.*]] = load double, ptr @g2, align 8
|
|
// CHECK-NEXT: [[G2_IMAG:%.*]] = load double, ptr getelementptr inbounds nuw (i8, ptr @g2, i64 8), align 8
|
|
// CHECK-NEXT: [[ADD_R:%.*]] = fadd double [[G1_REAL]], [[G2_REAL]]
|
|
// CHECK-NEXT: [[ADD_I:%.*]] = fadd double [[G1_IMAG]], [[G2_IMAG]]
|
|
// CHECK-NEXT: store double [[ADD_R]], ptr @g1, align 8
|
|
// CHECK-NEXT: store double [[ADD_I]], ptr getelementptr inbounds nuw (i8, ptr @g1, i64 8), align 8
|
|
// CHECK-NEXT: [[G1_REAL1:%.*]] = load double, ptr @g1, align 8
|
|
// CHECK-NEXT: [[G1_IMAG2:%.*]] = load double, ptr getelementptr inbounds nuw (i8, ptr @g1, i64 8), align 8
|
|
// CHECK-NEXT: [[G2_REAL3:%.*]] = load double, ptr @g2, align 8
|
|
// CHECK-NEXT: [[G2_IMAG4:%.*]] = load double, ptr getelementptr inbounds nuw (i8, ptr @g2, i64 8), align 8
|
|
// CHECK-NEXT: [[SUB_R:%.*]] = fsub double [[G1_REAL1]], [[G2_REAL3]]
|
|
// CHECK-NEXT: [[SUB_I:%.*]] = fsub double [[G1_IMAG2]], [[G2_IMAG4]]
|
|
// CHECK-NEXT: store double [[SUB_R]], ptr @g1, align 8
|
|
// CHECK-NEXT: store double [[SUB_I]], ptr getelementptr inbounds nuw (i8, ptr @g1, i64 8), align 8
|
|
// CHECK-NEXT: [[G1_REAL5:%.*]] = load double, ptr @g1, align 8
|
|
// CHECK-NEXT: [[G1_IMAG6:%.*]] = load double, ptr getelementptr inbounds nuw (i8, ptr @g1, i64 8), align 8
|
|
// CHECK-NEXT: [[G2_REAL7:%.*]] = load double, ptr @g2, align 8
|
|
// CHECK-NEXT: [[G2_IMAG8:%.*]] = load double, ptr getelementptr inbounds nuw (i8, ptr @g2, i64 8), align 8
|
|
// CHECK-NEXT: [[MUL_AC:%.*]] = fmul double [[G1_REAL5]], [[G2_REAL7]]
|
|
// CHECK-NEXT: [[MUL_BD:%.*]] = fmul double [[G1_IMAG6]], [[G2_IMAG8]]
|
|
// CHECK-NEXT: [[MUL_AD:%.*]] = fmul double [[G1_REAL5]], [[G2_IMAG8]]
|
|
// CHECK-NEXT: [[MUL_BC:%.*]] = fmul double [[G1_IMAG6]], [[G2_REAL7]]
|
|
// CHECK-NEXT: [[MUL_R:%.*]] = fsub double [[MUL_AC]], [[MUL_BD]]
|
|
// CHECK-NEXT: [[MUL_I:%.*]] = fadd double [[MUL_AD]], [[MUL_BC]]
|
|
// CHECK-NEXT: [[ISNAN_CMP:%.*]] = fcmp uno double [[MUL_R]], [[MUL_R]]
|
|
// CHECK-NEXT: br i1 [[ISNAN_CMP]], label %[[COMPLEX_MUL_IMAG_NAN:.*]], label %[[COMPLEX_MUL_CONT:.*]], !prof [[PROF2]]
|
|
// CHECK: [[COMPLEX_MUL_IMAG_NAN]]:
|
|
// CHECK-NEXT: [[ISNAN_CMP9:%.*]] = fcmp uno double [[MUL_I]], [[MUL_I]]
|
|
// CHECK-NEXT: br i1 [[ISNAN_CMP9]], label %[[COMPLEX_MUL_LIBCALL:.*]], label %[[COMPLEX_MUL_CONT]], !prof [[PROF2]]
|
|
// CHECK: [[COMPLEX_MUL_LIBCALL]]:
|
|
// CHECK-NEXT: [[CALL:%.*]] = call { double, double } @__muldc3(double noundef [[G1_REAL5]], double noundef [[G1_IMAG6]], double noundef [[G2_REAL7]], double noundef [[G2_IMAG8]]) #[[ATTR4]]
|
|
// CHECK-NEXT: [[TMP0:%.*]] = extractvalue { double, double } [[CALL]], 0
|
|
// CHECK-NEXT: [[TMP1:%.*]] = extractvalue { double, double } [[CALL]], 1
|
|
// CHECK-NEXT: br label %[[COMPLEX_MUL_CONT]]
|
|
// CHECK: [[COMPLEX_MUL_CONT]]:
|
|
// CHECK-NEXT: [[REAL_MUL_PHI:%.*]] = phi double [ [[MUL_R]], %[[ENTRY]] ], [ [[MUL_R]], %[[COMPLEX_MUL_IMAG_NAN]] ], [ [[TMP0]], %[[COMPLEX_MUL_LIBCALL]] ]
|
|
// CHECK-NEXT: [[IMAG_MUL_PHI:%.*]] = phi double [ [[MUL_I]], %[[ENTRY]] ], [ [[MUL_I]], %[[COMPLEX_MUL_IMAG_NAN]] ], [ [[TMP1]], %[[COMPLEX_MUL_LIBCALL]] ]
|
|
// CHECK-NEXT: store double [[REAL_MUL_PHI]], ptr @g1, align 8
|
|
// CHECK-NEXT: store double [[IMAG_MUL_PHI]], ptr getelementptr inbounds nuw (i8, ptr @g1, i64 8), align 8
|
|
// CHECK-NEXT: [[G1_REAL10:%.*]] = load double, ptr @g1, align 8
|
|
// CHECK-NEXT: [[G1_IMAG11:%.*]] = load double, ptr getelementptr inbounds nuw (i8, ptr @g1, i64 8), align 8
|
|
// CHECK-NEXT: [[CONJ_I:%.*]] = fneg double [[G1_IMAG11]]
|
|
// CHECK-NEXT: [[NEG_R:%.*]] = fneg double [[G1_REAL10]]
|
|
// CHECK-NEXT: [[NEG_I:%.*]] = fneg double [[CONJ_I]]
|
|
// CHECK-NEXT: store double [[NEG_R]], ptr @g1, align 8
|
|
// CHECK-NEXT: store double [[NEG_I]], ptr getelementptr inbounds nuw (i8, ptr @g1, i64 8), align 8
|
|
// CHECK-NEXT: [[TMP2:%.*]] = load double, ptr @g1, align 8
|
|
// CHECK-NEXT: store double [[TMP2]], ptr [[GR]], align 8
|
|
// CHECK-NEXT: [[TMP3:%.*]] = load double, ptr @D, align 8
|
|
// CHECK-NEXT: [[CF_REAL:%.*]] = load float, ptr @cf, align 4
|
|
// CHECK-NEXT: [[CF_IMAG:%.*]] = load float, ptr getelementptr inbounds nuw (i8, ptr @cf, i64 4), align 4
|
|
// CHECK-NEXT: [[CONV:%.*]] = fpext float [[CF_REAL]] to double
|
|
// CHECK-NEXT: [[CONV12:%.*]] = fpext float [[CF_IMAG]] to double
|
|
// CHECK-NEXT: [[ADD_R13:%.*]] = fadd double [[CONV]], [[TMP3]]
|
|
// CHECK-NEXT: [[CONV14:%.*]] = fptrunc double [[ADD_R13]] to float
|
|
// CHECK-NEXT: [[CONV15:%.*]] = fptrunc double [[CONV12]] to float
|
|
// CHECK-NEXT: store float [[CONV14]], ptr @cf, align 4
|
|
// CHECK-NEXT: store float [[CONV15]], ptr getelementptr inbounds nuw (i8, ptr @cf, i64 4), align 4
|
|
// CHECK-NEXT: [[CF_REAL16:%.*]] = load float, ptr @cf, align 4
|
|
// CHECK-NEXT: [[CF_IMAG17:%.*]] = load float, ptr getelementptr inbounds nuw (i8, ptr @cf, i64 4), align 4
|
|
// CHECK-NEXT: [[CONV18:%.*]] = fpext float [[CF_REAL16]] to double
|
|
// CHECK-NEXT: [[CONV19:%.*]] = fpext float [[CF_IMAG17]] to double
|
|
// CHECK-NEXT: [[TMP4:%.*]] = load double, ptr @D, align 8
|
|
// CHECK-NEXT: [[ADD_R20:%.*]] = fadd double [[TMP4]], [[CONV18]]
|
|
// CHECK-NEXT: store double [[ADD_R20]], ptr @D, align 8
|
|
// CHECK-NEXT: [[G1_REAL21:%.*]] = load double, ptr @g1, align 8
|
|
// CHECK-NEXT: [[G1_IMAG22:%.*]] = load double, ptr getelementptr inbounds nuw (i8, ptr @g1, i64 8), align 8
|
|
// CHECK-NEXT: [[CF_REAL23:%.*]] = load float, ptr @cf, align 4
|
|
// CHECK-NEXT: [[CF_IMAG24:%.*]] = load float, ptr getelementptr inbounds nuw (i8, ptr @cf, i64 4), align 4
|
|
// CHECK-NEXT: [[CONV25:%.*]] = fpext float [[CF_REAL23]] to double
|
|
// CHECK-NEXT: [[CONV26:%.*]] = fpext float [[CF_IMAG24]] to double
|
|
// CHECK-NEXT: [[CALL27:%.*]] = call { double, double } @__divdc3(double noundef [[CONV25]], double noundef [[CONV26]], double noundef [[G1_REAL21]], double noundef [[G1_IMAG22]]) #[[ATTR4]]
|
|
// CHECK-NEXT: [[TMP5:%.*]] = extractvalue { double, double } [[CALL27]], 0
|
|
// CHECK-NEXT: [[TMP6:%.*]] = extractvalue { double, double } [[CALL27]], 1
|
|
// CHECK-NEXT: [[CONV28:%.*]] = fptrunc double [[TMP5]] to float
|
|
// CHECK-NEXT: [[CONV29:%.*]] = fptrunc double [[TMP6]] to float
|
|
// CHECK-NEXT: store float [[CONV28]], ptr @cf, align 4
|
|
// CHECK-NEXT: store float [[CONV29]], ptr getelementptr inbounds nuw (i8, ptr @cf, i64 4), align 4
|
|
// CHECK-NEXT: [[G1_REAL30:%.*]] = load double, ptr @g1, align 8
|
|
// CHECK-NEXT: [[G1_IMAG31:%.*]] = load double, ptr getelementptr inbounds nuw (i8, ptr @g1, i64 8), align 8
|
|
// CHECK-NEXT: [[TMP7:%.*]] = load double, ptr @D, align 8
|
|
// CHECK-NEXT: [[ADD_R32:%.*]] = fadd double [[G1_REAL30]], [[TMP7]]
|
|
// CHECK-NEXT: store double [[ADD_R32]], ptr @g1, align 8
|
|
// CHECK-NEXT: store double [[G1_IMAG31]], ptr getelementptr inbounds nuw (i8, ptr @g1, i64 8), align 8
|
|
// CHECK-NEXT: [[TMP8:%.*]] = load double, ptr @D, align 8
|
|
// CHECK-NEXT: [[G1_REAL33:%.*]] = load double, ptr @g1, align 8
|
|
// CHECK-NEXT: [[G1_IMAG34:%.*]] = load double, ptr getelementptr inbounds nuw (i8, ptr @g1, i64 8), align 8
|
|
// CHECK-NEXT: [[ADD_R35:%.*]] = fadd double [[TMP8]], [[G1_REAL33]]
|
|
// CHECK-NEXT: store double [[ADD_R35]], ptr @g1, align 8
|
|
// CHECK-NEXT: store double [[G1_IMAG34]], ptr getelementptr inbounds nuw (i8, ptr @g1, i64 8), align 8
|
|
// CHECK-NEXT: ret void
|
|
//
|
|
void test3(void) {
|
|
g1 = g1 + g2;
|
|
g1 = g1 - g2;
|
|
g1 = g1 * g2;
|
|
g1 = +-~g1;
|
|
|
|
double Gr = __real g1;
|
|
|
|
cf += D;
|
|
D += cf;
|
|
cf /= g1;
|
|
g1 = g1 + D;
|
|
g1 = D + g1;
|
|
}
|
|
|
|
__complex__ int ci1, ci2;
|
|
__complex__ short cs;
|
|
int i;
|
|
// CHECK-LABEL: define dso_local void @test3int(
|
|
// CHECK-SAME: ) #[[ATTR0]] {
|
|
// CHECK-NEXT: [[ENTRY:.*:]]
|
|
// CHECK-NEXT: [[CI1_REAL:%.*]] = load i32, ptr @ci1, align 4
|
|
// CHECK-NEXT: [[CI1_IMAG:%.*]] = load i32, ptr getelementptr inbounds nuw (i8, ptr @ci1, i64 4), align 4
|
|
// CHECK-NEXT: [[CI2_REAL:%.*]] = load i32, ptr @ci2, align 4
|
|
// CHECK-NEXT: [[CI2_IMAG:%.*]] = load i32, ptr getelementptr inbounds nuw (i8, ptr @ci2, i64 4), align 4
|
|
// CHECK-NEXT: [[ADD_R:%.*]] = add i32 [[CI1_REAL]], [[CI2_REAL]]
|
|
// CHECK-NEXT: [[ADD_I:%.*]] = add i32 [[CI1_IMAG]], [[CI2_IMAG]]
|
|
// CHECK-NEXT: store i32 [[ADD_R]], ptr @ci1, align 4
|
|
// CHECK-NEXT: store i32 [[ADD_I]], ptr getelementptr inbounds nuw (i8, ptr @ci1, i64 4), align 4
|
|
// CHECK-NEXT: [[CI1_REAL1:%.*]] = load i32, ptr @ci1, align 4
|
|
// CHECK-NEXT: [[CI1_IMAG2:%.*]] = load i32, ptr getelementptr inbounds nuw (i8, ptr @ci1, i64 4), align 4
|
|
// CHECK-NEXT: [[CI2_REAL3:%.*]] = load i32, ptr @ci2, align 4
|
|
// CHECK-NEXT: [[CI2_IMAG4:%.*]] = load i32, ptr getelementptr inbounds nuw (i8, ptr @ci2, i64 4), align 4
|
|
// CHECK-NEXT: [[SUB_R:%.*]] = sub i32 [[CI1_REAL1]], [[CI2_REAL3]]
|
|
// CHECK-NEXT: [[SUB_I:%.*]] = sub i32 [[CI1_IMAG2]], [[CI2_IMAG4]]
|
|
// CHECK-NEXT: store i32 [[SUB_R]], ptr @ci1, align 4
|
|
// CHECK-NEXT: store i32 [[SUB_I]], ptr getelementptr inbounds nuw (i8, ptr @ci1, i64 4), align 4
|
|
// CHECK-NEXT: [[CI1_REAL5:%.*]] = load i32, ptr @ci1, align 4
|
|
// CHECK-NEXT: [[CI1_IMAG6:%.*]] = load i32, ptr getelementptr inbounds nuw (i8, ptr @ci1, i64 4), align 4
|
|
// CHECK-NEXT: [[CI2_REAL7:%.*]] = load i32, ptr @ci2, align 4
|
|
// CHECK-NEXT: [[CI2_IMAG8:%.*]] = load i32, ptr getelementptr inbounds nuw (i8, ptr @ci2, i64 4), align 4
|
|
// CHECK-NEXT: [[MUL_RL:%.*]] = mul i32 [[CI1_REAL5]], [[CI2_REAL7]]
|
|
// CHECK-NEXT: [[MUL_RR:%.*]] = mul i32 [[CI1_IMAG6]], [[CI2_IMAG8]]
|
|
// CHECK-NEXT: [[MUL_R:%.*]] = sub i32 [[MUL_RL]], [[MUL_RR]]
|
|
// CHECK-NEXT: [[MUL_IL:%.*]] = mul i32 [[CI1_IMAG6]], [[CI2_REAL7]]
|
|
// CHECK-NEXT: [[MUL_IR:%.*]] = mul i32 [[CI1_REAL5]], [[CI2_IMAG8]]
|
|
// CHECK-NEXT: [[MUL_I:%.*]] = add i32 [[MUL_IL]], [[MUL_IR]]
|
|
// CHECK-NEXT: store i32 [[MUL_R]], ptr @ci1, align 4
|
|
// CHECK-NEXT: store i32 [[MUL_I]], ptr getelementptr inbounds nuw (i8, ptr @ci1, i64 4), align 4
|
|
// CHECK-NEXT: [[CI1_REAL9:%.*]] = load i32, ptr @ci1, align 4
|
|
// CHECK-NEXT: [[CI1_IMAG10:%.*]] = load i32, ptr getelementptr inbounds nuw (i8, ptr @ci1, i64 4), align 4
|
|
// CHECK-NEXT: [[CONJ_I:%.*]] = sub i32 0, [[CI1_IMAG10]]
|
|
// CHECK-NEXT: [[NEG_R:%.*]] = sub i32 0, [[CI1_REAL9]]
|
|
// CHECK-NEXT: [[NEG_I:%.*]] = sub i32 0, [[CONJ_I]]
|
|
// CHECK-NEXT: store i32 [[NEG_R]], ptr @ci1, align 4
|
|
// CHECK-NEXT: store i32 [[NEG_I]], ptr getelementptr inbounds nuw (i8, ptr @ci1, i64 4), align 4
|
|
// CHECK-NEXT: [[TMP0:%.*]] = load i32, ptr @ci1, align 4
|
|
// CHECK-NEXT: store i32 [[TMP0]], ptr @i, align 4
|
|
// CHECK-NEXT: [[TMP1:%.*]] = load i32, ptr @i, align 4
|
|
// CHECK-NEXT: [[CS_REAL:%.*]] = load i16, ptr @cs, align 2
|
|
// CHECK-NEXT: [[CS_IMAG:%.*]] = load i16, ptr getelementptr inbounds nuw (i8, ptr @cs, i64 2), align 2
|
|
// CHECK-NEXT: [[CONV:%.*]] = sext i16 [[CS_REAL]] to i32
|
|
// CHECK-NEXT: [[CONV11:%.*]] = sext i16 [[CS_IMAG]] to i32
|
|
// CHECK-NEXT: [[ADD_R12:%.*]] = add i32 [[CONV]], [[TMP1]]
|
|
// CHECK-NEXT: [[ADD_I13:%.*]] = add i32 [[CONV11]], 0
|
|
// CHECK-NEXT: [[CONV14:%.*]] = trunc i32 [[ADD_R12]] to i16
|
|
// CHECK-NEXT: [[CONV15:%.*]] = trunc i32 [[ADD_I13]] to i16
|
|
// CHECK-NEXT: store i16 [[CONV14]], ptr @cs, align 2
|
|
// CHECK-NEXT: store i16 [[CONV15]], ptr getelementptr inbounds nuw (i8, ptr @cs, i64 2), align 2
|
|
// CHECK-NEXT: [[CF_REAL:%.*]] = load float, ptr @cf, align 4
|
|
// CHECK-NEXT: [[CF_IMAG:%.*]] = load float, ptr getelementptr inbounds nuw (i8, ptr @cf, i64 4), align 4
|
|
// CHECK-NEXT: [[CONV16:%.*]] = fpext float [[CF_REAL]] to double
|
|
// CHECK-NEXT: [[CONV17:%.*]] = fpext float [[CF_IMAG]] to double
|
|
// CHECK-NEXT: [[TMP2:%.*]] = load double, ptr @D, align 8
|
|
// CHECK-NEXT: [[ADD_R18:%.*]] = fadd double [[TMP2]], [[CONV16]]
|
|
// CHECK-NEXT: store double [[ADD_R18]], ptr @D, align 8
|
|
// CHECK-NEXT: [[CI1_REAL19:%.*]] = load i32, ptr @ci1, align 4
|
|
// CHECK-NEXT: [[CI1_IMAG20:%.*]] = load i32, ptr getelementptr inbounds nuw (i8, ptr @ci1, i64 4), align 4
|
|
// CHECK-NEXT: [[CS_REAL21:%.*]] = load i16, ptr @cs, align 2
|
|
// CHECK-NEXT: [[CS_IMAG22:%.*]] = load i16, ptr getelementptr inbounds nuw (i8, ptr @cs, i64 2), align 2
|
|
// CHECK-NEXT: [[CONV23:%.*]] = sext i16 [[CS_REAL21]] to i32
|
|
// CHECK-NEXT: [[CONV24:%.*]] = sext i16 [[CS_IMAG22]] to i32
|
|
// CHECK-NEXT: [[TMP3:%.*]] = mul i32 [[CONV23]], [[CI1_REAL19]]
|
|
// CHECK-NEXT: [[TMP4:%.*]] = mul i32 [[CONV24]], [[CI1_IMAG20]]
|
|
// CHECK-NEXT: [[TMP5:%.*]] = add i32 [[TMP3]], [[TMP4]]
|
|
// CHECK-NEXT: [[TMP6:%.*]] = mul i32 [[CI1_REAL19]], [[CI1_REAL19]]
|
|
// CHECK-NEXT: [[TMP7:%.*]] = mul i32 [[CI1_IMAG20]], [[CI1_IMAG20]]
|
|
// CHECK-NEXT: [[TMP8:%.*]] = add i32 [[TMP6]], [[TMP7]]
|
|
// CHECK-NEXT: [[TMP9:%.*]] = mul i32 [[CONV24]], [[CI1_REAL19]]
|
|
// CHECK-NEXT: [[TMP10:%.*]] = mul i32 [[CONV23]], [[CI1_IMAG20]]
|
|
// CHECK-NEXT: [[TMP11:%.*]] = sub i32 [[TMP9]], [[TMP10]]
|
|
// CHECK-NEXT: [[TMP12:%.*]] = sdiv i32 [[TMP5]], [[TMP8]]
|
|
// CHECK-NEXT: [[TMP13:%.*]] = sdiv i32 [[TMP11]], [[TMP8]]
|
|
// CHECK-NEXT: [[CONV25:%.*]] = trunc i32 [[TMP12]] to i16
|
|
// CHECK-NEXT: [[CONV26:%.*]] = trunc i32 [[TMP13]] to i16
|
|
// CHECK-NEXT: store i16 [[CONV25]], ptr @cs, align 2
|
|
// CHECK-NEXT: store i16 [[CONV26]], ptr getelementptr inbounds nuw (i8, ptr @cs, i64 2), align 2
|
|
// CHECK-NEXT: [[CI1_REAL27:%.*]] = load i32, ptr @ci1, align 4
|
|
// CHECK-NEXT: [[CI1_IMAG28:%.*]] = load i32, ptr getelementptr inbounds nuw (i8, ptr @ci1, i64 4), align 4
|
|
// CHECK-NEXT: [[TMP14:%.*]] = load i32, ptr @i, align 4
|
|
// CHECK-NEXT: [[ADD_R29:%.*]] = add i32 [[CI1_REAL27]], [[TMP14]]
|
|
// CHECK-NEXT: [[ADD_I30:%.*]] = add i32 [[CI1_IMAG28]], 0
|
|
// CHECK-NEXT: store i32 [[ADD_R29]], ptr @ci1, align 4
|
|
// CHECK-NEXT: store i32 [[ADD_I30]], ptr getelementptr inbounds nuw (i8, ptr @ci1, i64 4), align 4
|
|
// CHECK-NEXT: [[TMP15:%.*]] = load i32, ptr @i, align 4
|
|
// CHECK-NEXT: [[CI1_REAL31:%.*]] = load i32, ptr @ci1, align 4
|
|
// CHECK-NEXT: [[CI1_IMAG32:%.*]] = load i32, ptr getelementptr inbounds nuw (i8, ptr @ci1, i64 4), align 4
|
|
// CHECK-NEXT: [[ADD_R33:%.*]] = add i32 [[TMP15]], [[CI1_REAL31]]
|
|
// CHECK-NEXT: [[ADD_I34:%.*]] = add i32 0, [[CI1_IMAG32]]
|
|
// CHECK-NEXT: store i32 [[ADD_R33]], ptr @ci1, align 4
|
|
// CHECK-NEXT: store i32 [[ADD_I34]], ptr getelementptr inbounds nuw (i8, ptr @ci1, i64 4), align 4
|
|
// CHECK-NEXT: ret void
|
|
//
|
|
void test3int(void) {
|
|
ci1 = ci1 + ci2;
|
|
ci1 = ci1 - ci2;
|
|
ci1 = ci1 * ci2;
|
|
ci1 = +-~ci1;
|
|
|
|
i = __real ci1;
|
|
|
|
cs += i;
|
|
D += cf;
|
|
cs /= ci1;
|
|
ci1 = ci1 + i;
|
|
ci1 = i + ci1;
|
|
}
|
|
|
|
// CHECK-LABEL: define dso_local void @t1(
|
|
// CHECK-SAME: ) #[[ATTR0]] {
|
|
// CHECK-NEXT: [[ENTRY:.*:]]
|
|
// CHECK-NEXT: store float 4.000000e+00, ptr @cf, align 4
|
|
// CHECK-NEXT: ret void
|
|
//
|
|
void t1(void) {
|
|
(__real__ cf) = 4.0;
|
|
}
|
|
|
|
// CHECK-LABEL: define dso_local void @t2(
|
|
// CHECK-SAME: ) #[[ATTR0]] {
|
|
// CHECK-NEXT: [[ENTRY:.*:]]
|
|
// CHECK-NEXT: store float 4.000000e+00, ptr getelementptr inbounds nuw (i8, ptr @cf, i64 4), align 4
|
|
// CHECK-NEXT: ret void
|
|
//
|
|
void t2(void) {
|
|
(__imag__ cf) = 4.0;
|
|
}
|
|
|
|
// PR1960
|
|
// CHECK-LABEL: define dso_local void @t3(
|
|
// CHECK-SAME: ) #[[ATTR0]] {
|
|
// CHECK-NEXT: [[ENTRY:.*:]]
|
|
// CHECK-NEXT: [[V:%.*]] = alloca { i64, i64 }, align 8
|
|
// CHECK-NEXT: [[V_REALP:%.*]] = getelementptr inbounds nuw { i64, i64 }, ptr [[V]], i32 0, i32 0
|
|
// CHECK-NEXT: [[V_IMAGP:%.*]] = getelementptr inbounds nuw { i64, i64 }, ptr [[V]], i32 0, i32 1
|
|
// CHECK-NEXT: store i64 2, ptr [[V_REALP]], align 8
|
|
// CHECK-NEXT: store i64 0, ptr [[V_IMAGP]], align 8
|
|
// CHECK-NEXT: ret void
|
|
//
|
|
void t3(void) {
|
|
__complex__ long long v = 2;
|
|
}
|
|
|
|
// PR3131
|
|
float _Complex t4(void);
|
|
|
|
// CHECK-LABEL: define dso_local void @t5(
|
|
// CHECK-SAME: ) #[[ATTR2:[0-9]+]] {
|
|
// CHECK-NEXT: [[ENTRY:.*:]]
|
|
// CHECK-NEXT: [[X:%.*]] = alloca { float, float }, align 4
|
|
// CHECK-NEXT: [[COERCE:%.*]] = alloca { float, float }, align 4
|
|
// CHECK-NEXT: [[CALL:%.*]] = call <2 x float> @t4()
|
|
// CHECK-NEXT: store <2 x float> [[CALL]], ptr [[COERCE]], align 4
|
|
// CHECK-NEXT: [[COERCE_REALP:%.*]] = getelementptr inbounds nuw { float, float }, ptr [[COERCE]], i32 0, i32 0
|
|
// CHECK-NEXT: [[COERCE_REAL:%.*]] = load float, ptr [[COERCE_REALP]], align 4
|
|
// CHECK-NEXT: [[COERCE_IMAGP:%.*]] = getelementptr inbounds nuw { float, float }, ptr [[COERCE]], i32 0, i32 1
|
|
// CHECK-NEXT: [[COERCE_IMAG:%.*]] = load float, ptr [[COERCE_IMAGP]], align 4
|
|
// CHECK-NEXT: [[X_REALP:%.*]] = getelementptr inbounds nuw { float, float }, ptr [[X]], i32 0, i32 0
|
|
// CHECK-NEXT: [[X_IMAGP:%.*]] = getelementptr inbounds nuw { float, float }, ptr [[X]], i32 0, i32 1
|
|
// CHECK-NEXT: store float [[COERCE_REAL]], ptr [[X_REALP]], align 4
|
|
// CHECK-NEXT: store float [[COERCE_IMAG]], ptr [[X_IMAGP]], align 4
|
|
// CHECK-NEXT: ret void
|
|
//
|
|
void t5(void) {
|
|
float _Complex x = t4();
|
|
}
|
|
|
|
// CHECK-LABEL: define dso_local void @t6(
|
|
// CHECK-SAME: ) #[[ATTR0]] {
|
|
// CHECK-NEXT: [[ENTRY:.*:]]
|
|
// CHECK-NEXT: [[G1_REAL:%.*]] = load double, ptr @g1, align 8
|
|
// CHECK-NEXT: [[G1_IMAG:%.*]] = load double, ptr getelementptr inbounds nuw (i8, ptr @g1, i64 8), align 8
|
|
// CHECK-NEXT: [[INC:%.*]] = fadd double [[G1_REAL]], 1.000000e+00
|
|
// CHECK-NEXT: store double [[INC]], ptr @g1, align 8
|
|
// CHECK-NEXT: store double [[G1_IMAG]], ptr getelementptr inbounds nuw (i8, ptr @g1, i64 8), align 8
|
|
// CHECK-NEXT: [[G1_REAL1:%.*]] = load double, ptr @g1, align 8
|
|
// CHECK-NEXT: [[G1_IMAG2:%.*]] = load double, ptr getelementptr inbounds nuw (i8, ptr @g1, i64 8), align 8
|
|
// CHECK-NEXT: [[DEC:%.*]] = fadd double [[G1_REAL1]], -1.000000e+00
|
|
// CHECK-NEXT: store double [[DEC]], ptr @g1, align 8
|
|
// CHECK-NEXT: store double [[G1_IMAG2]], ptr getelementptr inbounds nuw (i8, ptr @g1, i64 8), align 8
|
|
// CHECK-NEXT: [[G1_REAL3:%.*]] = load double, ptr @g1, align 8
|
|
// CHECK-NEXT: [[G1_IMAG4:%.*]] = load double, ptr getelementptr inbounds nuw (i8, ptr @g1, i64 8), align 8
|
|
// CHECK-NEXT: [[INC5:%.*]] = fadd double [[G1_REAL3]], 1.000000e+00
|
|
// CHECK-NEXT: store double [[INC5]], ptr @g1, align 8
|
|
// CHECK-NEXT: store double [[G1_IMAG4]], ptr getelementptr inbounds nuw (i8, ptr @g1, i64 8), align 8
|
|
// CHECK-NEXT: [[G1_REAL6:%.*]] = load double, ptr @g1, align 8
|
|
// CHECK-NEXT: [[G1_IMAG7:%.*]] = load double, ptr getelementptr inbounds nuw (i8, ptr @g1, i64 8), align 8
|
|
// CHECK-NEXT: [[DEC8:%.*]] = fadd double [[G1_REAL6]], -1.000000e+00
|
|
// CHECK-NEXT: store double [[DEC8]], ptr @g1, align 8
|
|
// CHECK-NEXT: store double [[G1_IMAG7]], ptr getelementptr inbounds nuw (i8, ptr @g1, i64 8), align 8
|
|
// CHECK-NEXT: [[CI1_REAL:%.*]] = load i32, ptr @ci1, align 4
|
|
// CHECK-NEXT: [[CI1_IMAG:%.*]] = load i32, ptr getelementptr inbounds nuw (i8, ptr @ci1, i64 4), align 4
|
|
// CHECK-NEXT: [[INC9:%.*]] = add i32 [[CI1_REAL]], 1
|
|
// CHECK-NEXT: store i32 [[INC9]], ptr @ci1, align 4
|
|
// CHECK-NEXT: store i32 [[CI1_IMAG]], ptr getelementptr inbounds nuw (i8, ptr @ci1, i64 4), align 4
|
|
// CHECK-NEXT: [[CI1_REAL10:%.*]] = load i32, ptr @ci1, align 4
|
|
// CHECK-NEXT: [[CI1_IMAG11:%.*]] = load i32, ptr getelementptr inbounds nuw (i8, ptr @ci1, i64 4), align 4
|
|
// CHECK-NEXT: [[DEC12:%.*]] = add i32 [[CI1_REAL10]], -1
|
|
// CHECK-NEXT: store i32 [[DEC12]], ptr @ci1, align 4
|
|
// CHECK-NEXT: store i32 [[CI1_IMAG11]], ptr getelementptr inbounds nuw (i8, ptr @ci1, i64 4), align 4
|
|
// CHECK-NEXT: [[CI1_REAL13:%.*]] = load i32, ptr @ci1, align 4
|
|
// CHECK-NEXT: [[CI1_IMAG14:%.*]] = load i32, ptr getelementptr inbounds nuw (i8, ptr @ci1, i64 4), align 4
|
|
// CHECK-NEXT: [[INC15:%.*]] = add i32 [[CI1_REAL13]], 1
|
|
// CHECK-NEXT: store i32 [[INC15]], ptr @ci1, align 4
|
|
// CHECK-NEXT: store i32 [[CI1_IMAG14]], ptr getelementptr inbounds nuw (i8, ptr @ci1, i64 4), align 4
|
|
// CHECK-NEXT: [[CI1_REAL16:%.*]] = load i32, ptr @ci1, align 4
|
|
// CHECK-NEXT: [[CI1_IMAG17:%.*]] = load i32, ptr getelementptr inbounds nuw (i8, ptr @ci1, i64 4), align 4
|
|
// CHECK-NEXT: [[DEC18:%.*]] = add i32 [[CI1_REAL16]], -1
|
|
// CHECK-NEXT: store i32 [[DEC18]], ptr @ci1, align 4
|
|
// CHECK-NEXT: store i32 [[CI1_IMAG17]], ptr getelementptr inbounds nuw (i8, ptr @ci1, i64 4), align 4
|
|
// CHECK-NEXT: ret void
|
|
//
|
|
void t6(void) {
|
|
g1++;
|
|
g1--;
|
|
++g1;
|
|
--g1;
|
|
ci1++;
|
|
ci1--;
|
|
++ci1;
|
|
--ci1;
|
|
}
|
|
|
|
// CHECK-LABEL: define dso_local double @t7(
|
|
// CHECK-SAME: double noundef [[C_COERCE0:%.*]], double noundef [[C_COERCE1:%.*]]) #[[ATTR0]] {
|
|
// CHECK-NEXT: [[ENTRY:.*:]]
|
|
// CHECK-NEXT: [[C:%.*]] = alloca { double, double }, align 8
|
|
// CHECK-NEXT: [[TMP0:%.*]] = getelementptr inbounds nuw { double, double }, ptr [[C]], i32 0, i32 0
|
|
// CHECK-NEXT: store double [[C_COERCE0]], ptr [[TMP0]], align 8
|
|
// CHECK-NEXT: [[TMP1:%.*]] = getelementptr inbounds nuw { double, double }, ptr [[C]], i32 0, i32 1
|
|
// CHECK-NEXT: store double [[C_COERCE1]], ptr [[TMP1]], align 8
|
|
// CHECK-NEXT: [[C_REALP:%.*]] = getelementptr inbounds nuw { double, double }, ptr [[C]], i32 0, i32 0
|
|
// CHECK-NEXT: [[TMP2:%.*]] = load double, ptr [[C_REALP]], align 8
|
|
// CHECK-NEXT: [[TMP3:%.*]] = call double @llvm.fabs.f64(double [[TMP2]])
|
|
// CHECK-NEXT: ret double [[TMP3]]
|
|
//
|
|
double t7(double _Complex c) {
|
|
return __builtin_fabs(__real__(c));
|
|
}
|
|
|
|
// CHECK-LABEL: define dso_local void @t8(
|
|
// CHECK-SAME: ) #[[ATTR0]] {
|
|
// CHECK-NEXT: [[ENTRY:.*:]]
|
|
// CHECK-NEXT: [[X:%.*]] = alloca ptr, align 8
|
|
// CHECK-NEXT: [[DOTCOMPOUNDLITERAL:%.*]] = alloca { i32, i32 }, align 4
|
|
// CHECK-NEXT: [[DOTCOMPOUNDLITERAL_REALP:%.*]] = getelementptr inbounds nuw { i32, i32 }, ptr [[DOTCOMPOUNDLITERAL]], i32 0, i32 0
|
|
// CHECK-NEXT: [[DOTCOMPOUNDLITERAL_IMAGP:%.*]] = getelementptr inbounds nuw { i32, i32 }, ptr [[DOTCOMPOUNDLITERAL]], i32 0, i32 1
|
|
// CHECK-NEXT: store i32 1, ptr [[DOTCOMPOUNDLITERAL_REALP]], align 4
|
|
// CHECK-NEXT: store i32 0, ptr [[DOTCOMPOUNDLITERAL_IMAGP]], align 4
|
|
// CHECK-NEXT: store ptr [[DOTCOMPOUNDLITERAL]], ptr [[X]], align 8
|
|
// CHECK-NEXT: ret void
|
|
//
|
|
void t8(void) {
|
|
__complex__ int *x = &(__complex__ int){1};
|
|
}
|
|
|
|
const _Complex double test9const = 0;
|
|
// CHECK-LABEL: define dso_local { double, double } @test9func(
|
|
// CHECK-SAME: ) #[[ATTR0]] {
|
|
// CHECK-NEXT: [[ENTRY:.*:]]
|
|
// CHECK-NEXT: [[RETVAL:%.*]] = alloca { double, double }, align 8
|
|
// CHECK-NEXT: [[RETVAL_REALP:%.*]] = getelementptr inbounds nuw { double, double }, ptr [[RETVAL]], i32 0, i32 0
|
|
// CHECK-NEXT: [[RETVAL_IMAGP:%.*]] = getelementptr inbounds nuw { double, double }, ptr [[RETVAL]], i32 0, i32 1
|
|
// CHECK-NEXT: store double 0.000000e+00, ptr [[RETVAL_REALP]], align 8
|
|
// CHECK-NEXT: store double 0.000000e+00, ptr [[RETVAL_IMAGP]], align 8
|
|
// CHECK-NEXT: [[TMP0:%.*]] = load { double, double }, ptr [[RETVAL]], align 8
|
|
// CHECK-NEXT: ret { double, double } [[TMP0]]
|
|
//
|
|
_Complex double test9func(void) { return test9const; }
|
|
|
|
// D6217
|
|
// CHECK-LABEL: define dso_local void @t91(
|
|
// CHECK-SAME: ) #[[ATTR0]] {
|
|
// CHECK-NEXT: [[ENTRY:.*:]]
|
|
// CHECK-NEXT: [[C:%.*]] = alloca [0 x i8], align 1
|
|
// CHECK-NEXT: br i1 false, label %[[COND_TRUE:.*]], label %[[COND_FALSE:.*]]
|
|
// CHECK: [[COND_TRUE]]:
|
|
// CHECK-NEXT: br label %[[COND_END:.*]]
|
|
// CHECK: [[COND_FALSE]]:
|
|
// CHECK-NEXT: br label %[[COND_END]]
|
|
// CHECK: [[COND_END]]:
|
|
// CHECK-NEXT: [[COND_R:%.*]] = phi double [ 2.000000e+00, %[[COND_TRUE]] ], [ 2.000000e+00, %[[COND_FALSE]] ]
|
|
// CHECK-NEXT: [[COND_I:%.*]] = phi double [ 0.000000e+00, %[[COND_TRUE]] ], [ 0.000000e+00, %[[COND_FALSE]] ]
|
|
// CHECK-NEXT: ret void
|
|
//
|
|
void t91(void) {
|
|
// Check for proper type promotion of conditional expression
|
|
char c[(int)(sizeof(typeof((0 ? 2.0f : (_Complex double) 2.0f))) - sizeof(_Complex double))];
|
|
// Check for proper codegen
|
|
(0 ? 2.0f : (_Complex double) 2.0f);
|
|
}
|
|
|
|
// CHECK-LABEL: define dso_local void @t92(
|
|
// CHECK-SAME: ) #[[ATTR0]] {
|
|
// CHECK-NEXT: [[ENTRY:.*:]]
|
|
// CHECK-NEXT: [[C:%.*]] = alloca [0 x i8], align 1
|
|
// CHECK-NEXT: br i1 false, label %[[COND_TRUE:.*]], label %[[COND_FALSE:.*]]
|
|
// CHECK: [[COND_TRUE]]:
|
|
// CHECK-NEXT: br label %[[COND_END:.*]]
|
|
// CHECK: [[COND_FALSE]]:
|
|
// CHECK-NEXT: br label %[[COND_END]]
|
|
// CHECK: [[COND_END]]:
|
|
// CHECK-NEXT: [[COND_R:%.*]] = phi double [ 2.000000e+00, %[[COND_TRUE]] ], [ 2.000000e+00, %[[COND_FALSE]] ]
|
|
// CHECK-NEXT: [[COND_I:%.*]] = phi double [ 0.000000e+00, %[[COND_TRUE]] ], [ 0.000000e+00, %[[COND_FALSE]] ]
|
|
// CHECK-NEXT: ret void
|
|
//
|
|
void t92(void) {
|
|
// Check for proper type promotion of conditional expression
|
|
char c[(int)(sizeof(typeof((0 ? (_Complex double) 2.0f : 2.0f))) - sizeof(_Complex double))];
|
|
// Check for proper codegen
|
|
(0 ? (_Complex double) 2.0f : 2.0f);
|
|
}
|
|
|
|
// CHECK-LABEL: define dso_local void @real_on_scalar_with_type_promotion(
|
|
// CHECK-SAME: ) #[[ATTR0]] {
|
|
// CHECK-NEXT: [[ENTRY:.*:]]
|
|
// CHECK-NEXT: [[A:%.*]] = alloca { half, half }, align 2
|
|
// CHECK-NEXT: [[B:%.*]] = alloca half, align 2
|
|
// CHECK-NEXT: [[A_REALP:%.*]] = getelementptr inbounds nuw { 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: store half [[UNPROMOTION]], ptr [[B]], align 2
|
|
// CHECK-NEXT: ret void
|
|
//
|
|
void real_on_scalar_with_type_promotion() {
|
|
_Float16 _Complex a;
|
|
_Float16 b = __real__(__real__ a);
|
|
}
|
|
|
|
// CHECK-LABEL: define dso_local void @imag_on_scalar_with_type_promotion(
|
|
// CHECK-SAME: ) #[[ATTR0]] {
|
|
// CHECK-NEXT: [[ENTRY:.*:]]
|
|
// CHECK-NEXT: [[A:%.*]] = alloca { half, half }, align 2
|
|
// CHECK-NEXT: [[B:%.*]] = alloca half, align 2
|
|
// CHECK-NEXT: [[A_IMAGP:%.*]] = getelementptr inbounds nuw { 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: store half [[UNPROMOTION]], ptr [[B]], align 2
|
|
// CHECK-NEXT: ret void
|
|
//
|
|
void imag_on_scalar_with_type_promotion() {
|
|
_Float16 _Complex a;
|
|
_Float16 b = __real__(__imag__ a);
|
|
}
|
|
//.
|
|
// CHECK: [[PROF2]] = !{!"branch_weights", i32 1, i32 1048575}
|
|
//.
|