diff --git a/clang/lib/Driver/ToolChains/Clang.cpp b/clang/lib/Driver/ToolChains/Clang.cpp index 3b98c7ae6e6ec..20d65a998a9a7 100644 --- a/clang/lib/Driver/ToolChains/Clang.cpp +++ b/clang/lib/Driver/ToolChains/Clang.cpp @@ -5660,12 +5660,14 @@ void Clang::ConstructJob(Compilation &C, const JobAction &JA, } // Non-PIC code defaults to -fdirect-access-external-data while PIC code - // defaults to -fno-direct-access-external-data. Pass the option if different - // from the default. + // defaults to -fno-direct-access-external-data. + // LoongArch does not and will not support copy relocation, so non-PIC code + // defaults to -fno-direct-access-external-data. + // Pass the option if different from the default. if (Arg *A = Args.getLastArg(options::OPT_fdirect_access_external_data, options::OPT_fno_direct_access_external_data)) - if (A->getOption().matches(options::OPT_fdirect_access_external_data) != - (PICLevel == 0)) + if (A->getOption().matches(options::OPT_fdirect_access_external_data) == + (PICLevel != 0 || Triple.isLoongArch())) A->render(Args, CmdArgs); if (Args.hasFlag(options::OPT_fno_plt, options::OPT_fplt, false)) { diff --git a/clang/lib/Frontend/CompilerInvocation.cpp b/clang/lib/Frontend/CompilerInvocation.cpp index 637c6a35af653..db5d597d5169d 100644 --- a/clang/lib/Frontend/CompilerInvocation.cpp +++ b/clang/lib/Frontend/CompilerInvocation.cpp @@ -1745,10 +1745,12 @@ bool CompilerInvocation::ParseCodeGenArgs(CodeGenOptions &Opts, ArgList &Args, // PIC defaults to -fno-direct-access-external-data while non-PIC defaults to // -fdirect-access-external-data. + // LoongArch does not and will not support copy relocation, so non-PIC code + // defaults to -fno-direct-access-external-data. Opts.DirectAccessExternalData = Args.hasArg(OPT_fdirect_access_external_data) || (!Args.hasArg(OPT_fno_direct_access_external_data) && - LangOpts->PICLevel == 0); + LangOpts->PICLevel == 0 && !T.isLoongArch()); if (Arg *A = Args.getLastArg(OPT_debug_info_kind_EQ)) { unsigned Val = diff --git a/clang/test/CodeGen/LoongArch/inline-asm-operand-modifiers.c b/clang/test/CodeGen/LoongArch/inline-asm-operand-modifiers.c index b36fe7a7b69bb..e3f31f0f702a9 100644 --- a/clang/test/CodeGen/LoongArch/inline-asm-operand-modifiers.c +++ b/clang/test/CodeGen/LoongArch/inline-asm-operand-modifiers.c @@ -6,7 +6,7 @@ // CHECK-LABEL: @test_z_zero( // CHECK-NEXT: entry: -// CHECK-NEXT: [[TMP0:%.*]] = tail call i32 asm sideeffect "add.w $0, $1, ${2:z}", "=r,r,ri"(i32 [[A:%.*]], i32 0) #[[ATTR1:[0-9]+]], !srcloc !2 +// CHECK-NEXT: [[TMP0:%.*]] = tail call i32 asm sideeffect "add.w $0, $1, ${2:z}", "=r,r,ri"(i32 [[A:%.*]], i32 0) #[[ATTR1:[0-9]+]], !srcloc !3 // CHECK-NEXT: ret void // void test_z_zero(int a) { @@ -16,7 +16,7 @@ void test_z_zero(int a) { // CHECK-LABEL: @test_z_nonzero( // CHECK-NEXT: entry: -// CHECK-NEXT: [[TMP0:%.*]] = tail call i32 asm sideeffect "add.w $0, $1, ${2:z}", "=r,r,ri"(i32 [[A:%.*]], i32 1) #[[ATTR1]], !srcloc !3 +// CHECK-NEXT: [[TMP0:%.*]] = tail call i32 asm sideeffect "add.w $0, $1, ${2:z}", "=r,r,ri"(i32 [[A:%.*]], i32 1) #[[ATTR1]], !srcloc !4 // CHECK-NEXT: ret void // void test_z_nonzero(int a) { diff --git a/clang/test/CodeGen/LoongArch/intrinsic-la32.c b/clang/test/CodeGen/LoongArch/intrinsic-la32.c index 93d54f511a9cd..0c603a3e46d39 100644 --- a/clang/test/CodeGen/LoongArch/intrinsic-la32.c +++ b/clang/test/CodeGen/LoongArch/intrinsic-la32.c @@ -169,8 +169,8 @@ unsigned int cpucfg(unsigned int a) { // LA32-LABEL: @rdtime( // LA32-NEXT: entry: -// LA32-NEXT: [[TMP0:%.*]] = tail call { i32, i32 } asm sideeffect "rdtimeh.w $0, $1\0A\09", "=&r,=&r"() #[[ATTR1:[0-9]+]], !srcloc !2 -// LA32-NEXT: [[TMP1:%.*]] = tail call { i32, i32 } asm sideeffect "rdtimel.w $0, $1\0A\09", "=&r,=&r"() #[[ATTR1]], !srcloc !3 +// LA32-NEXT: [[TMP0:%.*]] = tail call { i32, i32 } asm sideeffect "rdtimeh.w $0, $1\0A\09", "=&r,=&r"() #[[ATTR1:[0-9]+]], !srcloc !3 +// LA32-NEXT: [[TMP1:%.*]] = tail call { i32, i32 } asm sideeffect "rdtimel.w $0, $1\0A\09", "=&r,=&r"() #[[ATTR1]], !srcloc !4 // LA32-NEXT: ret void // void rdtime() { @@ -206,6 +206,11 @@ void loongarch_movgr2fcsr(int a) { // CHECK-NEXT: tail call void @llvm.loongarch.cacop.w(i32 1, i32 [[A:%.*]], i32 1024) // CHECK-NEXT: tail call void @llvm.loongarch.cacop.w(i32 1, i32 [[A]], i32 1024) // CHECK-NEXT: ret void +// LA32-LABEL: @cacop_w( +// LA32-NEXT: entry: +// LA32-NEXT: tail call void @llvm.loongarch.cacop.w(i32 1, i32 [[A:%.*]], i32 1024) +// LA32-NEXT: tail call void @llvm.loongarch.cacop.w(i32 1, i32 [[A]], i32 1024) +// LA32-NEXT: ret void // void cacop_w(unsigned long int a) { __cacop_w(1, a, 1024); diff --git a/clang/test/CodeGen/LoongArch/intrinsic-la64.c b/clang/test/CodeGen/LoongArch/intrinsic-la64.c index a740882eef541..773135dc19e90 100644 --- a/clang/test/CodeGen/LoongArch/intrinsic-la64.c +++ b/clang/test/CodeGen/LoongArch/intrinsic-la64.c @@ -387,7 +387,7 @@ unsigned int cpucfg(unsigned int a) { // CHECK-LABEL: @rdtime_d( // CHECK-NEXT: entry: -// CHECK-NEXT: [[TMP0:%.*]] = tail call { i64, i64 } asm sideeffect "rdtime.d $0, $1\0A\09", "=&r,=&r"() #[[ATTR1:[0-9]+]], !srcloc !2 +// CHECK-NEXT: [[TMP0:%.*]] = tail call { i64, i64 } asm sideeffect "rdtime.d $0, $1\0A\09", "=&r,=&r"() #[[ATTR1:[0-9]+]], !srcloc !3 // CHECK-NEXT: ret void // void rdtime_d() { @@ -396,8 +396,8 @@ void rdtime_d() { // CHECK-LABEL: @rdtime( // CHECK-NEXT: entry: -// CHECK-NEXT: [[TMP0:%.*]] = tail call { i32, i32 } asm sideeffect "rdtimeh.w $0, $1\0A\09", "=&r,=&r"() #[[ATTR1]], !srcloc !3 -// CHECK-NEXT: [[TMP1:%.*]] = tail call { i32, i32 } asm sideeffect "rdtimel.w $0, $1\0A\09", "=&r,=&r"() #[[ATTR1]], !srcloc !4 +// CHECK-NEXT: [[TMP0:%.*]] = tail call { i32, i32 } asm sideeffect "rdtimeh.w $0, $1\0A\09", "=&r,=&r"() #[[ATTR1]], !srcloc !4 +// CHECK-NEXT: [[TMP1:%.*]] = tail call { i32, i32 } asm sideeffect "rdtimel.w $0, $1\0A\09", "=&r,=&r"() #[[ATTR1]], !srcloc !5 // CHECK-NEXT: ret void // void rdtime() { diff --git a/clang/test/CodeGen/LoongArch/lasx/inline-asm-gcc-regs.c b/clang/test/CodeGen/LoongArch/lasx/inline-asm-gcc-regs.c index ed1a9660a06c9..a863d861cb51b 100644 --- a/clang/test/CodeGen/LoongArch/lasx/inline-asm-gcc-regs.c +++ b/clang/test/CodeGen/LoongArch/lasx/inline-asm-gcc-regs.c @@ -4,7 +4,7 @@ typedef signed char v32i8 __attribute__((vector_size(32), aligned(32))); // CHECK-LABEL: @test_xr0( -// CHECK: tail call void asm sideeffect "", "{$xr0}"(<32 x i8> undef) #[[ATTR1:[0-9]+]], !srcloc !2 +// CHECK: tail call void asm sideeffect "", "{$xr0}"(<32 x i8> undef) #[[ATTR1:[0-9]+]], !srcloc !3 // void test_xr0() { register v32i8 a asm ("$xr0"); @@ -12,7 +12,7 @@ void test_xr0() { } // CHECK-LABEL: @test_xr7( -// CHECK: tail call void asm sideeffect "", "{$xr7}"(<32 x i8> undef) #[[ATTR1]], !srcloc !3 +// CHECK: tail call void asm sideeffect "", "{$xr7}"(<32 x i8> undef) #[[ATTR1]], !srcloc !4 // void test_xr7() { register v32i8 a asm ("$xr7"); @@ -20,7 +20,7 @@ void test_xr7() { } // CHECK-LABEL: @test_xr15( -// CHECK: tail call void asm sideeffect "", "{$xr15}"(<32 x i8> undef) #[[ATTR1]], !srcloc !4 +// CHECK: tail call void asm sideeffect "", "{$xr15}"(<32 x i8> undef) #[[ATTR1]], !srcloc !5 // void test_xr15() { register v32i8 a asm ("$xr15"); @@ -28,7 +28,7 @@ void test_xr15() { } // CHECK-LABEL: @test_xr31( -// CHECK: tail call void asm sideeffect "", "{$xr31}"(<32 x i8> undef) #[[ATTR1]], !srcloc !5 +// CHECK: tail call void asm sideeffect "", "{$xr31}"(<32 x i8> undef) #[[ATTR1]], !srcloc !6 // void test_xr31() { register v32i8 a asm ("$xr31"); diff --git a/clang/test/CodeGen/LoongArch/lasx/inline-asm-operand-modifier.c b/clang/test/CodeGen/LoongArch/lasx/inline-asm-operand-modifier.c index a5cc8798fd66b..90257d2e1ae62 100644 --- a/clang/test/CodeGen/LoongArch/lasx/inline-asm-operand-modifier.c +++ b/clang/test/CodeGen/LoongArch/lasx/inline-asm-operand-modifier.c @@ -6,7 +6,7 @@ typedef long long v4i64 __attribute__ ((vector_size(32), aligned(32))); // CHECK-LABEL: define dso_local void @test_u // CHECK-SAME: () local_unnamed_addr #[[ATTR0:[0-9]+]] { // CHECK-NEXT: entry: -// CHECK-NEXT: [[TMP0:%.*]] = tail call <4 x i64> asm sideeffect "xvldi ${0:u}, 1", "=f"() #[[ATTR1:[0-9]+]], !srcloc !2 +// CHECK-NEXT: [[TMP0:%.*]] = tail call <4 x i64> asm sideeffect "xvldi ${0:u}, 1", "=f"() #[[ATTR1:[0-9]+]], !srcloc !3 // CHECK-NEXT: ret void // void test_u() { diff --git a/clang/test/CodeGen/LoongArch/lsx/inline-asm-gcc-regs.c b/clang/test/CodeGen/LoongArch/lsx/inline-asm-gcc-regs.c index b05b1c8c15fae..e77362f7ef23d 100644 --- a/clang/test/CodeGen/LoongArch/lsx/inline-asm-gcc-regs.c +++ b/clang/test/CodeGen/LoongArch/lsx/inline-asm-gcc-regs.c @@ -4,7 +4,7 @@ typedef signed char v16i8 __attribute__((vector_size(16), aligned(16))); // CHECK-LABEL: @test_vr0( -// CHECK: tail call void asm sideeffect "", "{$vr0}"(<16 x i8> undef) #[[ATTR1:[0-9]+]], !srcloc !2 +// CHECK: tail call void asm sideeffect "", "{$vr0}"(<16 x i8> undef) #[[ATTR1:[0-9]+]], !srcloc !3 // void test_vr0() { register v16i8 a asm ("$vr0"); @@ -12,7 +12,7 @@ void test_vr0() { } // CHECK-LABEL: @test_vr7( -// CHECK: tail call void asm sideeffect "", "{$vr7}"(<16 x i8> undef) #[[ATTR1]], !srcloc !3 +// CHECK: tail call void asm sideeffect "", "{$vr7}"(<16 x i8> undef) #[[ATTR1]], !srcloc !4 // void test_vr7() { register v16i8 a asm ("$vr7"); @@ -20,7 +20,7 @@ void test_vr7() { } // CHECK-LABEL: @test_vr15( -// CHECK: tail call void asm sideeffect "", "{$vr15}"(<16 x i8> undef) #[[ATTR1]], !srcloc !4 +// CHECK: tail call void asm sideeffect "", "{$vr15}"(<16 x i8> undef) #[[ATTR1]], !srcloc !5 // void test_vr15() { register v16i8 a asm ("$vr15"); @@ -28,7 +28,7 @@ void test_vr15() { } // CHECK-LABEL: @test_vr31( -// CHECK: tail call void asm sideeffect "", "{$vr31}"(<16 x i8> undef) #[[ATTR1]], !srcloc !5 +// CHECK: tail call void asm sideeffect "", "{$vr31}"(<16 x i8> undef) #[[ATTR1]], !srcloc !6 // void test_vr31() { register v16i8 a asm ("$vr31"); diff --git a/clang/test/CodeGen/LoongArch/lsx/inline-asm-operand-modifier.c b/clang/test/CodeGen/LoongArch/lsx/inline-asm-operand-modifier.c index 5e0fae984134e..a055a427dc0b3 100644 --- a/clang/test/CodeGen/LoongArch/lsx/inline-asm-operand-modifier.c +++ b/clang/test/CodeGen/LoongArch/lsx/inline-asm-operand-modifier.c @@ -6,7 +6,7 @@ typedef long long v2i64 __attribute__ ((vector_size(16), aligned(16))); // CHECK-LABEL: define dso_local void @test_w // CHECK-SAME: () local_unnamed_addr #[[ATTR0:[0-9]+]] { // CHECK-NEXT: entry: -// CHECK-NEXT: [[TMP0:%.*]] = tail call <2 x i64> asm sideeffect "vldi ${0:w}, 1", "=f"() #[[ATTR1:[0-9]+]], !srcloc !2 +// CHECK-NEXT: [[TMP0:%.*]] = tail call <2 x i64> asm sideeffect "vldi ${0:w}, 1", "=f"() #[[ATTR1:[0-9]+]], !srcloc !3 // CHECK-NEXT: ret void // void test_w() { diff --git a/clang/test/Driver/fdirect-access-external-data.c b/clang/test/Driver/fdirect-access-external-data.c index f132b1b088af3..6e8dfd3e14fdb 100644 --- a/clang/test/Driver/fdirect-access-external-data.c +++ b/clang/test/Driver/fdirect-access-external-data.c @@ -3,12 +3,25 @@ // RUN: %clang -### -c -target x86_64 %s -fdirect-access-external-data 2>&1 | FileCheck %s --check-prefix=DEFAULT // RUN: %clang -### -c -target x86_64 %s -fdirect-access-external-data -fno-direct-access-external-data 2>&1 | FileCheck %s --check-prefix=INDIRECT +/// -fno-pic code defaults to -fno-direct-access-external-data. +// RUN: %clang -### -c -target loongarch64 %s 2>&1 | FileCheck %s --check-prefix=DEFAULT +// RUN: %clang -### -c -target loongarch64 %s -fdirect-access-external-data 2>&1 | FileCheck %s --check-prefix=DIRECT +// RUN: %clang -### -c -target loongarch64 %s -fdirect-access-external-data -fno-direct-access-external-data 2>&1 | FileCheck %s --check-prefix=DEFAULT + /// -fpie/-fpic code defaults to -fdirect-access-external-data. // RUN: %clang -### -c -target x86_64 %s -fpie 2>&1 | FileCheck %s --check-prefix=DEFAULT // RUN: %clang -### -c -target x86_64 %s -fpie -fno-direct-access-external-data -fdirect-access-external-data 2>&1 | FileCheck %s --check-prefix=DIRECT // RUN: %clang -### -c -target aarch64 %s -fpic 2>&1 | FileCheck %s --check-prefix=DEFAULT // RUN: %clang -### -c -target aarch64 %s -fpic -fdirect-access-external-data 2>&1 | FileCheck %s --check-prefix=DIRECT +/// -fpie/-fpic code defaults to -fno-direct-access-external-data. +// RUN: %clang -### -c -target loongarch64 %s -fpie 2>&1 | FileCheck %s --check-prefix=DEFAULT +// RUN: %clang -### -c -target loongarch64 %s -fpie -fdirect-access-external-data 2>&1 | FileCheck %s --check-prefix=DIRECT +// RUN: %clang -### -c -target loongarch64 %s -fpie -fdirect-access-external-data -fno-direct-access-external-data 2>&1 | FileCheck %s --check-prefix=DEFAULT +// RUN: %clang -### -c -target loongarch64 %s -fpic 2>&1 | FileCheck %s --check-prefix=DEFAULT +// RUN: %clang -### -c -target loongarch64 %s -fpic -fdirect-access-external-data 2>&1 | FileCheck %s --check-prefix=DIRECT +// RUN: %clang -### -c -target loongarch64 %s -fpic -fdirect-access-external-data -fno-direct-access-external-data 2>&1 | FileCheck %s --check-prefix=DEFAULT + // DEFAULT-NOT: direct-access-external-data" // DIRECT: "-fdirect-access-external-data" // INDIRECT: "-fno-direct-access-external-data"