From 19185d5a72565fce34521cb59d6c87232a86e0d4 Mon Sep 17 00:00:00 2001 From: Ye Luo Date: Wed, 27 Mar 2024 18:40:57 -0500 Subject: [PATCH 001/788] [Libomptarget] Make dynamic loading libffi more verbose. (#86891) --- .../plugins-nextgen/host/dynamic_ffi/ffi.cpp | 16 +++++++++++++--- 1 file changed, 13 insertions(+), 3 deletions(-) diff --git a/openmp/libomptarget/plugins-nextgen/host/dynamic_ffi/ffi.cpp b/openmp/libomptarget/plugins-nextgen/host/dynamic_ffi/ffi.cpp index c79daa798581..c586ad1c1969 100644 --- a/openmp/libomptarget/plugins-nextgen/host/dynamic_ffi/ffi.cpp +++ b/openmp/libomptarget/plugins-nextgen/host/dynamic_ffi/ffi.cpp @@ -11,6 +11,8 @@ //===----------------------------------------------------------------------===// #include "llvm/Support/DynamicLibrary.h" + +#include "Shared/Debug.h" #include #include "DLWrap.h" @@ -37,15 +39,21 @@ uint32_t ffi_init() { std::string ErrMsg; auto DynlibHandle = std::make_unique( llvm::sys::DynamicLibrary::getPermanentLibrary(FFI_PATH, &ErrMsg)); - if (!DynlibHandle->isValid()) + + if (!DynlibHandle->isValid()) { + DP("Unable to load library '%s': %s!\n", FFI_PATH, ErrMsg.c_str()); return DYNAMIC_FFI_FAIL; + } for (size_t I = 0; I < dlwrap::size(); I++) { const char *Sym = dlwrap::symbol(I); void *P = DynlibHandle->getAddressOfSymbol(Sym); - if (P == nullptr) + if (P == nullptr) { + DP("Unable to find '%s' in '%s'!\n", Sym, FFI_PATH); return DYNAMIC_FFI_FAIL; + } + DP("Implementing %s with dlsym(%s) -> %p\n", Sym, Sym, P); *dlwrap::pointer(I) = P; } @@ -53,8 +61,10 @@ uint32_t ffi_init() { #define DYNAMIC_INIT(SYMBOL) \ { \ void *SymbolPtr = DynlibHandle->getAddressOfSymbol(#SYMBOL); \ - if (!SymbolPtr) \ + if (!SymbolPtr) { \ + DP("Unable to find '%s' in '%s'!\n", #SYMBOL, FFI_PATH); \ return DYNAMIC_FFI_FAIL; \ + } \ SYMBOL = *reinterpret_cast(SymbolPtr); \ } DYNAMIC_INIT(ffi_type_void); -- GitLab From e318613418e08e20d3b9e139a1a3ef0208db4844 Mon Sep 17 00:00:00 2001 From: Alex MacLean Date: Wed, 27 Mar 2024 16:49:59 -0700 Subject: [PATCH 002/788] [NFC][TLI] Move VecFuncs to statics to reduce stack usage (#86829) `TargetLibraryInfoImpl::addVectorizableFunctionsFromVecLib` has a lot of data in local stack arrays, which MSVC keeps on the stack even in release builds. To reduce stack usage, the data arrays (which are const), are moved outside the function as statics. This drops the method stack usage to be negligible. --- llvm/lib/Analysis/TargetLibraryInfo.cpp | 130 +++++++++++++----------- 1 file changed, 68 insertions(+), 62 deletions(-) diff --git a/llvm/lib/Analysis/TargetLibraryInfo.cpp b/llvm/lib/Analysis/TargetLibraryInfo.cpp index c8195584ade3..9e17dcaa5592 100644 --- a/llvm/lib/Analysis/TargetLibraryInfo.cpp +++ b/llvm/lib/Analysis/TargetLibraryInfo.cpp @@ -1190,107 +1190,113 @@ void TargetLibraryInfoImpl::addVectorizableFunctions(ArrayRef Fns) { llvm::sort(ScalarDescs, compareByVectorFnName); } +static const VecDesc VecFuncs_Accelerate[] = { +#define TLI_DEFINE_ACCELERATE_VECFUNCS +#include "llvm/Analysis/VecFuncs.def" +}; + +static const VecDesc VecFuncs_DarwinLibSystemM[] = { +#define TLI_DEFINE_DARWIN_LIBSYSTEM_M_VECFUNCS +#include "llvm/Analysis/VecFuncs.def" +}; + +static const VecDesc VecFuncs_LIBMVEC_X86[] = { +#define TLI_DEFINE_LIBMVEC_X86_VECFUNCS +#include "llvm/Analysis/VecFuncs.def" +}; + +static const VecDesc VecFuncs_MASSV[] = { +#define TLI_DEFINE_MASSV_VECFUNCS +#include "llvm/Analysis/VecFuncs.def" +}; + +static const VecDesc VecFuncs_SVML[] = { +#define TLI_DEFINE_SVML_VECFUNCS +#include "llvm/Analysis/VecFuncs.def" +}; + +static const VecDesc VecFuncs_SLEEFGNUABI_VF2[] = { +#define TLI_DEFINE_SLEEFGNUABI_VF2_VECFUNCS +#define TLI_DEFINE_VECFUNC(SCAL, VEC, VF, VABI_PREFIX) \ + {SCAL, VEC, VF, /* MASK = */ false, VABI_PREFIX}, +#include "llvm/Analysis/VecFuncs.def" +}; +static const VecDesc VecFuncs_SLEEFGNUABI_VF4[] = { +#define TLI_DEFINE_SLEEFGNUABI_VF4_VECFUNCS +#define TLI_DEFINE_VECFUNC(SCAL, VEC, VF, VABI_PREFIX) \ + {SCAL, VEC, VF, /* MASK = */ false, VABI_PREFIX}, +#include "llvm/Analysis/VecFuncs.def" +}; +static const VecDesc VecFuncs_SLEEFGNUABI_VFScalable[] = { +#define TLI_DEFINE_SLEEFGNUABI_SCALABLE_VECFUNCS +#define TLI_DEFINE_VECFUNC(SCAL, VEC, VF, MASK, VABI_PREFIX) \ + {SCAL, VEC, VF, MASK, VABI_PREFIX}, +#include "llvm/Analysis/VecFuncs.def" +}; + +static const VecDesc VecFuncs_ArmPL[] = { +#define TLI_DEFINE_ARMPL_VECFUNCS +#define TLI_DEFINE_VECFUNC(SCAL, VEC, VF, MASK, VABI_PREFIX) \ + {SCAL, VEC, VF, MASK, VABI_PREFIX}, +#include "llvm/Analysis/VecFuncs.def" +}; + +const VecDesc VecFuncs_AMDLIBM[] = { +#define TLI_DEFINE_AMDLIBM_VECFUNCS +#define TLI_DEFINE_VECFUNC(SCAL, VEC, VF, MASK, VABI_PREFIX) \ + {SCAL, VEC, VF, MASK, VABI_PREFIX}, +#include "llvm/Analysis/VecFuncs.def" +}; + void TargetLibraryInfoImpl::addVectorizableFunctionsFromVecLib( enum VectorLibrary VecLib, const llvm::Triple &TargetTriple) { switch (VecLib) { case Accelerate: { - const VecDesc VecFuncs[] = { - #define TLI_DEFINE_ACCELERATE_VECFUNCS - #include "llvm/Analysis/VecFuncs.def" - }; - addVectorizableFunctions(VecFuncs); + addVectorizableFunctions(VecFuncs_Accelerate); break; } case DarwinLibSystemM: { - const VecDesc VecFuncs[] = { - #define TLI_DEFINE_DARWIN_LIBSYSTEM_M_VECFUNCS - #include "llvm/Analysis/VecFuncs.def" - }; - addVectorizableFunctions(VecFuncs); + addVectorizableFunctions(VecFuncs_DarwinLibSystemM); break; } case LIBMVEC_X86: { - const VecDesc VecFuncs[] = { - #define TLI_DEFINE_LIBMVEC_X86_VECFUNCS - #include "llvm/Analysis/VecFuncs.def" - }; - addVectorizableFunctions(VecFuncs); + addVectorizableFunctions(VecFuncs_LIBMVEC_X86); break; } case MASSV: { - const VecDesc VecFuncs[] = { - #define TLI_DEFINE_MASSV_VECFUNCS - #include "llvm/Analysis/VecFuncs.def" - }; - addVectorizableFunctions(VecFuncs); + addVectorizableFunctions(VecFuncs_MASSV); break; } case SVML: { - const VecDesc VecFuncs[] = { - #define TLI_DEFINE_SVML_VECFUNCS - #include "llvm/Analysis/VecFuncs.def" - }; - addVectorizableFunctions(VecFuncs); + addVectorizableFunctions(VecFuncs_SVML); break; } case SLEEFGNUABI: { - const VecDesc VecFuncs_VF2[] = { -#define TLI_DEFINE_SLEEFGNUABI_VF2_VECFUNCS -#define TLI_DEFINE_VECFUNC(SCAL, VEC, VF, VABI_PREFIX) \ - {SCAL, VEC, VF, /* MASK = */ false, VABI_PREFIX}, -#include "llvm/Analysis/VecFuncs.def" - }; - const VecDesc VecFuncs_VF4[] = { -#define TLI_DEFINE_SLEEFGNUABI_VF4_VECFUNCS -#define TLI_DEFINE_VECFUNC(SCAL, VEC, VF, VABI_PREFIX) \ - {SCAL, VEC, VF, /* MASK = */ false, VABI_PREFIX}, -#include "llvm/Analysis/VecFuncs.def" - }; - const VecDesc VecFuncs_VFScalable[] = { -#define TLI_DEFINE_SLEEFGNUABI_SCALABLE_VECFUNCS -#define TLI_DEFINE_VECFUNC(SCAL, VEC, VF, MASK, VABI_PREFIX) \ - {SCAL, VEC, VF, MASK, VABI_PREFIX}, -#include "llvm/Analysis/VecFuncs.def" - }; - switch (TargetTriple.getArch()) { default: break; case llvm::Triple::aarch64: case llvm::Triple::aarch64_be: - addVectorizableFunctions(VecFuncs_VF2); - addVectorizableFunctions(VecFuncs_VF4); - addVectorizableFunctions(VecFuncs_VFScalable); + addVectorizableFunctions(VecFuncs_SLEEFGNUABI_VF2); + addVectorizableFunctions(VecFuncs_SLEEFGNUABI_VF4); + addVectorizableFunctions(VecFuncs_SLEEFGNUABI_VFScalable); break; } break; } case ArmPL: { - const VecDesc VecFuncs[] = { -#define TLI_DEFINE_ARMPL_VECFUNCS -#define TLI_DEFINE_VECFUNC(SCAL, VEC, VF, MASK, VABI_PREFIX) \ - {SCAL, VEC, VF, MASK, VABI_PREFIX}, -#include "llvm/Analysis/VecFuncs.def" - }; - switch (TargetTriple.getArch()) { default: break; case llvm::Triple::aarch64: case llvm::Triple::aarch64_be: - addVectorizableFunctions(VecFuncs); + addVectorizableFunctions(VecFuncs_ArmPL); break; } break; } case AMDLIBM: { - const VecDesc VecFuncs[] = { -#define TLI_DEFINE_AMDLIBM_VECFUNCS -#define TLI_DEFINE_VECFUNC(SCAL, VEC, VF, MASK, VABI_PREFIX) \ - {SCAL, VEC, VF, MASK, VABI_PREFIX}, -#include "llvm/Analysis/VecFuncs.def" - }; - addVectorizableFunctions(VecFuncs); + addVectorizableFunctions(VecFuncs_AMDLIBM); break; } case NoLibrary: -- GitLab From 036e7ee9d1f1bdc194b56302f8dd27d5eb6cfdab Mon Sep 17 00:00:00 2001 From: Eli Friedman Date: Wed, 27 Mar 2024 17:06:41 -0700 Subject: [PATCH 003/788] [NFC][AArch64] Regenerate regression tests. --- .../GlobalISel/load-addressing-modes.mir | 329 ++++++++++-------- .../aarch64-split-and-bitmask-immediate.ll | 14 +- 2 files changed, 186 insertions(+), 157 deletions(-) diff --git a/llvm/test/CodeGen/AArch64/GlobalISel/load-addressing-modes.mir b/llvm/test/CodeGen/AArch64/GlobalISel/load-addressing-modes.mir index 0cf9602adbb0..499c08fa4966 100644 --- a/llvm/test/CodeGen/AArch64/GlobalISel/load-addressing-modes.mir +++ b/llvm/test/CodeGen/AArch64/GlobalISel/load-addressing-modes.mir @@ -40,11 +40,12 @@ body: | ; CHECK-LABEL: name: ldrxrox_breg_oreg ; CHECK: liveins: $x0, $x1 - ; CHECK: [[COPY:%[0-9]+]]:gpr64sp = COPY $x0 - ; CHECK: [[COPY1:%[0-9]+]]:gpr64 = COPY $x1 - ; CHECK: [[LDRXroX:%[0-9]+]]:gpr64 = LDRXroX [[COPY]], [[COPY1]], 0, 0 :: (load (s64) from %ir.addr) - ; CHECK: $x0 = COPY [[LDRXroX]] - ; CHECK: RET_ReallyLR implicit $x0 + ; CHECK-NEXT: {{ $}} + ; CHECK-NEXT: [[COPY:%[0-9]+]]:gpr64sp = COPY $x0 + ; CHECK-NEXT: [[COPY1:%[0-9]+]]:gpr64 = COPY $x1 + ; CHECK-NEXT: [[LDRXroX:%[0-9]+]]:gpr64 = LDRXroX [[COPY]], [[COPY1]], 0, 0 :: (load (s64) from %ir.addr) + ; CHECK-NEXT: $x0 = COPY [[LDRXroX]] + ; CHECK-NEXT: RET_ReallyLR implicit $x0 %0:gpr(p0) = COPY $x0 %1:gpr(s64) = COPY $x1 %2:gpr(p0) = G_PTR_ADD %0, %1 @@ -65,11 +66,12 @@ body: | liveins: $d0, $x1 ; CHECK-LABEL: name: ldrdrox_breg_oreg ; CHECK: liveins: $d0, $x1 - ; CHECK: [[COPY:%[0-9]+]]:gpr64sp = COPY $d0 - ; CHECK: [[COPY1:%[0-9]+]]:gpr64 = COPY $x1 - ; CHECK: [[LDRDroX:%[0-9]+]]:fpr64 = LDRDroX [[COPY]], [[COPY1]], 0, 0 :: (load (s64) from %ir.addr) - ; CHECK: $d0 = COPY [[LDRDroX]] - ; CHECK: RET_ReallyLR implicit $d0 + ; CHECK-NEXT: {{ $}} + ; CHECK-NEXT: [[COPY:%[0-9]+]]:gpr64sp = COPY $d0 + ; CHECK-NEXT: [[COPY1:%[0-9]+]]:gpr64 = COPY $x1 + ; CHECK-NEXT: [[LDRDroX:%[0-9]+]]:fpr64 = LDRDroX [[COPY]], [[COPY1]], 0, 0 :: (load (s64) from %ir.addr) + ; CHECK-NEXT: $d0 = COPY [[LDRDroX]] + ; CHECK-NEXT: RET_ReallyLR implicit $d0 %0:gpr(p0) = COPY $d0 %1:gpr(s64) = COPY $x1 %2:gpr(p0) = G_PTR_ADD %0, %1 @@ -78,6 +80,9 @@ body: | RET_ReallyLR implicit $d0 ... --- +# This shouldn't be folded, since we reuse the result of the G_PTR_ADD outside +# the G_LOAD + name: more_than_one_use alignment: 4 legalized: true @@ -87,18 +92,17 @@ machineFunctionInfo: {} body: | bb.0: liveins: $x0, $x1 - ; This shouldn't be folded, since we reuse the result of the G_PTR_ADD outside - ; the G_LOAD ; CHECK-LABEL: name: more_than_one_use ; CHECK: liveins: $x0, $x1 - ; CHECK: [[COPY:%[0-9]+]]:gpr64 = COPY $x0 - ; CHECK: [[COPY1:%[0-9]+]]:gpr64 = COPY $x1 - ; CHECK: [[ADDXrr:%[0-9]+]]:gpr64common = ADDXrr [[COPY]], [[COPY1]] - ; CHECK: [[LDRXui:%[0-9]+]]:gpr64 = LDRXui [[ADDXrr]], 0 :: (load (s64) from %ir.addr) - ; CHECK: [[COPY2:%[0-9]+]]:gpr64 = COPY [[ADDXrr]] - ; CHECK: [[ADDXrr1:%[0-9]+]]:gpr64 = ADDXrr [[COPY2]], [[LDRXui]] - ; CHECK: $x0 = COPY [[ADDXrr1]] - ; CHECK: RET_ReallyLR implicit $x0 + ; CHECK-NEXT: {{ $}} + ; CHECK-NEXT: [[COPY:%[0-9]+]]:gpr64 = COPY $x0 + ; CHECK-NEXT: [[COPY1:%[0-9]+]]:gpr64 = COPY $x1 + ; CHECK-NEXT: [[ADDXrr:%[0-9]+]]:gpr64common = ADDXrr [[COPY]], [[COPY1]] + ; CHECK-NEXT: [[LDRXui:%[0-9]+]]:gpr64 = LDRXui [[ADDXrr]], 0 :: (load (s64) from %ir.addr) + ; CHECK-NEXT: [[COPY2:%[0-9]+]]:gpr64 = COPY [[ADDXrr]] + ; CHECK-NEXT: [[ADDXrr1:%[0-9]+]]:gpr64 = ADDXrr [[COPY2]], [[LDRXui]] + ; CHECK-NEXT: $x0 = COPY [[ADDXrr1]] + ; CHECK-NEXT: RET_ReallyLR implicit $x0 %0:gpr(p0) = COPY $x0 %1:gpr(s64) = COPY $x1 %2:gpr(p0) = G_PTR_ADD %0, %1 @@ -121,11 +125,12 @@ body: | liveins: $x0, $x1, $x2 ; CHECK-LABEL: name: ldrxrox_shl ; CHECK: liveins: $x0, $x1, $x2 - ; CHECK: [[COPY:%[0-9]+]]:gpr64 = COPY $x0 - ; CHECK: [[COPY1:%[0-9]+]]:gpr64sp = COPY $x1 - ; CHECK: [[LDRXroX:%[0-9]+]]:gpr64 = LDRXroX [[COPY1]], [[COPY]], 0, 1 :: (load (s64) from %ir.addr) - ; CHECK: $x2 = COPY [[LDRXroX]] - ; CHECK: RET_ReallyLR implicit $x2 + ; CHECK-NEXT: {{ $}} + ; CHECK-NEXT: [[COPY:%[0-9]+]]:gpr64 = COPY $x0 + ; CHECK-NEXT: [[COPY1:%[0-9]+]]:gpr64sp = COPY $x1 + ; CHECK-NEXT: [[LDRXroX:%[0-9]+]]:gpr64 = LDRXroX [[COPY1]], [[COPY]], 0, 1 :: (load (s64) from %ir.addr) + ; CHECK-NEXT: $x2 = COPY [[LDRXroX]] + ; CHECK-NEXT: RET_ReallyLR implicit $x2 %0:gpr(s64) = COPY $x0 %1:gpr(s64) = G_CONSTANT i64 3 %2:gpr(s64) = G_SHL %0, %1(s64) @@ -148,11 +153,12 @@ body: | liveins: $x0, $x1, $d2 ; CHECK-LABEL: name: ldrdrox_shl ; CHECK: liveins: $x0, $x1, $d2 - ; CHECK: [[COPY:%[0-9]+]]:gpr64 = COPY $x0 - ; CHECK: [[COPY1:%[0-9]+]]:gpr64sp = COPY $x1 - ; CHECK: [[LDRDroX:%[0-9]+]]:fpr64 = LDRDroX [[COPY1]], [[COPY]], 0, 1 :: (load (s64) from %ir.addr) - ; CHECK: $d2 = COPY [[LDRDroX]] - ; CHECK: RET_ReallyLR implicit $d2 + ; CHECK-NEXT: {{ $}} + ; CHECK-NEXT: [[COPY:%[0-9]+]]:gpr64 = COPY $x0 + ; CHECK-NEXT: [[COPY1:%[0-9]+]]:gpr64sp = COPY $x1 + ; CHECK-NEXT: [[LDRDroX:%[0-9]+]]:fpr64 = LDRDroX [[COPY1]], [[COPY]], 0, 1 :: (load (s64) from %ir.addr) + ; CHECK-NEXT: $d2 = COPY [[LDRDroX]] + ; CHECK-NEXT: RET_ReallyLR implicit $d2 %0:gpr(s64) = COPY $x0 %1:gpr(s64) = G_CONSTANT i64 3 %2:gpr(s64) = G_SHL %0, %1(s64) @@ -175,11 +181,12 @@ body: | liveins: $x0, $x1, $x2 ; CHECK-LABEL: name: ldrxrox_mul_rhs ; CHECK: liveins: $x0, $x1, $x2 - ; CHECK: [[COPY:%[0-9]+]]:gpr64 = COPY $x0 - ; CHECK: [[COPY1:%[0-9]+]]:gpr64sp = COPY $x1 - ; CHECK: [[LDRXroX:%[0-9]+]]:gpr64 = LDRXroX [[COPY1]], [[COPY]], 0, 1 :: (load (s64) from %ir.addr) - ; CHECK: $x2 = COPY [[LDRXroX]] - ; CHECK: RET_ReallyLR implicit $x2 + ; CHECK-NEXT: {{ $}} + ; CHECK-NEXT: [[COPY:%[0-9]+]]:gpr64 = COPY $x0 + ; CHECK-NEXT: [[COPY1:%[0-9]+]]:gpr64sp = COPY $x1 + ; CHECK-NEXT: [[LDRXroX:%[0-9]+]]:gpr64 = LDRXroX [[COPY1]], [[COPY]], 0, 1 :: (load (s64) from %ir.addr) + ; CHECK-NEXT: $x2 = COPY [[LDRXroX]] + ; CHECK-NEXT: RET_ReallyLR implicit $x2 %0:gpr(s64) = COPY $x0 %1:gpr(s64) = G_CONSTANT i64 8 %2:gpr(s64) = G_MUL %0, %1(s64) @@ -202,11 +209,12 @@ body: | liveins: $x0, $x1, $d2 ; CHECK-LABEL: name: ldrdrox_mul_rhs ; CHECK: liveins: $x0, $x1, $d2 - ; CHECK: [[COPY:%[0-9]+]]:gpr64 = COPY $x0 - ; CHECK: [[COPY1:%[0-9]+]]:gpr64sp = COPY $x1 - ; CHECK: [[LDRDroX:%[0-9]+]]:fpr64 = LDRDroX [[COPY1]], [[COPY]], 0, 1 :: (load (s64) from %ir.addr) - ; CHECK: $d2 = COPY [[LDRDroX]] - ; CHECK: RET_ReallyLR implicit $d2 + ; CHECK-NEXT: {{ $}} + ; CHECK-NEXT: [[COPY:%[0-9]+]]:gpr64 = COPY $x0 + ; CHECK-NEXT: [[COPY1:%[0-9]+]]:gpr64sp = COPY $x1 + ; CHECK-NEXT: [[LDRDroX:%[0-9]+]]:fpr64 = LDRDroX [[COPY1]], [[COPY]], 0, 1 :: (load (s64) from %ir.addr) + ; CHECK-NEXT: $d2 = COPY [[LDRDroX]] + ; CHECK-NEXT: RET_ReallyLR implicit $d2 %0:gpr(s64) = COPY $x0 %1:gpr(s64) = G_CONSTANT i64 8 %2:gpr(s64) = G_MUL %0, %1(s64) @@ -229,11 +237,12 @@ body: | liveins: $x0, $x1, $x2 ; CHECK-LABEL: name: ldrxrox_mul_lhs ; CHECK: liveins: $x0, $x1, $x2 - ; CHECK: [[COPY:%[0-9]+]]:gpr64 = COPY $x0 - ; CHECK: [[COPY1:%[0-9]+]]:gpr64sp = COPY $x1 - ; CHECK: [[LDRXroX:%[0-9]+]]:gpr64 = LDRXroX [[COPY1]], [[COPY]], 0, 1 :: (load (s64) from %ir.addr) - ; CHECK: $x2 = COPY [[LDRXroX]] - ; CHECK: RET_ReallyLR implicit $x2 + ; CHECK-NEXT: {{ $}} + ; CHECK-NEXT: [[COPY:%[0-9]+]]:gpr64 = COPY $x0 + ; CHECK-NEXT: [[COPY1:%[0-9]+]]:gpr64sp = COPY $x1 + ; CHECK-NEXT: [[LDRXroX:%[0-9]+]]:gpr64 = LDRXroX [[COPY1]], [[COPY]], 0, 1 :: (load (s64) from %ir.addr) + ; CHECK-NEXT: $x2 = COPY [[LDRXroX]] + ; CHECK-NEXT: RET_ReallyLR implicit $x2 %0:gpr(s64) = COPY $x0 %1:gpr(s64) = G_CONSTANT i64 8 %2:gpr(s64) = G_MUL %1, %0(s64) @@ -256,11 +265,12 @@ body: | liveins: $x0, $x1, $d2 ; CHECK-LABEL: name: ldrdrox_mul_lhs ; CHECK: liveins: $x0, $x1, $d2 - ; CHECK: [[COPY:%[0-9]+]]:gpr64 = COPY $x0 - ; CHECK: [[COPY1:%[0-9]+]]:gpr64sp = COPY $x1 - ; CHECK: [[LDRDroX:%[0-9]+]]:fpr64 = LDRDroX [[COPY1]], [[COPY]], 0, 1 :: (load (s64) from %ir.addr) - ; CHECK: $d2 = COPY [[LDRDroX]] - ; CHECK: RET_ReallyLR implicit $d2 + ; CHECK-NEXT: {{ $}} + ; CHECK-NEXT: [[COPY:%[0-9]+]]:gpr64 = COPY $x0 + ; CHECK-NEXT: [[COPY1:%[0-9]+]]:gpr64sp = COPY $x1 + ; CHECK-NEXT: [[LDRDroX:%[0-9]+]]:fpr64 = LDRDroX [[COPY1]], [[COPY]], 0, 1 :: (load (s64) from %ir.addr) + ; CHECK-NEXT: $d2 = COPY [[LDRDroX]] + ; CHECK-NEXT: RET_ReallyLR implicit $d2 %0:gpr(s64) = COPY $x0 %1:gpr(s64) = G_CONSTANT i64 8 %2:gpr(s64) = G_MUL %1, %0(s64) @@ -272,6 +282,9 @@ body: | ... --- +# Show that we don't get a shifted load from a mul when we don't have a +# power of 2. (The bit isn't set on the load.) + name: mul_not_pow_2 alignment: 4 legalized: true @@ -280,19 +293,18 @@ tracksRegLiveness: true machineFunctionInfo: {} body: | bb.0: - ; Show that we don't get a shifted load from a mul when we don't have a - ; power of 2. (The bit isn't set on the load.) liveins: $x0, $x1, $d2 ; CHECK-LABEL: name: mul_not_pow_2 ; CHECK: liveins: $x0, $x1, $d2 - ; CHECK: [[COPY:%[0-9]+]]:gpr64 = COPY $x0 - ; CHECK: [[MOVi32imm:%[0-9]+]]:gpr32 = MOVi32imm 7 - ; CHECK: [[SUBREG_TO_REG:%[0-9]+]]:gpr64 = SUBREG_TO_REG 0, [[MOVi32imm]], %subreg.sub_32 - ; CHECK: [[MADDXrrr:%[0-9]+]]:gpr64 = MADDXrrr [[SUBREG_TO_REG]], [[COPY]], $xzr - ; CHECK: [[COPY1:%[0-9]+]]:gpr64sp = COPY $x1 - ; CHECK: [[LDRDroX:%[0-9]+]]:fpr64 = LDRDroX [[COPY1]], [[MADDXrrr]], 0, 0 :: (load (s64) from %ir.addr) - ; CHECK: $d2 = COPY [[LDRDroX]] - ; CHECK: RET_ReallyLR implicit $d2 + ; CHECK-NEXT: {{ $}} + ; CHECK-NEXT: [[COPY:%[0-9]+]]:gpr64 = COPY $x0 + ; CHECK-NEXT: [[MOVi32imm:%[0-9]+]]:gpr32 = MOVi32imm 7 + ; CHECK-NEXT: [[SUBREG_TO_REG:%[0-9]+]]:gpr64 = SUBREG_TO_REG 0, [[MOVi32imm]], %subreg.sub_32 + ; CHECK-NEXT: [[MADDXrrr:%[0-9]+]]:gpr64 = MADDXrrr [[SUBREG_TO_REG]], [[COPY]], $xzr + ; CHECK-NEXT: [[COPY1:%[0-9]+]]:gpr64sp = COPY $x1 + ; CHECK-NEXT: [[LDRDroX:%[0-9]+]]:fpr64 = LDRDroX [[COPY1]], [[MADDXrrr]], 0, 0 :: (load (s64) from %ir.addr) + ; CHECK-NEXT: $d2 = COPY [[LDRDroX]] + ; CHECK-NEXT: RET_ReallyLR implicit $d2 %0:gpr(s64) = COPY $x0 %1:gpr(s64) = G_CONSTANT i64 7 %2:gpr(s64) = G_MUL %1, %0(s64) @@ -304,6 +316,9 @@ body: | ... --- +# Show that we don't get a shifted load from a mul when we don't have +# the right power of 2. (The bit isn't set on the load.) + name: mul_wrong_pow_2 alignment: 4 legalized: true @@ -312,19 +327,18 @@ tracksRegLiveness: true machineFunctionInfo: {} body: | bb.0: - ; Show that we don't get a shifted load from a mul when we don't have - ; the right power of 2. (The bit isn't set on the load.) liveins: $x0, $x1, $d2 ; CHECK-LABEL: name: mul_wrong_pow_2 ; CHECK: liveins: $x0, $x1, $d2 - ; CHECK: [[COPY:%[0-9]+]]:gpr64 = COPY $x0 - ; CHECK: [[MOVi32imm:%[0-9]+]]:gpr32 = MOVi32imm 16 - ; CHECK: [[SUBREG_TO_REG:%[0-9]+]]:gpr64 = SUBREG_TO_REG 0, [[MOVi32imm]], %subreg.sub_32 - ; CHECK: [[MADDXrrr:%[0-9]+]]:gpr64 = MADDXrrr [[SUBREG_TO_REG]], [[COPY]], $xzr - ; CHECK: [[COPY1:%[0-9]+]]:gpr64sp = COPY $x1 - ; CHECK: [[LDRDroX:%[0-9]+]]:fpr64 = LDRDroX [[COPY1]], [[MADDXrrr]], 0, 0 :: (load (s64) from %ir.addr) - ; CHECK: $d2 = COPY [[LDRDroX]] - ; CHECK: RET_ReallyLR implicit $d2 + ; CHECK-NEXT: {{ $}} + ; CHECK-NEXT: [[COPY:%[0-9]+]]:gpr64 = COPY $x0 + ; CHECK-NEXT: [[MOVi32imm:%[0-9]+]]:gpr32 = MOVi32imm 16 + ; CHECK-NEXT: [[SUBREG_TO_REG:%[0-9]+]]:gpr64 = SUBREG_TO_REG 0, [[MOVi32imm]], %subreg.sub_32 + ; CHECK-NEXT: [[MADDXrrr:%[0-9]+]]:gpr64 = MADDXrrr [[SUBREG_TO_REG]], [[COPY]], $xzr + ; CHECK-NEXT: [[COPY1:%[0-9]+]]:gpr64sp = COPY $x1 + ; CHECK-NEXT: [[LDRDroX:%[0-9]+]]:fpr64 = LDRDroX [[COPY1]], [[MADDXrrr]], 0, 0 :: (load (s64) from %ir.addr) + ; CHECK-NEXT: $d2 = COPY [[LDRDroX]] + ; CHECK-NEXT: RET_ReallyLR implicit $d2 %0:gpr(s64) = COPY $x0 %1:gpr(s64) = G_CONSTANT i64 16 %2:gpr(s64) = G_MUL %1, %0(s64) @@ -336,6 +350,9 @@ body: | ... --- +# Show that we can still fall back to the register-register addressing +# mode when we fail to pull in the shift. + name: more_than_one_use_shl_1 alignment: 4 legalized: true @@ -344,19 +361,18 @@ tracksRegLiveness: true machineFunctionInfo: {} body: | bb.0: - ; Show that we can still fall back to the register-register addressing - ; mode when we fail to pull in the shift. liveins: $x0, $x1, $x2 ; CHECK-LABEL: name: more_than_one_use_shl_1 ; CHECK: liveins: $x0, $x1, $x2 - ; CHECK: [[COPY:%[0-9]+]]:gpr64 = COPY $x0 - ; CHECK: [[UBFMXri:%[0-9]+]]:gpr64common = UBFMXri [[COPY]], 61, 60 - ; CHECK: [[COPY1:%[0-9]+]]:gpr64sp = COPY $x1 - ; CHECK: [[LDRXroX:%[0-9]+]]:gpr64 = LDRXroX [[COPY1]], [[UBFMXri]], 0, 0 :: (load (s64) from %ir.addr) - ; CHECK: [[ADDXri:%[0-9]+]]:gpr64common = ADDXri [[UBFMXri]], 3, 0 - ; CHECK: [[ADDXrr:%[0-9]+]]:gpr64 = ADDXrr [[LDRXroX]], [[ADDXri]] - ; CHECK: $x2 = COPY [[ADDXrr]] - ; CHECK: RET_ReallyLR implicit $x2 + ; CHECK-NEXT: {{ $}} + ; CHECK-NEXT: [[COPY:%[0-9]+]]:gpr64 = COPY $x0 + ; CHECK-NEXT: [[UBFMXri:%[0-9]+]]:gpr64common = UBFMXri [[COPY]], 61, 60 + ; CHECK-NEXT: [[COPY1:%[0-9]+]]:gpr64sp = COPY $x1 + ; CHECK-NEXT: [[LDRXroX:%[0-9]+]]:gpr64 = LDRXroX [[COPY1]], [[UBFMXri]], 0, 0 :: (load (s64) from %ir.addr) + ; CHECK-NEXT: [[ADDXri:%[0-9]+]]:gpr64common = ADDXri [[UBFMXri]], 3, 0 + ; CHECK-NEXT: [[ADDXrr:%[0-9]+]]:gpr64 = ADDXrr [[LDRXroX]], [[ADDXri]] + ; CHECK-NEXT: $x2 = COPY [[ADDXrr]] + ; CHECK-NEXT: RET_ReallyLR implicit $x2 %0:gpr(s64) = COPY $x0 %1:gpr(s64) = G_CONSTANT i64 3 %2:gpr(s64) = G_SHL %0, %1(s64) @@ -370,6 +386,9 @@ body: | ... --- +# Show that when the GEP is used outside a memory op, we don't do any +# folding at all. + name: more_than_one_use_shl_2 alignment: 4 legalized: true @@ -378,22 +397,21 @@ tracksRegLiveness: true machineFunctionInfo: {} body: | bb.0: - ; Show that when the GEP is used outside a memory op, we don't do any - ; folding at all. liveins: $x0, $x1, $x2 ; CHECK-LABEL: name: more_than_one_use_shl_2 ; CHECK: liveins: $x0, $x1, $x2 - ; CHECK: [[COPY:%[0-9]+]]:gpr64 = COPY $x0 - ; CHECK: [[UBFMXri:%[0-9]+]]:gpr64common = UBFMXri [[COPY]], 61, 60 - ; CHECK: [[COPY1:%[0-9]+]]:gpr64 = COPY $x1 - ; CHECK: [[ADDXrr:%[0-9]+]]:gpr64common = ADDXrr [[COPY1]], [[UBFMXri]] - ; CHECK: [[LDRXui:%[0-9]+]]:gpr64 = LDRXui [[ADDXrr]], 0 :: (load (s64) from %ir.addr) - ; CHECK: [[ADDXri:%[0-9]+]]:gpr64common = ADDXri [[UBFMXri]], 3, 0 - ; CHECK: [[ADDXrr1:%[0-9]+]]:gpr64 = ADDXrr [[LDRXui]], [[ADDXri]] - ; CHECK: [[COPY2:%[0-9]+]]:gpr64 = COPY [[ADDXrr]] - ; CHECK: [[ADDXrr2:%[0-9]+]]:gpr64 = ADDXrr [[COPY2]], [[ADDXrr1]] - ; CHECK: $x2 = COPY [[ADDXrr2]] - ; CHECK: RET_ReallyLR implicit $x2 + ; CHECK-NEXT: {{ $}} + ; CHECK-NEXT: [[COPY:%[0-9]+]]:gpr64 = COPY $x0 + ; CHECK-NEXT: [[UBFMXri:%[0-9]+]]:gpr64common = UBFMXri [[COPY]], 61, 60 + ; CHECK-NEXT: [[COPY1:%[0-9]+]]:gpr64 = COPY $x1 + ; CHECK-NEXT: [[ADDXrr:%[0-9]+]]:gpr64common = ADDXrr [[COPY1]], [[UBFMXri]] + ; CHECK-NEXT: [[LDRXui:%[0-9]+]]:gpr64 = LDRXui [[ADDXrr]], 0 :: (load (s64) from %ir.addr) + ; CHECK-NEXT: [[ADDXri:%[0-9]+]]:gpr64common = ADDXri [[UBFMXri]], 3, 0 + ; CHECK-NEXT: [[ADDXrr1:%[0-9]+]]:gpr64 = ADDXrr [[LDRXui]], [[ADDXri]] + ; CHECK-NEXT: [[COPY2:%[0-9]+]]:gpr64 = COPY [[ADDXrr]] + ; CHECK-NEXT: [[ADDXrr2:%[0-9]+]]:gpr64 = ADDXrr [[COPY2]], [[ADDXrr1]] + ; CHECK-NEXT: $x2 = COPY [[ADDXrr2]] + ; CHECK-NEXT: RET_ReallyLR implicit $x2 %0:gpr(s64) = COPY $x0 %1:gpr(s64) = G_CONSTANT i64 3 %2:gpr(s64) = G_SHL %0, %1(s64) @@ -409,6 +427,9 @@ body: | ... --- +# Show that when we have a fastpath for shift-left, we perform the folding +# if it has more than one use. + name: more_than_one_use_shl_lsl_fast alignment: 4 legalized: true @@ -417,18 +438,17 @@ tracksRegLiveness: true machineFunctionInfo: {} body: | bb.0: - ; Show that when we have a fastpath for shift-left, we perform the folding - ; if it has more than one use. liveins: $x0, $x1, $x2 ; CHECK-LABEL: name: more_than_one_use_shl_lsl_fast ; CHECK: liveins: $x0, $x1, $x2 - ; CHECK: [[COPY:%[0-9]+]]:gpr64 = COPY $x0 - ; CHECK: [[COPY1:%[0-9]+]]:gpr64sp = COPY $x1 - ; CHECK: [[LDRXroX:%[0-9]+]]:gpr64 = LDRXroX [[COPY1]], [[COPY]], 0, 1 :: (load (s64) from %ir.addr) - ; CHECK: [[LDRXroX1:%[0-9]+]]:gpr64 = LDRXroX [[COPY1]], [[COPY]], 0, 1 :: (load (s64) from %ir.addr) - ; CHECK: [[ADDXrr:%[0-9]+]]:gpr64 = ADDXrr [[LDRXroX]], [[LDRXroX1]] - ; CHECK: $x2 = COPY [[ADDXrr]] - ; CHECK: RET_ReallyLR implicit $x2 + ; CHECK-NEXT: {{ $}} + ; CHECK-NEXT: [[COPY:%[0-9]+]]:gpr64 = COPY $x0 + ; CHECK-NEXT: [[COPY1:%[0-9]+]]:gpr64sp = COPY $x1 + ; CHECK-NEXT: [[LDRXroX:%[0-9]+]]:gpr64 = LDRXroX [[COPY1]], [[COPY]], 0, 1 :: (load (s64) from %ir.addr) + ; CHECK-NEXT: [[LDRXroX1:%[0-9]+]]:gpr64 = LDRXroX [[COPY1]], [[COPY]], 0, 1 :: (load (s64) from %ir.addr) + ; CHECK-NEXT: [[ADDXrr:%[0-9]+]]:gpr64 = ADDXrr [[LDRXroX]], [[LDRXroX1]] + ; CHECK-NEXT: $x2 = COPY [[ADDXrr]] + ; CHECK-NEXT: RET_ReallyLR implicit $x2 %0:gpr(s64) = COPY $x0 %1:gpr(s64) = G_CONSTANT i64 3 %2:gpr(s64) = G_SHL %0, %1(s64) @@ -442,6 +462,9 @@ body: | ... --- +# Show that we don't fold into multiple memory ops when we don't have a +# fastpath for shift-left. + name: more_than_one_use_shl_lsl_slow alignment: 4 legalized: true @@ -450,19 +473,18 @@ tracksRegLiveness: true machineFunctionInfo: {} body: | bb.0: - ; Show that we don't fold into multiple memory ops when we don't have a - ; fastpath for shift-left. liveins: $x0, $x1, $x2 ; CHECK-LABEL: name: more_than_one_use_shl_lsl_slow ; CHECK: liveins: $x0, $x1, $x2 - ; CHECK: [[COPY:%[0-9]+]]:gpr64 = COPY $x0 - ; CHECK: [[COPY1:%[0-9]+]]:gpr64 = COPY $x1 - ; CHECK: [[ADDXrs:%[0-9]+]]:gpr64common = ADDXrs [[COPY1]], [[COPY]], 3 - ; CHECK: [[LDRXui:%[0-9]+]]:gpr64 = LDRXui [[ADDXrs]], 0 :: (load (s64) from %ir.addr) - ; CHECK: [[LDRXui1:%[0-9]+]]:gpr64 = LDRXui [[ADDXrs]], 0 :: (load (s64) from %ir.addr) - ; CHECK: [[ADDXrr:%[0-9]+]]:gpr64 = ADDXrr [[LDRXui]], [[LDRXui1]] - ; CHECK: $x2 = COPY [[ADDXrr]] - ; CHECK: RET_ReallyLR implicit $x2 + ; CHECK-NEXT: {{ $}} + ; CHECK-NEXT: [[COPY:%[0-9]+]]:gpr64 = COPY $x0 + ; CHECK-NEXT: [[COPY1:%[0-9]+]]:gpr64 = COPY $x1 + ; CHECK-NEXT: [[ADDXrs:%[0-9]+]]:gpr64common = ADDXrs [[COPY1]], [[COPY]], 3 + ; CHECK-NEXT: [[LDRXui:%[0-9]+]]:gpr64 = LDRXui [[ADDXrs]], 0 :: (load (s64) from %ir.addr) + ; CHECK-NEXT: [[LDRXui1:%[0-9]+]]:gpr64 = LDRXui [[ADDXrs]], 0 :: (load (s64) from %ir.addr) + ; CHECK-NEXT: [[ADDXrr:%[0-9]+]]:gpr64 = ADDXrr [[LDRXui]], [[LDRXui1]] + ; CHECK-NEXT: $x2 = COPY [[ADDXrr]] + ; CHECK-NEXT: RET_ReallyLR implicit $x2 %0:gpr(s64) = COPY $x0 %1:gpr(s64) = G_CONSTANT i64 3 %2:gpr(s64) = G_SHL %0, %1(s64) @@ -476,6 +498,9 @@ body: | ... --- +# Show that when we're optimizing for size, we'll do the folding no matter +# what. + name: more_than_one_use_shl_minsize alignment: 4 legalized: true @@ -484,22 +509,21 @@ tracksRegLiveness: true machineFunctionInfo: {} body: | bb.0: - ; Show that when we're optimizing for size, we'll do the folding no matter - ; what. liveins: $x0, $x1, $x2 ; CHECK-LABEL: name: more_than_one_use_shl_minsize ; CHECK: liveins: $x0, $x1, $x2 - ; CHECK: [[COPY:%[0-9]+]]:gpr64 = COPY $x0 - ; CHECK: [[UBFMXri:%[0-9]+]]:gpr64common = UBFMXri [[COPY]], 61, 60 - ; CHECK: [[COPY1:%[0-9]+]]:gpr64common = COPY $x1 - ; CHECK: [[COPY2:%[0-9]+]]:gpr64 = COPY [[COPY1]] - ; CHECK: [[ADDXrs:%[0-9]+]]:gpr64 = ADDXrs [[COPY2]], [[COPY]], 3 - ; CHECK: [[LDRXroX:%[0-9]+]]:gpr64 = LDRXroX [[COPY1]], [[COPY]], 0, 1 :: (load (s64) from %ir.addr) - ; CHECK: [[ADDXri:%[0-9]+]]:gpr64common = ADDXri [[UBFMXri]], 3, 0 - ; CHECK: [[ADDXrr:%[0-9]+]]:gpr64 = ADDXrr [[LDRXroX]], [[ADDXri]] - ; CHECK: [[ADDXrr1:%[0-9]+]]:gpr64 = ADDXrr [[ADDXrs]], [[ADDXrr]] - ; CHECK: $x2 = COPY [[ADDXrr1]] - ; CHECK: RET_ReallyLR implicit $x2 + ; CHECK-NEXT: {{ $}} + ; CHECK-NEXT: [[COPY:%[0-9]+]]:gpr64 = COPY $x0 + ; CHECK-NEXT: [[UBFMXri:%[0-9]+]]:gpr64common = UBFMXri [[COPY]], 61, 60 + ; CHECK-NEXT: [[COPY1:%[0-9]+]]:gpr64common = COPY $x1 + ; CHECK-NEXT: [[COPY2:%[0-9]+]]:gpr64 = COPY [[COPY1]] + ; CHECK-NEXT: [[ADDXrs:%[0-9]+]]:gpr64 = ADDXrs [[COPY2]], [[COPY]], 3 + ; CHECK-NEXT: [[LDRXroX:%[0-9]+]]:gpr64 = LDRXroX [[COPY1]], [[COPY]], 0, 1 :: (load (s64) from %ir.addr) + ; CHECK-NEXT: [[ADDXri:%[0-9]+]]:gpr64common = ADDXri [[UBFMXri]], 3, 0 + ; CHECK-NEXT: [[ADDXrr:%[0-9]+]]:gpr64 = ADDXrr [[LDRXroX]], [[ADDXri]] + ; CHECK-NEXT: [[ADDXrr1:%[0-9]+]]:gpr64 = ADDXrr [[ADDXrs]], [[ADDXrr]] + ; CHECK-NEXT: $x2 = COPY [[ADDXrr1]] + ; CHECK-NEXT: RET_ReallyLR implicit $x2 %0:gpr(s64) = COPY $x0 %1:gpr(s64) = G_CONSTANT i64 3 %2:gpr(s64) = G_SHL %0, %1(s64) @@ -525,11 +549,12 @@ body: | liveins: $x0, $x1 ; CHECK-LABEL: name: ldrwrox ; CHECK: liveins: $x0, $x1 - ; CHECK: [[COPY:%[0-9]+]]:gpr64sp = COPY $x0 - ; CHECK: [[COPY1:%[0-9]+]]:gpr64 = COPY $x1 - ; CHECK: [[LDRWroX:%[0-9]+]]:gpr32 = LDRWroX [[COPY]], [[COPY1]], 0, 0 :: (load (s32) from %ir.addr) - ; CHECK: $w2 = COPY [[LDRWroX]] - ; CHECK: RET_ReallyLR implicit $w2 + ; CHECK-NEXT: {{ $}} + ; CHECK-NEXT: [[COPY:%[0-9]+]]:gpr64sp = COPY $x0 + ; CHECK-NEXT: [[COPY1:%[0-9]+]]:gpr64 = COPY $x1 + ; CHECK-NEXT: [[LDRWroX:%[0-9]+]]:gpr32 = LDRWroX [[COPY]], [[COPY1]], 0, 0 :: (load (s32) from %ir.addr) + ; CHECK-NEXT: $w2 = COPY [[LDRWroX]] + ; CHECK-NEXT: RET_ReallyLR implicit $w2 %0:gpr(p0) = COPY $x0 %1:gpr(s64) = COPY $x1 %2:gpr(p0) = G_PTR_ADD %0, %1 @@ -549,11 +574,12 @@ body: | liveins: $d0, $x1 ; CHECK-LABEL: name: ldrsrox ; CHECK: liveins: $d0, $x1 - ; CHECK: [[COPY:%[0-9]+]]:gpr64sp = COPY $d0 - ; CHECK: [[COPY1:%[0-9]+]]:gpr64 = COPY $x1 - ; CHECK: [[LDRSroX:%[0-9]+]]:fpr32 = LDRSroX [[COPY]], [[COPY1]], 0, 0 :: (load (s32) from %ir.addr) - ; CHECK: $s2 = COPY [[LDRSroX]] - ; CHECK: RET_ReallyLR implicit $h2 + ; CHECK-NEXT: {{ $}} + ; CHECK-NEXT: [[COPY:%[0-9]+]]:gpr64sp = COPY $d0 + ; CHECK-NEXT: [[COPY1:%[0-9]+]]:gpr64 = COPY $x1 + ; CHECK-NEXT: [[LDRSroX:%[0-9]+]]:fpr32 = LDRSroX [[COPY]], [[COPY1]], 0, 0 :: (load (s32) from %ir.addr) + ; CHECK-NEXT: $s2 = COPY [[LDRSroX]] + ; CHECK-NEXT: RET_ReallyLR implicit $h2 %0:gpr(p0) = COPY $d0 %1:gpr(s64) = COPY $x1 %2:gpr(p0) = G_PTR_ADD %0, %1 @@ -573,11 +599,12 @@ body: | liveins: $x0, $x1 ; CHECK-LABEL: name: ldrhrox ; CHECK: liveins: $x0, $x1 - ; CHECK: [[COPY:%[0-9]+]]:gpr64sp = COPY $x0 - ; CHECK: [[COPY1:%[0-9]+]]:gpr64 = COPY $x1 - ; CHECK: [[LDRHroX:%[0-9]+]]:fpr16 = LDRHroX [[COPY]], [[COPY1]], 0, 0 :: (load (s16) from %ir.addr) - ; CHECK: $h2 = COPY [[LDRHroX]] - ; CHECK: RET_ReallyLR implicit $h2 + ; CHECK-NEXT: {{ $}} + ; CHECK-NEXT: [[COPY:%[0-9]+]]:gpr64sp = COPY $x0 + ; CHECK-NEXT: [[COPY1:%[0-9]+]]:gpr64 = COPY $x1 + ; CHECK-NEXT: [[LDRHroX:%[0-9]+]]:fpr16 = LDRHroX [[COPY]], [[COPY1]], 0, 0 :: (load (s16) from %ir.addr) + ; CHECK-NEXT: $h2 = COPY [[LDRHroX]] + ; CHECK-NEXT: RET_ReallyLR implicit $h2 %0:gpr(p0) = COPY $x0 %1:gpr(s64) = COPY $x1 %2:gpr(p0) = G_PTR_ADD %0, %1 @@ -597,11 +624,12 @@ body: | liveins: $x0, $x1 ; CHECK-LABEL: name: ldbbrox ; CHECK: liveins: $x0, $x1 - ; CHECK: [[COPY:%[0-9]+]]:gpr64sp = COPY $x0 - ; CHECK: [[COPY1:%[0-9]+]]:gpr64 = COPY $x1 - ; CHECK: [[LDRBBroX:%[0-9]+]]:gpr32 = LDRBBroX [[COPY]], [[COPY1]], 0, 0 :: (load (s8) from %ir.addr) - ; CHECK: $w2 = COPY [[LDRBBroX]] - ; CHECK: RET_ReallyLR implicit $w2 + ; CHECK-NEXT: {{ $}} + ; CHECK-NEXT: [[COPY:%[0-9]+]]:gpr64sp = COPY $x0 + ; CHECK-NEXT: [[COPY1:%[0-9]+]]:gpr64 = COPY $x1 + ; CHECK-NEXT: [[LDRBBroX:%[0-9]+]]:gpr32 = LDRBBroX [[COPY]], [[COPY1]], 0, 0 :: (load (s8) from %ir.addr) + ; CHECK-NEXT: $w2 = COPY [[LDRBBroX]] + ; CHECK-NEXT: RET_ReallyLR implicit $w2 %0:gpr(p0) = COPY $x0 %1:gpr(s64) = COPY $x1 %2:gpr(p0) = G_PTR_ADD %0, %1 @@ -621,11 +649,12 @@ body: | liveins: $d0, $x1 ; CHECK-LABEL: name: ldrqrox ; CHECK: liveins: $d0, $x1 - ; CHECK: [[COPY:%[0-9]+]]:gpr64sp = COPY $d0 - ; CHECK: [[COPY1:%[0-9]+]]:gpr64 = COPY $x1 - ; CHECK: [[LDRQroX:%[0-9]+]]:fpr128 = LDRQroX [[COPY]], [[COPY1]], 0, 0 :: (load (<2 x s64>) from %ir.addr) - ; CHECK: $q0 = COPY [[LDRQroX]] - ; CHECK: RET_ReallyLR implicit $q0 + ; CHECK-NEXT: {{ $}} + ; CHECK-NEXT: [[COPY:%[0-9]+]]:gpr64sp = COPY $d0 + ; CHECK-NEXT: [[COPY1:%[0-9]+]]:gpr64 = COPY $x1 + ; CHECK-NEXT: [[LDRQroX:%[0-9]+]]:fpr128 = LDRQroX [[COPY]], [[COPY1]], 0, 0 :: (load (<2 x s64>) from %ir.addr) + ; CHECK-NEXT: $q0 = COPY [[LDRQroX]] + ; CHECK-NEXT: RET_ReallyLR implicit $q0 %0:gpr(p0) = COPY $d0 %1:gpr(s64) = COPY $x1 %2:gpr(p0) = G_PTR_ADD %0, %1 diff --git a/llvm/test/CodeGen/AArch64/aarch64-split-and-bitmask-immediate.ll b/llvm/test/CodeGen/AArch64/aarch64-split-and-bitmask-immediate.ll index cf9ed4d5f0e1..573f921e638c 100644 --- a/llvm/test/CodeGen/AArch64/aarch64-split-and-bitmask-immediate.ll +++ b/llvm/test/CodeGen/AArch64/aarch64-split-and-bitmask-immediate.ll @@ -20,7 +20,7 @@ entry: define i8 @test2(i32 %a) { ; CHECK-LABEL: test2: ; CHECK: // %bb.0: // %entry -; CHECK-NEXT: mov w8, #135 +; CHECK-NEXT: mov w8, #135 // =0x87 ; CHECK-NEXT: and w8, w0, w8 ; CHECK-NEXT: cmp w8, #1024 ; CHECK-NEXT: cset w0, eq @@ -37,7 +37,7 @@ entry: define i8 @test3(i32 %a) { ; CHECK-LABEL: test3: ; CHECK: // %bb.0: // %entry -; CHECK-NEXT: mov w8, #1024 +; CHECK-NEXT: mov w8, #1024 // =0x400 ; CHECK-NEXT: movk w8, #33, lsl #16 ; CHECK-NEXT: and w8, w0, w8 ; CHECK-NEXT: cmp w8, #1024 @@ -84,7 +84,7 @@ entry: define i8 @test6(i64 %a) { ; CHECK-LABEL: test6: ; CHECK: // %bb.0: // %entry -; CHECK-NEXT: mov w8, #135 +; CHECK-NEXT: mov w8, #135 // =0x87 ; CHECK-NEXT: and x8, x0, x8 ; CHECK-NEXT: cmp x8, #1024 ; CHECK-NEXT: cset w0, eq @@ -101,7 +101,7 @@ entry: define i8 @test7(i64 %a) { ; CHECK-LABEL: test7: ; CHECK: // %bb.0: // %entry -; CHECK-NEXT: mov w8, #1024 +; CHECK-NEXT: mov w8, #1024 // =0x400 ; CHECK-NEXT: movk w8, #33, lsl #16 ; CHECK-NEXT: and x8, x0, x8 ; CHECK-NEXT: cmp x8, #1024 @@ -175,7 +175,7 @@ define i32 @test9(ptr nocapture %x, ptr nocapture readonly %y, i32 %n) { ; CHECK-NEXT: cmp w2, #1 ; CHECK-NEXT: b.lt .LBB8_3 ; CHECK-NEXT: // %bb.1: // %for.body.preheader -; CHECK-NEXT: mov w9, #1024 +; CHECK-NEXT: mov w9, #1024 // =0x400 ; CHECK-NEXT: mov w8, w2 ; CHECK-NEXT: movk w9, #32, lsl #16 ; CHECK-NEXT: .LBB8_2: // %for.body @@ -226,7 +226,7 @@ define void @test10(ptr nocapture %x, ptr nocapture readonly %y, ptr nocapture % ; CHECK-LABEL: test10: ; CHECK: // %bb.0: // %entry ; CHECK-NEXT: ldr w8, [x1] -; CHECK-NEXT: mov w9, #1024 +; CHECK-NEXT: mov w9, #1024 // =0x400 ; CHECK-NEXT: movk w9, #32, lsl #16 ; CHECK-NEXT: and w8, w8, w9 ; CHECK-NEXT: str w8, [x0] @@ -253,7 +253,7 @@ entry: define i8 @test11(i64 %a) { ; CHECK-LABEL: test11: ; CHECK: // %bb.0: // %entry -; CHECK-NEXT: mov w8, #-1610612736 +; CHECK-NEXT: mov w8, #-1610612736 // =0xa0000000 ; CHECK-NEXT: and x8, x0, x8 ; CHECK-NEXT: cmp x8, #1024 ; CHECK-NEXT: cset w0, eq -- GitLab From 0fda758f26c1ec06809fdc067cd65dc146f867d0 Mon Sep 17 00:00:00 2001 From: Marc Auberer Date: Thu, 28 Mar 2024 01:19:09 +0100 Subject: [PATCH 004/788] [GISEL][NFC] Refactor OperandPredicateMatcher::isHigherPriorityThan (#86837) Fixes #86827 This will simplify code, de-duplicate some logic and fix the faulty bool compare. cc @dcb314 --- .../GlobalISel/GlobalISelMatchTable.cpp | 27 ++++++++----------- 1 file changed, 11 insertions(+), 16 deletions(-) diff --git a/llvm/utils/TableGen/Common/GlobalISel/GlobalISelMatchTable.cpp b/llvm/utils/TableGen/Common/GlobalISel/GlobalISelMatchTable.cpp index 193f95443b16..19d42b7688da 100644 --- a/llvm/utils/TableGen/Common/GlobalISel/GlobalISelMatchTable.cpp +++ b/llvm/utils/TableGen/Common/GlobalISel/GlobalISelMatchTable.cpp @@ -1077,30 +1077,25 @@ OperandPredicateMatcher::~OperandPredicateMatcher() {} bool OperandPredicateMatcher::isHigherPriorityThan( const OperandPredicateMatcher &B) const { // Generally speaking, an instruction is more important than an Int or a - // LiteralInt because it can cover more nodes but theres an exception to + // LiteralInt because it can cover more nodes but there's an exception to // this. G_CONSTANT's are less important than either of those two because they // are more permissive. - const InstructionOperandMatcher *AOM = - dyn_cast(this); - const InstructionOperandMatcher *BOM = - dyn_cast(&B); + const auto *AOM = dyn_cast(this); + const auto *BOM = dyn_cast(&B); bool AIsConstantInsn = AOM && AOM->getInsnMatcher().isConstantInstruction(); bool BIsConstantInsn = BOM && BOM->getInsnMatcher().isConstantInstruction(); - if (AOM && BOM) { - // The relative priorities between a G_CONSTANT and any other instruction - // don't actually matter but this code is needed to ensure a strict weak - // ordering. This is particularly important on Windows where the rules will - // be incorrectly sorted without it. - if (AIsConstantInsn != BIsConstantInsn) - return AIsConstantInsn < BIsConstantInsn; - return false; - } + // The relative priorities between a G_CONSTANT and any other instruction + // don't actually matter but this code is needed to ensure a strict weak + // ordering. This is particularly important on Windows where the rules will + // be incorrectly sorted without it. + if (AOM && BOM) + return !AIsConstantInsn && BIsConstantInsn; - if (AOM && AIsConstantInsn && (B.Kind == OPM_Int || B.Kind == OPM_LiteralInt)) + if (AIsConstantInsn && (B.Kind == OPM_Int || B.Kind == OPM_LiteralInt)) return false; - if (BOM && BIsConstantInsn && (Kind == OPM_Int || Kind == OPM_LiteralInt)) + if (BIsConstantInsn && (Kind == OPM_Int || Kind == OPM_LiteralInt)) return true; return Kind < B.Kind; -- GitLab From bbfa50696e43f337f55f8bacf739683b181debd5 Mon Sep 17 00:00:00 2001 From: alx32 <103613512+alx32@users.noreply.github.com> Date: Wed, 27 Mar 2024 17:27:51 -0700 Subject: [PATCH 005/788] [lld-macho] Fix bug in makeSyntheticInputSection when -dead_strip flag is specified (#86878) Previously, `makeSyntheticInputSection` would create a new `ConcatInputSection` without setting `live` explicitly for it. Without `-dead_strip` this would be OK since `live` would default to `true`. However, with `-dead_strip`, `live` would default to false, and it would remain set to `false`. This hasn't resulted in any issues so far since no code paths that exposed this issue were present. However a recent change - ObjC relative method lists (https://github.com/llvm/llvm-project/pull/86231) exposes this issue by creating relocations to the `SyntheticInputSection`. When these relocations are attempted to be written, this ends up with a crash(assert), since the `SyntheticInputSection` they refer to is marked as dead (`live` = `false`). With this change, we set the correct behavior - `live` will always be `true`. We add a test case that before this change would trigger an assert in the linker. --- lld/MachO/ConcatOutputSection.cpp | 6 +----- lld/MachO/InputSection.cpp | 3 +++ lld/MachO/InputSection.h | 1 + lld/MachO/SymbolTable.cpp | 2 +- lld/MachO/SyntheticSections.cpp | 2 +- lld/MachO/Writer.cpp | 4 +--- lld/test/MachO/objc-relative-method-lists-simple.s | 4 ++++ 7 files changed, 12 insertions(+), 10 deletions(-) diff --git a/lld/MachO/ConcatOutputSection.cpp b/lld/MachO/ConcatOutputSection.cpp index c5c0c8a89e28..279423720be9 100644 --- a/lld/MachO/ConcatOutputSection.cpp +++ b/lld/MachO/ConcatOutputSection.cpp @@ -323,11 +323,7 @@ void TextOutputSection::finalize() { thunkInfo.isec = makeSyntheticInputSection(isec->getSegName(), isec->getName()); thunkInfo.isec->parent = this; - - // This code runs after dead code removal. Need to set the `live` bit - // on the thunk isec so that asserts that check that only live sections - // get written are happy. - thunkInfo.isec->live = true; + assert(thunkInfo.isec->live); StringRef thunkName = saver().save(funcSym->getName() + ".thunk." + std::to_string(thunkInfo.sequence++)); diff --git a/lld/MachO/InputSection.cpp b/lld/MachO/InputSection.cpp index e3d7a400e4ce..5c1e07cd21b1 100644 --- a/lld/MachO/InputSection.cpp +++ b/lld/MachO/InputSection.cpp @@ -281,6 +281,9 @@ ConcatInputSection *macho::makeSyntheticInputSection(StringRef segName, Section §ion = *make
(/*file=*/nullptr, segName, sectName, flags, /*addr=*/0); auto isec = make(section, data, align); + // Since this is an explicitly created 'fake' input section, + // it should not be dead stripped. + isec->live = true; section.subsections.push_back({0, isec}); return isec; } diff --git a/lld/MachO/InputSection.h b/lld/MachO/InputSection.h index a0e6afef92cb..0f389e50425a 100644 --- a/lld/MachO/InputSection.h +++ b/lld/MachO/InputSection.h @@ -149,6 +149,7 @@ public: }; // Initialize a fake InputSection that does not belong to any InputFile. +// The created ConcatInputSection will always have 'live=true' ConcatInputSection *makeSyntheticInputSection(StringRef segName, StringRef sectName, uint32_t flags = 0, diff --git a/lld/MachO/SymbolTable.cpp b/lld/MachO/SymbolTable.cpp index 825242f2cc72..755ff270e2f7 100644 --- a/lld/MachO/SymbolTable.cpp +++ b/lld/MachO/SymbolTable.cpp @@ -377,7 +377,7 @@ static void handleSectionBoundarySymbol(const Undefined &sym, StringRef segSect, // live. Marking the isec live ensures an OutputSection is created that the // start/end symbol can refer to. assert(sym.isLive()); - isec->live = true; + assert(isec->live); // This runs after gatherInputSections(), so need to explicitly set parent // and add to inputSections. diff --git a/lld/MachO/SyntheticSections.cpp b/lld/MachO/SyntheticSections.cpp index 808ea8eac6eb..6f6b66118b7a 100644 --- a/lld/MachO/SyntheticSections.cpp +++ b/lld/MachO/SyntheticSections.cpp @@ -850,7 +850,7 @@ ConcatInputSection *ObjCSelRefsHelper::makeSelRef(StringRef methname) { S_LITERAL_POINTERS | S_ATTR_NO_DEAD_STRIP, ArrayRef{selrefData, wordSize}, /*align=*/wordSize); - objcSelref->live = true; + assert(objcSelref->live); objcSelref->relocs.push_back({/*type=*/target->unsignedRelocType, /*pcrel=*/false, /*length=*/3, /*offset=*/0, diff --git a/lld/MachO/Writer.cpp b/lld/MachO/Writer.cpp index fe989de648d7..1c054912551e 100644 --- a/lld/MachO/Writer.cpp +++ b/lld/MachO/Writer.cpp @@ -1375,9 +1375,7 @@ void macho::createSyntheticSections() { segment_names::data, section_names::data, S_REGULAR, ArrayRef{arr, target->wordSize}, /*align=*/target->wordSize); - // References from dyld are not visible to us, so ensure this section is - // always treated as live. - in.imageLoaderCache->live = true; + assert(in.imageLoaderCache->live); } OutputSection *macho::firstTLVDataSection = nullptr; diff --git a/lld/test/MachO/objc-relative-method-lists-simple.s b/lld/test/MachO/objc-relative-method-lists-simple.s index 1ffec3c6241c..5a77085c7d93 100644 --- a/lld/test/MachO/objc-relative-method-lists-simple.s +++ b/lld/test/MachO/objc-relative-method-lists-simple.s @@ -8,6 +8,10 @@ # RUN: %no-lsystem-lld a64_rel_dylib.o -o a64_rel_dylib.dylib -map a64_rel_dylib.map -dylib -arch arm64 -objc_relative_method_lists # RUN: llvm-objdump --macho --objc-meta-data a64_rel_dylib.dylib | FileCheck %s --check-prefix=CHK_REL +## Test arm64 + relative method lists + dead-strip +# RUN: %no-lsystem-lld a64_rel_dylib.o -o a64_rel_dylib.dylib -map a64_rel_dylib.map -dylib -arch arm64 -objc_relative_method_lists -dead_strip +# RUN: llvm-objdump --macho --objc-meta-data a64_rel_dylib.dylib | FileCheck %s --check-prefix=CHK_REL + ## Test arm64 + traditional method lists (no relative offsets) # RUN: %no-lsystem-lld a64_rel_dylib.o -o a64_rel_dylib.dylib -map a64_rel_dylib.map -dylib -arch arm64 -no_objc_relative_method_lists # RUN: llvm-objdump --macho --objc-meta-data a64_rel_dylib.dylib | FileCheck %s --check-prefix=CHK_NO_REL -- GitLab From cb898e26f3321e0b861609f5fec7f7410e5b6778 Mon Sep 17 00:00:00 2001 From: Kai Sasaki Date: Thu, 28 Mar 2024 09:40:17 +0900 Subject: [PATCH 006/788] [mlir] Make the print function in CRunnerUtil platform agnostic (#86767) The platform running on Apple Silicon does not seem to support the negative nan. It causes the test failure where we explicitly specify the negative nan bit pattern and check the output printed by the CRunnerUtil function. We can make the print function in the utility platform agnostic by using the standard library functions (i.e. `std::isnan` and `std::signbit`) so that we can run the test across platforms that do not support the negative bit pattern. I have added two test cases that would fail in the Apple Silicon platform without print function changes. ``` $ uname -a Darwin Kernel Version 23.3.0: Wed Dec 20 21:30:44 PST 2023; root:xnu-10002.81.5~7/RELEASE_ARM64_T6000 arm64 ``` See: https://discourse.llvm.org/t/test-failure-of-sparse-sign-test-in-apple-silicon/77876/3 --- mlir/lib/ExecutionEngine/CRunnerUtils.cpp | 16 ++++++++++++++-- .../test-expand-math-approx.mlir | 18 +++++++++++++++++- 2 files changed, 31 insertions(+), 3 deletions(-) diff --git a/mlir/lib/ExecutionEngine/CRunnerUtils.cpp b/mlir/lib/ExecutionEngine/CRunnerUtils.cpp index 48e4b8cd88b5..41c619566b55 100644 --- a/mlir/lib/ExecutionEngine/CRunnerUtils.cpp +++ b/mlir/lib/ExecutionEngine/CRunnerUtils.cpp @@ -51,8 +51,20 @@ void stdSort(uint64_t n, V *p) { // details of our vectors. Also useful for direct LLVM IR output. extern "C" void printI64(int64_t i) { fprintf(stdout, "%" PRId64, i); } extern "C" void printU64(uint64_t u) { fprintf(stdout, "%" PRIu64, u); } -extern "C" void printF32(float f) { fprintf(stdout, "%g", f); } -extern "C" void printF64(double d) { fprintf(stdout, "%lg", d); } +extern "C" void printF32(float f) { + if (std::isnan(f) && std::signbit(f)) { + fprintf(stdout, "-nan"); + } else { + fprintf(stdout, "%g", f); + } +} +extern "C" void printF64(double d) { + if (std::isnan(d) && std::signbit(d)) { + fprintf(stdout, "-nan"); + } else { + fprintf(stdout, "%lg", d); + } +} extern "C" void printString(char const *s) { fputs(s, stdout); } extern "C" void printOpen() { fputs("( ", stdout); } extern "C" void printClose() { fputs(" )", stdout); } diff --git a/mlir/test/mlir-cpu-runner/test-expand-math-approx.mlir b/mlir/test/mlir-cpu-runner/test-expand-math-approx.mlir index e2229a392bbf..340ef30bf59c 100644 --- a/mlir/test/mlir-cpu-runner/test-expand-math-approx.mlir +++ b/mlir/test/mlir-cpu-runner/test-expand-math-approx.mlir @@ -190,6 +190,12 @@ func.func @func_powff64(%a : f64, %b : f64) { return } +func.func @func_powff32(%a : f32, %b : f32) { + %r = math.powf %a, %b : f32 + vector.print %r : f32 + return +} + func.func @powf() { // CHECK-NEXT: 16 %a = arith.constant 4.0 : f64 @@ -230,7 +236,17 @@ func.func @powf() { %j = arith.constant 29385.0 : f64 %j_p = arith.constant 23598.0 : f64 call @func_powff64(%j, %j_p) : (f64, f64) -> () - return + + // CHECK-NEXT: -nan + %k = arith.constant 1.0 : f64 + %k_p = arith.constant 0xfff0000001000000 : f64 + call @func_powff64(%k, %k_p) : (f64, f64) -> () + + // CHECK-NEXT: -nan + %l = arith.constant 1.0 : f32 + %l_p = arith.constant 0xffffffff : f32 + call @func_powff32(%l, %l_p) : (f32, f32) -> () + return } // -------------------------------------------------------------------------- // -- GitLab From 17ab9e64464f989b3fe4a304a450581a618097a0 Mon Sep 17 00:00:00 2001 From: Vitaly Buka Date: Wed, 27 Mar 2024 17:44:49 -0700 Subject: [PATCH 007/788] [TSAN] Move test into Linux/ Linux specific test was introduced by #86537 --- compiler-rt/test/tsan/{ => Linux}/signal_in_futex_wait.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) rename compiler-rt/test/tsan/{ => Linux}/signal_in_futex_wait.cpp (99%) diff --git a/compiler-rt/test/tsan/signal_in_futex_wait.cpp b/compiler-rt/test/tsan/Linux/signal_in_futex_wait.cpp similarity index 99% rename from compiler-rt/test/tsan/signal_in_futex_wait.cpp rename to compiler-rt/test/tsan/Linux/signal_in_futex_wait.cpp index cf31e5467486..34d058edd526 100644 --- a/compiler-rt/test/tsan/signal_in_futex_wait.cpp +++ b/compiler-rt/test/tsan/Linux/signal_in_futex_wait.cpp @@ -1,6 +1,6 @@ // RUN: %clang_tsan %s -lstdc++ -o %t && %run %t 2>&1 | FileCheck %s -#include "test.h" +#include "../test.h" #include #include #include -- GitLab From 64f0410193490167aee186abf4de06b681476a86 Mon Sep 17 00:00:00 2001 From: Marc Auberer Date: Thu, 28 Mar 2024 02:03:24 +0100 Subject: [PATCH 008/788] [CI] Hotfix: CI runs failing due to target escaping (#86897) My patch #86877 contains a mistake. Should have read the comment. Recent buildkite runs fail because of this, so it is a bit urgent. --- .ci/monolithic-linux.sh | 2 +- .ci/monolithic-windows.sh | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/.ci/monolithic-linux.sh b/.ci/monolithic-linux.sh index 35f1aacb4985..b347c443da67 100755 --- a/.ci/monolithic-linux.sh +++ b/.ci/monolithic-linux.sh @@ -54,4 +54,4 @@ cmake -S "${MONOREPO_ROOT}"/llvm -B "${BUILD_DIR}" \ echo "--- ninja" # Targets are not escaped as they are passed as separate arguments. -ninja -C "${BUILD_DIR}" -k 0 "${targets}" +ninja -C "${BUILD_DIR}" -k 0 ${targets} diff --git a/.ci/monolithic-windows.sh b/.ci/monolithic-windows.sh index f84c0966704e..4fd88ea81c84 100755 --- a/.ci/monolithic-windows.sh +++ b/.ci/monolithic-windows.sh @@ -62,4 +62,4 @@ cmake -S "${MONOREPO_ROOT}"/llvm -B "${BUILD_DIR}" \ echo "--- ninja" # Targets are not escaped as they are passed as separate arguments. -ninja -C "${BUILD_DIR}" -k 0 "${targets}" +ninja -C "${BUILD_DIR}" -k 0 ${targets} -- GitLab From cc98ffb6dc6ca3e68fd939558eb8c4ddb1cc03de Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Naz=C4=B1m=20Can=20Alt=C4=B1nova?= Date: Thu, 28 Mar 2024 02:09:20 +0100 Subject: [PATCH 009/788] [tsan][test] Remove some unneded debug comments in a tsan test (#86896) I introduced this test in #86537, let's remove some unneeded debugging comments. This PR was initially also moving the test to linux directory but looks like it's already done by 17ab9e64464f989b3fe4a304a450581a618097a0 . --- compiler-rt/test/tsan/Linux/signal_in_futex_wait.cpp | 3 --- 1 file changed, 3 deletions(-) diff --git a/compiler-rt/test/tsan/Linux/signal_in_futex_wait.cpp b/compiler-rt/test/tsan/Linux/signal_in_futex_wait.cpp index 34d058edd526..3c8804aae3d0 100644 --- a/compiler-rt/test/tsan/Linux/signal_in_futex_wait.cpp +++ b/compiler-rt/test/tsan/Linux/signal_in_futex_wait.cpp @@ -57,16 +57,13 @@ private: Mutex mutex; void *Thread(void *x) { - // fprintf(stderr, "canova here thread 0\n"); // Waiting for the futex. mutex.lock(); - // fprintf(stderr, "canova here thread 1\n"); // Finished waiting. return nullptr; } static void SigprofHandler(int signal, siginfo_t *info, void *context) { - // fprintf(stderr, "canova here sigprof handler\n"); // Unlock the futex. mutex.unlock(); } -- GitLab From f75eebab887903567906d22e790a3be20a2a6438 Mon Sep 17 00:00:00 2001 From: Akira Hatanaka Date: Wed, 27 Mar 2024 18:14:04 -0700 Subject: [PATCH 010/788] Revert "[CodeGen][arm64e] Add methods and data members to Address, which are needed to authenticate signed pointers (#86721)" (#86898) This reverts commit d9a685a9dd589486e882b722e513ee7b8c84870c. The commit broke ubsan bots. --- clang/lib/CodeGen/ABIInfoImpl.cpp | 10 +- clang/lib/CodeGen/Address.h | 195 +++-------------- clang/lib/CodeGen/CGAtomic.cpp | 53 +++-- clang/lib/CodeGen/CGBlocks.cpp | 34 ++- clang/lib/CodeGen/CGBlocks.h | 3 +- clang/lib/CodeGen/CGBuilder.h | 234 +++++++-------------- clang/lib/CodeGen/CGBuiltin.cpp | 173 ++++++++------- clang/lib/CodeGen/CGCUDANV.cpp | 19 +- clang/lib/CodeGen/CGCXXABI.cpp | 21 +- clang/lib/CodeGen/CGCXXABI.h | 14 +- clang/lib/CodeGen/CGCall.cpp | 171 +++++++-------- clang/lib/CodeGen/CGCall.h | 1 - clang/lib/CodeGen/CGClass.cpp | 76 +++---- clang/lib/CodeGen/CGCleanup.cpp | 110 ++++++---- clang/lib/CodeGen/CGCleanup.h | 2 +- clang/lib/CodeGen/CGCoroutine.cpp | 4 +- clang/lib/CodeGen/CGDecl.cpp | 28 ++- clang/lib/CodeGen/CGException.cpp | 19 +- clang/lib/CodeGen/CGExpr.cpp | 227 ++++++++++---------- clang/lib/CodeGen/CGExprAgg.cpp | 29 ++- clang/lib/CodeGen/CGExprCXX.cpp | 111 +++++----- clang/lib/CodeGen/CGExprConstant.cpp | 4 +- clang/lib/CodeGen/CGExprScalar.cpp | 23 +- clang/lib/CodeGen/CGNonTrivialStruct.cpp | 8 +- clang/lib/CodeGen/CGObjC.cpp | 43 ++-- clang/lib/CodeGen/CGObjCGNU.cpp | 42 ++-- clang/lib/CodeGen/CGObjCMac.cpp | 95 +++++---- clang/lib/CodeGen/CGObjCRuntime.cpp | 6 +- clang/lib/CodeGen/CGOpenMPRuntime.cpp | 194 ++++++++--------- clang/lib/CodeGen/CGOpenMPRuntime.h | 5 +- clang/lib/CodeGen/CGOpenMPRuntimeGPU.cpp | 76 ++++--- clang/lib/CodeGen/CGStmt.cpp | 8 +- clang/lib/CodeGen/CGStmtOpenMP.cpp | 87 ++++---- clang/lib/CodeGen/CGVTables.cpp | 9 +- clang/lib/CodeGen/CGValue.h | 250 +++++++++++----------- clang/lib/CodeGen/CodeGenFunction.cpp | 71 +++---- clang/lib/CodeGen/CodeGenFunction.h | 257 +++++++---------------- clang/lib/CodeGen/CodeGenModule.cpp | 2 +- clang/lib/CodeGen/CodeGenPGO.cpp | 10 +- clang/lib/CodeGen/CodeGenPGO.h | 6 +- clang/lib/CodeGen/ItaniumCXXABI.cpp | 52 +++-- clang/lib/CodeGen/MicrosoftCXXABI.cpp | 58 +++-- clang/lib/CodeGen/TargetInfo.h | 5 - clang/lib/CodeGen/Targets/NVPTX.cpp | 2 +- clang/lib/CodeGen/Targets/PPC.cpp | 11 +- clang/lib/CodeGen/Targets/Sparc.cpp | 2 +- clang/lib/CodeGen/Targets/SystemZ.cpp | 9 +- clang/lib/CodeGen/Targets/XCore.cpp | 2 +- clang/utils/TableGen/MveEmitter.cpp | 2 +- llvm/include/llvm/IR/IRBuilder.h | 1 - 50 files changed, 1234 insertions(+), 1640 deletions(-) diff --git a/clang/lib/CodeGen/ABIInfoImpl.cpp b/clang/lib/CodeGen/ABIInfoImpl.cpp index 3e34d82cb399..dd59101ecc81 100644 --- a/clang/lib/CodeGen/ABIInfoImpl.cpp +++ b/clang/lib/CodeGen/ABIInfoImpl.cpp @@ -187,7 +187,7 @@ CodeGen::emitVoidPtrDirectVAArg(CodeGenFunction &CGF, Address VAListAddr, CharUnits FullDirectSize = DirectSize.alignTo(SlotSize); Address NextPtr = CGF.Builder.CreateConstInBoundsByteGEP(Addr, FullDirectSize, "argp.next"); - CGF.Builder.CreateStore(NextPtr.emitRawPointer(CGF), VAListAddr); + CGF.Builder.CreateStore(NextPtr.getPointer(), VAListAddr); // If the argument is smaller than a slot, and this is a big-endian // target, the argument will be right-adjusted in its slot. @@ -239,8 +239,8 @@ Address CodeGen::emitMergePHI(CodeGenFunction &CGF, Address Addr1, const llvm::Twine &Name) { assert(Addr1.getType() == Addr2.getType()); llvm::PHINode *PHI = CGF.Builder.CreatePHI(Addr1.getType(), 2, Name); - PHI->addIncoming(Addr1.emitRawPointer(CGF), Block1); - PHI->addIncoming(Addr2.emitRawPointer(CGF), Block2); + PHI->addIncoming(Addr1.getPointer(), Block1); + PHI->addIncoming(Addr2.getPointer(), Block2); CharUnits Align = std::min(Addr1.getAlignment(), Addr2.getAlignment()); return Address(PHI, Addr1.getElementType(), Align); } @@ -400,7 +400,7 @@ Address CodeGen::EmitVAArgInstr(CodeGenFunction &CGF, Address VAListAddr, llvm::Type *ElementTy = CGF.ConvertTypeForMem(Ty); llvm::Type *BaseTy = llvm::PointerType::getUnqual(ElementTy); llvm::Value *Addr = - CGF.Builder.CreateVAArg(VAListAddr.emitRawPointer(CGF), BaseTy); + CGF.Builder.CreateVAArg(VAListAddr.getPointer(), BaseTy); return Address(Addr, ElementTy, TyAlignForABI); } else { assert((AI.isDirect() || AI.isExtend()) && @@ -416,7 +416,7 @@ Address CodeGen::EmitVAArgInstr(CodeGenFunction &CGF, Address VAListAddr, "Unexpected CoerceToType seen in arginfo in generic VAArg emitter!"); Address Temp = CGF.CreateMemTemp(Ty, "varet"); - Val = CGF.Builder.CreateVAArg(VAListAddr.emitRawPointer(CGF), + Val = CGF.Builder.CreateVAArg(VAListAddr.getPointer(), CGF.ConvertTypeForMem(Ty)); CGF.Builder.CreateStore(Val, Temp); return Temp; diff --git a/clang/lib/CodeGen/Address.h b/clang/lib/CodeGen/Address.h index 35ec370a139c..cf48df8f5e73 100644 --- a/clang/lib/CodeGen/Address.h +++ b/clang/lib/CodeGen/Address.h @@ -15,7 +15,6 @@ #define LLVM_CLANG_LIB_CODEGEN_ADDRESS_H #include "clang/AST/CharUnits.h" -#include "clang/AST/Type.h" #include "llvm/ADT/PointerIntPair.h" #include "llvm/IR/Constants.h" #include "llvm/Support/MathExtras.h" @@ -23,41 +22,28 @@ namespace clang { namespace CodeGen { -class Address; -class CGBuilderTy; -class CodeGenFunction; -class CodeGenModule; - // Indicates whether a pointer is known not to be null. enum KnownNonNull_t { NotKnownNonNull, KnownNonNull }; -/// An abstract representation of an aligned address. This is designed to be an -/// IR-level abstraction, carrying just the information necessary to perform IR -/// operations on an address like loads and stores. In particular, it doesn't -/// carry C type information or allow the representation of things like -/// bit-fields; clients working at that level should generally be using -/// `LValue`. -/// The pointer contained in this class is known to be unsigned. -class RawAddress { +/// An aligned address. +class Address { llvm::PointerIntPair PointerAndKnownNonNull; llvm::Type *ElementType; CharUnits Alignment; protected: - RawAddress(std::nullptr_t) : ElementType(nullptr) {} + Address(std::nullptr_t) : ElementType(nullptr) {} public: - RawAddress(llvm::Value *Pointer, llvm::Type *ElementType, CharUnits Alignment, - KnownNonNull_t IsKnownNonNull = NotKnownNonNull) + Address(llvm::Value *Pointer, llvm::Type *ElementType, CharUnits Alignment, + KnownNonNull_t IsKnownNonNull = NotKnownNonNull) : PointerAndKnownNonNull(Pointer, IsKnownNonNull), ElementType(ElementType), Alignment(Alignment) { assert(Pointer != nullptr && "Pointer cannot be null"); assert(ElementType != nullptr && "Element type cannot be null"); } - inline RawAddress(Address Addr); - - static RawAddress invalid() { return RawAddress(nullptr); } + static Address invalid() { return Address(nullptr); } bool isValid() const { return PointerAndKnownNonNull.getPointer() != nullptr; } @@ -94,133 +80,6 @@ public: return Alignment; } - /// Return address with different element type, but same pointer and - /// alignment. - RawAddress withElementType(llvm::Type *ElemTy) const { - return RawAddress(getPointer(), ElemTy, getAlignment(), isKnownNonNull()); - } - - KnownNonNull_t isKnownNonNull() const { - assert(isValid()); - return (KnownNonNull_t)PointerAndKnownNonNull.getInt(); - } -}; - -/// Like RawAddress, an abstract representation of an aligned address, but the -/// pointer contained in this class is possibly signed. -class Address { - friend class CGBuilderTy; - - // The boolean flag indicates whether the pointer is known to be non-null. - llvm::PointerIntPair Pointer; - - /// The expected IR type of the pointer. Carrying accurate element type - /// information in Address makes it more convenient to work with Address - /// values and allows frontend assertions to catch simple mistakes. - llvm::Type *ElementType = nullptr; - - CharUnits Alignment; - - /// Offset from the base pointer. - llvm::Value *Offset = nullptr; - - llvm::Value *emitRawPointerSlow(CodeGenFunction &CGF) const; - -protected: - Address(std::nullptr_t) : ElementType(nullptr) {} - -public: - Address(llvm::Value *pointer, llvm::Type *elementType, CharUnits alignment, - KnownNonNull_t IsKnownNonNull = NotKnownNonNull) - : Pointer(pointer, IsKnownNonNull), ElementType(elementType), - Alignment(alignment) { - assert(pointer != nullptr && "Pointer cannot be null"); - assert(elementType != nullptr && "Element type cannot be null"); - assert(!alignment.isZero() && "Alignment cannot be zero"); - } - - Address(llvm::Value *BasePtr, llvm::Type *ElementType, CharUnits Alignment, - llvm::Value *Offset, KnownNonNull_t IsKnownNonNull = NotKnownNonNull) - : Pointer(BasePtr, IsKnownNonNull), ElementType(ElementType), - Alignment(Alignment), Offset(Offset) {} - - Address(RawAddress RawAddr) - : Pointer(RawAddr.isValid() ? RawAddr.getPointer() : nullptr), - ElementType(RawAddr.isValid() ? RawAddr.getElementType() : nullptr), - Alignment(RawAddr.isValid() ? RawAddr.getAlignment() - : CharUnits::Zero()) {} - - static Address invalid() { return Address(nullptr); } - bool isValid() const { return Pointer.getPointer() != nullptr; } - - /// This function is used in situations where the caller is doing some sort of - /// opaque "laundering" of the pointer. - void replaceBasePointer(llvm::Value *P) { - assert(isValid() && "pointer isn't valid"); - assert(P->getType() == Pointer.getPointer()->getType() && - "Pointer's type changed"); - Pointer.setPointer(P); - assert(isValid() && "pointer is invalid after replacement"); - } - - CharUnits getAlignment() const { return Alignment; } - - void setAlignment(CharUnits Value) { Alignment = Value; } - - llvm::Value *getBasePointer() const { - assert(isValid() && "pointer isn't valid"); - return Pointer.getPointer(); - } - - /// Return the type of the pointer value. - llvm::PointerType *getType() const { - return llvm::PointerType::get( - ElementType, - llvm::cast(Pointer.getPointer()->getType()) - ->getAddressSpace()); - } - - /// Return the type of the values stored in this address. - llvm::Type *getElementType() const { - assert(isValid()); - return ElementType; - } - - /// Return the address space that this address resides in. - unsigned getAddressSpace() const { return getType()->getAddressSpace(); } - - /// Return the IR name of the pointer value. - llvm::StringRef getName() const { return Pointer.getPointer()->getName(); } - - // This function is called only in CGBuilderBaseTy::CreateElementBitCast. - void setElementType(llvm::Type *Ty) { - assert(hasOffset() && - "this funcion shouldn't be called when there is no offset"); - ElementType = Ty; - } - - /// Whether the pointer is known not to be null. - KnownNonNull_t isKnownNonNull() const { - assert(isValid()); - return (KnownNonNull_t)Pointer.getInt(); - } - - Address setKnownNonNull() { - assert(isValid()); - Pointer.setInt(KnownNonNull); - return *this; - } - - bool hasOffset() const { return Offset; } - - llvm::Value *getOffset() const { return Offset; } - - /// Return the pointer contained in this class after authenticating it and - /// adding offset to it if necessary. - llvm::Value *emitRawPointer(CodeGenFunction &CGF) const { - return getBasePointer(); - } - /// Return address with different pointer, but same element type and /// alignment. Address withPointer(llvm::Value *NewPointer, @@ -232,59 +91,61 @@ public: /// Return address with different alignment, but same pointer and element /// type. Address withAlignment(CharUnits NewAlignment) const { - return Address(Pointer.getPointer(), getElementType(), NewAlignment, + return Address(getPointer(), getElementType(), NewAlignment, isKnownNonNull()); } /// Return address with different element type, but same pointer and /// alignment. Address withElementType(llvm::Type *ElemTy) const { - if (!hasOffset()) - return Address(getBasePointer(), ElemTy, getAlignment(), nullptr, - isKnownNonNull()); - Address A(*this); - A.ElementType = ElemTy; - return A; + return Address(getPointer(), ElemTy, getAlignment(), isKnownNonNull()); } -}; -inline RawAddress::RawAddress(Address Addr) - : PointerAndKnownNonNull(Addr.isValid() ? Addr.getBasePointer() : nullptr, - Addr.isValid() ? Addr.isKnownNonNull() - : NotKnownNonNull), - ElementType(Addr.isValid() ? Addr.getElementType() : nullptr), - Alignment(Addr.isValid() ? Addr.getAlignment() : CharUnits::Zero()) {} + /// Whether the pointer is known not to be null. + KnownNonNull_t isKnownNonNull() const { + assert(isValid()); + return (KnownNonNull_t)PointerAndKnownNonNull.getInt(); + } + + /// Set the non-null bit. + Address setKnownNonNull() { + assert(isValid()); + PointerAndKnownNonNull.setInt(true); + return *this; + } +}; /// A specialization of Address that requires the address to be an /// LLVM Constant. -class ConstantAddress : public RawAddress { - ConstantAddress(std::nullptr_t) : RawAddress(nullptr) {} +class ConstantAddress : public Address { + ConstantAddress(std::nullptr_t) : Address(nullptr) {} public: ConstantAddress(llvm::Constant *pointer, llvm::Type *elementType, CharUnits alignment) - : RawAddress(pointer, elementType, alignment) {} + : Address(pointer, elementType, alignment) {} static ConstantAddress invalid() { return ConstantAddress(nullptr); } llvm::Constant *getPointer() const { - return llvm::cast(RawAddress::getPointer()); + return llvm::cast(Address::getPointer()); } ConstantAddress withElementType(llvm::Type *ElemTy) const { return ConstantAddress(getPointer(), ElemTy, getAlignment()); } - static bool isaImpl(RawAddress addr) { + static bool isaImpl(Address addr) { return llvm::isa(addr.getPointer()); } - static ConstantAddress castImpl(RawAddress addr) { + static ConstantAddress castImpl(Address addr) { return ConstantAddress(llvm::cast(addr.getPointer()), addr.getElementType(), addr.getAlignment()); } }; + } // Present a minimal LLVM-like casting interface. diff --git a/clang/lib/CodeGen/CGAtomic.cpp b/clang/lib/CodeGen/CGAtomic.cpp index 56198385de9d..fb03d013e8af 100644 --- a/clang/lib/CodeGen/CGAtomic.cpp +++ b/clang/lib/CodeGen/CGAtomic.cpp @@ -80,7 +80,7 @@ namespace { AtomicSizeInBits = C.toBits( C.toCharUnitsFromBits(Offset + OrigBFI.Size + C.getCharWidth() - 1) .alignTo(lvalue.getAlignment())); - llvm::Value *BitFieldPtr = lvalue.getRawBitFieldPointer(CGF); + llvm::Value *BitFieldPtr = lvalue.getBitFieldPointer(); auto OffsetInChars = (C.toCharUnitsFromBits(OrigBFI.Offset) / lvalue.getAlignment()) * lvalue.getAlignment(); @@ -139,13 +139,13 @@ namespace { const LValue &getAtomicLValue() const { return LVal; } llvm::Value *getAtomicPointer() const { if (LVal.isSimple()) - return LVal.emitRawPointer(CGF); + return LVal.getPointer(CGF); else if (LVal.isBitField()) - return LVal.getRawBitFieldPointer(CGF); + return LVal.getBitFieldPointer(); else if (LVal.isVectorElt()) - return LVal.getRawVectorPointer(CGF); + return LVal.getVectorPointer(); assert(LVal.isExtVectorElt()); - return LVal.getRawExtVectorPointer(CGF); + return LVal.getExtVectorPointer(); } Address getAtomicAddress() const { llvm::Type *ElTy; @@ -368,7 +368,7 @@ bool AtomicInfo::emitMemSetZeroIfNecessary() const { return false; CGF.Builder.CreateMemSet( - addr.emitRawPointer(CGF), llvm::ConstantInt::get(CGF.Int8Ty, 0), + addr.getPointer(), llvm::ConstantInt::get(CGF.Int8Ty, 0), CGF.getContext().toCharUnitsFromBits(AtomicSizeInBits).getQuantity(), LVal.getAlignment().getAsAlign()); return true; @@ -1055,8 +1055,7 @@ RValue CodeGenFunction::EmitAtomicExpr(AtomicExpr *E) { return getTargetHooks().performAddrSpaceCast( *this, V, AS, LangAS::opencl_generic, DestType, false); }; - - Args.add(RValue::get(CastToGenericAddrSpace(Ptr.emitRawPointer(*this), + Args.add(RValue::get(CastToGenericAddrSpace(Ptr.getPointer(), E->getPtr()->getType())), getContext().VoidPtrTy); @@ -1087,10 +1086,10 @@ RValue CodeGenFunction::EmitAtomicExpr(AtomicExpr *E) { LibCallName = "__atomic_compare_exchange"; RetTy = getContext().BoolTy; HaveRetTy = true; - Args.add(RValue::get(CastToGenericAddrSpace(Val1.emitRawPointer(*this), + Args.add(RValue::get(CastToGenericAddrSpace(Val1.getPointer(), E->getVal1()->getType())), getContext().VoidPtrTy); - Args.add(RValue::get(CastToGenericAddrSpace(Val2.emitRawPointer(*this), + Args.add(RValue::get(CastToGenericAddrSpace(Val2.getPointer(), E->getVal2()->getType())), getContext().VoidPtrTy); Args.add(RValue::get(Order), getContext().IntTy); @@ -1106,7 +1105,7 @@ RValue CodeGenFunction::EmitAtomicExpr(AtomicExpr *E) { case AtomicExpr::AO__scoped_atomic_exchange: case AtomicExpr::AO__scoped_atomic_exchange_n: LibCallName = "__atomic_exchange"; - Args.add(RValue::get(CastToGenericAddrSpace(Val1.emitRawPointer(*this), + Args.add(RValue::get(CastToGenericAddrSpace(Val1.getPointer(), E->getVal1()->getType())), getContext().VoidPtrTy); break; @@ -1121,7 +1120,7 @@ RValue CodeGenFunction::EmitAtomicExpr(AtomicExpr *E) { LibCallName = "__atomic_store"; RetTy = getContext().VoidTy; HaveRetTy = true; - Args.add(RValue::get(CastToGenericAddrSpace(Val1.emitRawPointer(*this), + Args.add(RValue::get(CastToGenericAddrSpace(Val1.getPointer(), E->getVal1()->getType())), getContext().VoidPtrTy); break; @@ -1200,8 +1199,7 @@ RValue CodeGenFunction::EmitAtomicExpr(AtomicExpr *E) { if (!HaveRetTy) { // Value is returned through parameter before the order. RetTy = getContext().VoidTy; - Args.add(RValue::get( - CastToGenericAddrSpace(Dest.emitRawPointer(*this), RetTy)), + Args.add(RValue::get(CastToGenericAddrSpace(Dest.getPointer(), RetTy)), getContext().VoidPtrTy); } // Order is always the last parameter. @@ -1515,7 +1513,7 @@ RValue AtomicInfo::EmitAtomicLoad(AggValueSlot ResultSlot, SourceLocation Loc, } else TempAddr = CreateTempAlloca(); - EmitAtomicLoadLibcall(TempAddr.emitRawPointer(CGF), AO, IsVolatile); + EmitAtomicLoadLibcall(TempAddr.getPointer(), AO, IsVolatile); // Okay, turn that back into the original value or whole atomic (for // non-simple lvalues) type. @@ -1675,9 +1673,9 @@ std::pair AtomicInfo::EmitAtomicCompareExchange( if (shouldUseLibcall()) { // Produce a source address. Address ExpectedAddr = materializeRValue(Expected); - llvm::Value *ExpectedPtr = ExpectedAddr.emitRawPointer(CGF); - llvm::Value *DesiredPtr = materializeRValue(Desired).emitRawPointer(CGF); - auto *Res = EmitAtomicCompareExchangeLibcall(ExpectedPtr, DesiredPtr, + Address DesiredAddr = materializeRValue(Desired); + auto *Res = EmitAtomicCompareExchangeLibcall(ExpectedAddr.getPointer(), + DesiredAddr.getPointer(), Success, Failure); return std::make_pair( convertAtomicTempToRValue(ExpectedAddr, AggValueSlot::ignored(), @@ -1759,7 +1757,7 @@ void AtomicInfo::EmitAtomicUpdateLibcall( Address ExpectedAddr = CreateTempAlloca(); - EmitAtomicLoadLibcall(ExpectedAddr.emitRawPointer(CGF), AO, IsVolatile); + EmitAtomicLoadLibcall(ExpectedAddr.getPointer(), AO, IsVolatile); auto *ContBB = CGF.createBasicBlock("atomic_cont"); auto *ExitBB = CGF.createBasicBlock("atomic_exit"); CGF.EmitBlock(ContBB); @@ -1773,10 +1771,10 @@ void AtomicInfo::EmitAtomicUpdateLibcall( AggValueSlot::ignored(), SourceLocation(), /*AsValue=*/false); EmitAtomicUpdateValue(CGF, *this, OldRVal, UpdateOp, DesiredAddr); - llvm::Value *ExpectedPtr = ExpectedAddr.emitRawPointer(CGF); - llvm::Value *DesiredPtr = DesiredAddr.emitRawPointer(CGF); auto *Res = - EmitAtomicCompareExchangeLibcall(ExpectedPtr, DesiredPtr, AO, Failure); + EmitAtomicCompareExchangeLibcall(ExpectedAddr.getPointer(), + DesiredAddr.getPointer(), + AO, Failure); CGF.Builder.CreateCondBr(Res, ExitBB, ContBB); CGF.EmitBlock(ExitBB, /*IsFinished=*/true); } @@ -1845,7 +1843,7 @@ void AtomicInfo::EmitAtomicUpdateLibcall(llvm::AtomicOrdering AO, Address ExpectedAddr = CreateTempAlloca(); - EmitAtomicLoadLibcall(ExpectedAddr.emitRawPointer(CGF), AO, IsVolatile); + EmitAtomicLoadLibcall(ExpectedAddr.getPointer(), AO, IsVolatile); auto *ContBB = CGF.createBasicBlock("atomic_cont"); auto *ExitBB = CGF.createBasicBlock("atomic_exit"); CGF.EmitBlock(ContBB); @@ -1856,10 +1854,10 @@ void AtomicInfo::EmitAtomicUpdateLibcall(llvm::AtomicOrdering AO, CGF.Builder.CreateStore(OldVal, DesiredAddr); } EmitAtomicUpdateValue(CGF, *this, UpdateRVal, DesiredAddr); - llvm::Value *ExpectedPtr = ExpectedAddr.emitRawPointer(CGF); - llvm::Value *DesiredPtr = DesiredAddr.emitRawPointer(CGF); auto *Res = - EmitAtomicCompareExchangeLibcall(ExpectedPtr, DesiredPtr, AO, Failure); + EmitAtomicCompareExchangeLibcall(ExpectedAddr.getPointer(), + DesiredAddr.getPointer(), + AO, Failure); CGF.Builder.CreateCondBr(Res, ExitBB, ContBB); CGF.EmitBlock(ExitBB, /*IsFinished=*/true); } @@ -1959,8 +1957,7 @@ void CodeGenFunction::EmitAtomicStore(RValue rvalue, LValue dest, args.add(RValue::get(atomics.getAtomicSizeValue()), getContext().getSizeType()); args.add(RValue::get(atomics.getAtomicPointer()), getContext().VoidPtrTy); - args.add(RValue::get(srcAddr.emitRawPointer(*this)), - getContext().VoidPtrTy); + args.add(RValue::get(srcAddr.getPointer()), getContext().VoidPtrTy); args.add( RValue::get(llvm::ConstantInt::get(IntTy, (int)llvm::toCABI(AO))), getContext().IntTy); diff --git a/clang/lib/CodeGen/CGBlocks.cpp b/clang/lib/CodeGen/CGBlocks.cpp index a01f2c7c9798..ad0b50d79961 100644 --- a/clang/lib/CodeGen/CGBlocks.cpp +++ b/clang/lib/CodeGen/CGBlocks.cpp @@ -36,8 +36,7 @@ CGBlockInfo::CGBlockInfo(const BlockDecl *block, StringRef name) : Name(name), CXXThisIndex(0), CanBeGlobal(false), NeedsCopyDispose(false), NoEscape(false), HasCXXObject(false), UsesStret(false), HasCapturedVariableLayout(false), CapturesNonExternalType(false), - LocalAddress(RawAddress::invalid()), StructureType(nullptr), - Block(block) { + LocalAddress(Address::invalid()), StructureType(nullptr), Block(block) { // Skip asm prefix, if any. 'name' is usually taken directly from // the mangled name of the enclosing function. @@ -795,7 +794,7 @@ llvm::Value *CodeGenFunction::EmitBlockLiteral(const CGBlockInfo &blockInfo) { // Otherwise, we have to emit this as a local block. - RawAddress blockAddr = blockInfo.LocalAddress; + Address blockAddr = blockInfo.LocalAddress; assert(blockAddr.isValid() && "block has no address!"); llvm::Constant *isa; @@ -940,7 +939,7 @@ llvm::Value *CodeGenFunction::EmitBlockLiteral(const CGBlockInfo &blockInfo) { if (CI.isNested()) byrefPointer = Builder.CreateLoad(src, "byref.capture"); else - byrefPointer = src.emitRawPointer(*this); + byrefPointer = src.getPointer(); // Write that void* into the capture field. Builder.CreateStore(byrefPointer, blockField); @@ -962,10 +961,10 @@ llvm::Value *CodeGenFunction::EmitBlockLiteral(const CGBlockInfo &blockInfo) { } // If it's a reference variable, copy the reference into the block field. - } else if (auto refType = type->getAs()) { - Builder.CreateStore(src.emitRawPointer(*this), blockField); + } else if (type->isReferenceType()) { + Builder.CreateStore(src.getPointer(), blockField); - // If type is const-qualified, copy the value into the block field. + // If type is const-qualified, copy the value into the block field. } else if (type.isConstQualified() && type.getObjCLifetime() == Qualifiers::OCL_Strong && CGM.getCodeGenOpts().OptimizationLevel != 0) { @@ -1378,7 +1377,7 @@ void CodeGenFunction::setBlockContextParameter(const ImplicitParamDecl *D, // Allocate a stack slot like for any local variable to guarantee optimal // debug info at -O0. The mem2reg pass will eliminate it when optimizing. - RawAddress alloc = CreateMemTemp(D->getType(), D->getName() + ".addr"); + Address alloc = CreateMemTemp(D->getType(), D->getName() + ".addr"); Builder.CreateStore(arg, alloc); if (CGDebugInfo *DI = getDebugInfo()) { if (CGM.getCodeGenOpts().hasReducedDebugInfo()) { @@ -1498,7 +1497,7 @@ llvm::Function *CodeGenFunction::GenerateBlockFunction( // frame setup instruction by llvm::DwarfDebug::beginFunction(). auto NL = ApplyDebugLocation::CreateEmpty(*this); Builder.CreateStore(BlockPointer, Alloca); - BlockPointerDbgLoc = Alloca.emitRawPointer(*this); + BlockPointerDbgLoc = Alloca.getPointer(); } // If we have a C++ 'this' reference, go ahead and force it into @@ -1558,8 +1557,8 @@ llvm::Function *CodeGenFunction::GenerateBlockFunction( const CGBlockInfo::Capture &capture = blockInfo.getCapture(variable); if (capture.isConstant()) { auto addr = LocalDeclMap.find(variable)->second; - (void)DI->EmitDeclareOfAutoVariable( - variable, addr.emitRawPointer(*this), Builder); + (void)DI->EmitDeclareOfAutoVariable(variable, addr.getPointer(), + Builder); continue; } @@ -1663,7 +1662,7 @@ struct CallBlockRelease final : EHScopeStack::Cleanup { if (LoadBlockVarAddr) { BlockVarAddr = CGF.Builder.CreateLoad(Addr); } else { - BlockVarAddr = Addr.emitRawPointer(CGF); + BlockVarAddr = Addr.getPointer(); } CGF.BuildBlockRelease(BlockVarAddr, FieldFlags, CanThrow); @@ -1963,15 +1962,13 @@ CodeGenFunction::GenerateCopyHelperFunction(const CGBlockInfo &blockInfo) { // it. It's not quite worth the annoyance to avoid creating it in the // first place. if (!needsEHCleanup(captureType.isDestructedType())) - if (auto *I = - cast_or_null(dstField.getBasePointer())) - I->eraseFromParent(); + cast(dstField.getPointer())->eraseFromParent(); } break; } case BlockCaptureEntityKind::BlockObject: { llvm::Value *srcValue = Builder.CreateLoad(srcField, "blockcopy.src"); - llvm::Value *dstAddr = dstField.emitRawPointer(*this); + llvm::Value *dstAddr = dstField.getPointer(); llvm::Value *args[] = { dstAddr, srcValue, llvm::ConstantInt::get(Int32Ty, flags.getBitMask()) }; @@ -2142,7 +2139,7 @@ public: llvm::Value *flagsVal = llvm::ConstantInt::get(CGF.Int32Ty, flags); llvm::FunctionCallee fn = CGF.CGM.getBlockObjectAssign(); - llvm::Value *args[] = {destField.emitRawPointer(CGF), srcValue, flagsVal}; + llvm::Value *args[] = { destField.getPointer(), srcValue, flagsVal }; CGF.EmitNounwindRuntimeCall(fn, args); } @@ -2699,8 +2696,7 @@ void CodeGenFunction::emitByrefStructureInit(const AutoVarEmission &emission) { storeHeaderField(V, getPointerSize(), "byref.isa"); // Store the address of the variable into its own forwarding pointer. - storeHeaderField(addr.emitRawPointer(*this), getPointerSize(), - "byref.forwarding"); + storeHeaderField(addr.getPointer(), getPointerSize(), "byref.forwarding"); // Blocks ABI: // c) the flags field is set to either 0 if no helper functions are diff --git a/clang/lib/CodeGen/CGBlocks.h b/clang/lib/CodeGen/CGBlocks.h index 8d10c4f69b20..4ef1ae9f3365 100644 --- a/clang/lib/CodeGen/CGBlocks.h +++ b/clang/lib/CodeGen/CGBlocks.h @@ -271,8 +271,7 @@ public: /// The block's captures. Non-constant captures are sorted by their offsets. llvm::SmallVector SortedCaptures; - // Currently we assume that block-pointer types are never signed. - RawAddress LocalAddress; + Address LocalAddress; llvm::StructType *StructureType; const BlockDecl *Block; const BlockExpr *BlockExpression; diff --git a/clang/lib/CodeGen/CGBuilder.h b/clang/lib/CodeGen/CGBuilder.h index 6dd9da7c4cad..bf5ab171d720 100644 --- a/clang/lib/CodeGen/CGBuilder.h +++ b/clang/lib/CodeGen/CGBuilder.h @@ -10,9 +10,7 @@ #define LLVM_CLANG_LIB_CODEGEN_CGBUILDER_H #include "Address.h" -#include "CGValue.h" #include "CodeGenTypeCache.h" -#include "llvm/Analysis/Utils/Local.h" #include "llvm/IR/DataLayout.h" #include "llvm/IR/IRBuilder.h" #include "llvm/IR/Type.h" @@ -20,15 +18,12 @@ namespace clang { namespace CodeGen { -class CGBuilderTy; class CodeGenFunction; /// This is an IRBuilder insertion helper that forwards to /// CodeGenFunction::InsertHelper, which adds necessary metadata to /// instructions. class CGBuilderInserter final : public llvm::IRBuilderDefaultInserter { - friend CGBuilderTy; - public: CGBuilderInserter() = default; explicit CGBuilderInserter(CodeGenFunction *CGF) : CGF(CGF) {} @@ -48,42 +43,10 @@ typedef llvm::IRBuilder CGBuilderBaseTy; class CGBuilderTy : public CGBuilderBaseTy { - friend class Address; - /// Storing a reference to the type cache here makes it a lot easier /// to build natural-feeling, target-specific IR. const CodeGenTypeCache &TypeCache; - CodeGenFunction *getCGF() const { return getInserter().CGF; } - - llvm::Value *emitRawPointerFromAddress(Address Addr) const { - return Addr.getBasePointer(); - } - - template - Address createConstGEP2_32(Address Addr, unsigned Idx0, unsigned Idx1, - const llvm::Twine &Name) { - const llvm::DataLayout &DL = BB->getParent()->getParent()->getDataLayout(); - llvm::GetElementPtrInst *GEP; - if (IsInBounds) - GEP = cast(CreateConstInBoundsGEP2_32( - Addr.getElementType(), emitRawPointerFromAddress(Addr), Idx0, Idx1, - Name)); - else - GEP = cast(CreateConstGEP2_32( - Addr.getElementType(), emitRawPointerFromAddress(Addr), Idx0, Idx1, - Name)); - llvm::APInt Offset( - DL.getIndexSizeInBits(Addr.getType()->getPointerAddressSpace()), 0, - /*isSigned=*/true); - if (!GEP->accumulateConstantOffset(DL, Offset)) - llvm_unreachable("offset of GEP with constants is always computable"); - return Address(GEP, GEP->getResultElementType(), - Addr.getAlignment().alignmentAtOffset( - CharUnits::fromQuantity(Offset.getSExtValue())), - IsInBounds ? Addr.isKnownNonNull() : NotKnownNonNull); - } - public: CGBuilderTy(const CodeGenTypeCache &TypeCache, llvm::LLVMContext &C) : CGBuilderBaseTy(C), TypeCache(TypeCache) {} @@ -106,22 +69,20 @@ public: // Note that we intentionally hide the CreateLoad APIs that don't // take an alignment. llvm::LoadInst *CreateLoad(Address Addr, const llvm::Twine &Name = "") { - return CreateAlignedLoad(Addr.getElementType(), - emitRawPointerFromAddress(Addr), + return CreateAlignedLoad(Addr.getElementType(), Addr.getPointer(), Addr.getAlignment().getAsAlign(), Name); } llvm::LoadInst *CreateLoad(Address Addr, const char *Name) { // This overload is required to prevent string literals from // ending up in the IsVolatile overload. - return CreateAlignedLoad(Addr.getElementType(), - emitRawPointerFromAddress(Addr), + return CreateAlignedLoad(Addr.getElementType(), Addr.getPointer(), Addr.getAlignment().getAsAlign(), Name); } llvm::LoadInst *CreateLoad(Address Addr, bool IsVolatile, const llvm::Twine &Name = "") { - return CreateAlignedLoad( - Addr.getElementType(), emitRawPointerFromAddress(Addr), - Addr.getAlignment().getAsAlign(), IsVolatile, Name); + return CreateAlignedLoad(Addr.getElementType(), Addr.getPointer(), + Addr.getAlignment().getAsAlign(), IsVolatile, + Name); } using CGBuilderBaseTy::CreateAlignedLoad; @@ -135,7 +96,7 @@ public: // take an alignment. llvm::StoreInst *CreateStore(llvm::Value *Val, Address Addr, bool IsVolatile = false) { - return CreateAlignedStore(Val, emitRawPointerFromAddress(Addr), + return CreateAlignedStore(Val, Addr.getPointer(), Addr.getAlignment().getAsAlign(), IsVolatile); } @@ -171,41 +132,33 @@ public: llvm::AtomicOrdering FailureOrdering, llvm::SyncScope::ID SSID = llvm::SyncScope::System) { return CGBuilderBaseTy::CreateAtomicCmpXchg( - Addr.emitRawPointer(*getCGF()), Cmp, New, - Addr.getAlignment().getAsAlign(), SuccessOrdering, FailureOrdering, - SSID); + Addr.getPointer(), Cmp, New, Addr.getAlignment().getAsAlign(), + SuccessOrdering, FailureOrdering, SSID); } llvm::AtomicRMWInst * CreateAtomicRMW(llvm::AtomicRMWInst::BinOp Op, Address Addr, llvm::Value *Val, llvm::AtomicOrdering Ordering, llvm::SyncScope::ID SSID = llvm::SyncScope::System) { - return CGBuilderBaseTy::CreateAtomicRMW( - Op, Addr.emitRawPointer(*getCGF()), Val, - Addr.getAlignment().getAsAlign(), Ordering, SSID); + return CGBuilderBaseTy::CreateAtomicRMW(Op, Addr.getPointer(), Val, + Addr.getAlignment().getAsAlign(), + Ordering, SSID); } using CGBuilderBaseTy::CreateAddrSpaceCast; Address CreateAddrSpaceCast(Address Addr, llvm::Type *Ty, - llvm::Type *ElementTy, const llvm::Twine &Name = "") { - if (!Addr.hasOffset()) - return Address(CreateAddrSpaceCast(Addr.getBasePointer(), Ty, Name), - ElementTy, Addr.getAlignment(), nullptr, - Addr.isKnownNonNull()); - // Eagerly force a raw address if these is an offset. - return RawAddress( - CreateAddrSpaceCast(Addr.emitRawPointer(*getCGF()), Ty, Name), - ElementTy, Addr.getAlignment(), Addr.isKnownNonNull()); + return Addr.withPointer(CreateAddrSpaceCast(Addr.getPointer(), Ty, Name), + Addr.isKnownNonNull()); } using CGBuilderBaseTy::CreatePointerBitCastOrAddrSpaceCast; Address CreatePointerBitCastOrAddrSpaceCast(Address Addr, llvm::Type *Ty, llvm::Type *ElementTy, const llvm::Twine &Name = "") { - if (Addr.getType()->getAddressSpace() == Ty->getPointerAddressSpace()) - return Addr.withElementType(ElementTy); - return CreateAddrSpaceCast(Addr, Ty, ElementTy, Name); + llvm::Value *Ptr = + CreatePointerBitCastOrAddrSpaceCast(Addr.getPointer(), Ty, Name); + return Address(Ptr, ElementTy, Addr.getAlignment(), Addr.isKnownNonNull()); } /// Given @@ -223,11 +176,10 @@ public: const llvm::StructLayout *Layout = DL.getStructLayout(ElTy); auto Offset = CharUnits::fromQuantity(Layout->getElementOffset(Index)); - return Address(CreateStructGEP(Addr.getElementType(), Addr.getBasePointer(), - Index, Name), - ElTy->getElementType(Index), - Addr.getAlignment().alignmentAtOffset(Offset), - Addr.isKnownNonNull()); + return Address( + CreateStructGEP(Addr.getElementType(), Addr.getPointer(), Index, Name), + ElTy->getElementType(Index), + Addr.getAlignment().alignmentAtOffset(Offset), Addr.isKnownNonNull()); } /// Given @@ -246,7 +198,7 @@ public: CharUnits::fromQuantity(DL.getTypeAllocSize(ElTy->getElementType())); return Address( - CreateInBoundsGEP(Addr.getElementType(), Addr.getBasePointer(), + CreateInBoundsGEP(Addr.getElementType(), Addr.getPointer(), {getSize(CharUnits::Zero()), getSize(Index)}, Name), ElTy->getElementType(), Addr.getAlignment().alignmentAtOffset(Index * EltSize), @@ -264,10 +216,10 @@ public: const llvm::DataLayout &DL = BB->getParent()->getParent()->getDataLayout(); CharUnits EltSize = CharUnits::fromQuantity(DL.getTypeAllocSize(ElTy)); - return Address( - CreateInBoundsGEP(ElTy, Addr.getBasePointer(), getSize(Index), Name), - ElTy, Addr.getAlignment().alignmentAtOffset(Index * EltSize), - Addr.isKnownNonNull()); + return Address(CreateInBoundsGEP(Addr.getElementType(), Addr.getPointer(), + getSize(Index), Name), + ElTy, Addr.getAlignment().alignmentAtOffset(Index * EltSize), + Addr.isKnownNonNull()); } /// Given @@ -277,133 +229,110 @@ public: /// where i64 is actually the target word size. Address CreateConstGEP(Address Addr, uint64_t Index, const llvm::Twine &Name = "") { - llvm::Type *ElTy = Addr.getElementType(); const llvm::DataLayout &DL = BB->getParent()->getParent()->getDataLayout(); - CharUnits EltSize = CharUnits::fromQuantity(DL.getTypeAllocSize(ElTy)); + CharUnits EltSize = + CharUnits::fromQuantity(DL.getTypeAllocSize(Addr.getElementType())); - return Address(CreateGEP(ElTy, Addr.getBasePointer(), getSize(Index), Name), + return Address(CreateGEP(Addr.getElementType(), Addr.getPointer(), + getSize(Index), Name), Addr.getElementType(), - Addr.getAlignment().alignmentAtOffset(Index * EltSize)); + Addr.getAlignment().alignmentAtOffset(Index * EltSize), + NotKnownNonNull); } /// Create GEP with single dynamic index. The address alignment is reduced /// according to the element size. using CGBuilderBaseTy::CreateGEP; - Address CreateGEP(CodeGenFunction &CGF, Address Addr, llvm::Value *Index, + Address CreateGEP(Address Addr, llvm::Value *Index, const llvm::Twine &Name = "") { const llvm::DataLayout &DL = BB->getParent()->getParent()->getDataLayout(); CharUnits EltSize = CharUnits::fromQuantity(DL.getTypeAllocSize(Addr.getElementType())); return Address( - CreateGEP(Addr.getElementType(), Addr.emitRawPointer(CGF), Index, Name), + CreateGEP(Addr.getElementType(), Addr.getPointer(), Index, Name), Addr.getElementType(), - Addr.getAlignment().alignmentOfArrayElement(EltSize)); + Addr.getAlignment().alignmentOfArrayElement(EltSize), NotKnownNonNull); } /// Given a pointer to i8, adjust it by a given constant offset. Address CreateConstInBoundsByteGEP(Address Addr, CharUnits Offset, const llvm::Twine &Name = "") { assert(Addr.getElementType() == TypeCache.Int8Ty); - return Address( - CreateInBoundsGEP(Addr.getElementType(), Addr.getBasePointer(), - getSize(Offset), Name), - Addr.getElementType(), Addr.getAlignment().alignmentAtOffset(Offset), - Addr.isKnownNonNull()); + return Address(CreateInBoundsGEP(Addr.getElementType(), Addr.getPointer(), + getSize(Offset), Name), + Addr.getElementType(), + Addr.getAlignment().alignmentAtOffset(Offset), + Addr.isKnownNonNull()); } - Address CreateConstByteGEP(Address Addr, CharUnits Offset, const llvm::Twine &Name = "") { assert(Addr.getElementType() == TypeCache.Int8Ty); - return Address(CreateGEP(Addr.getElementType(), Addr.getBasePointer(), + return Address(CreateGEP(Addr.getElementType(), Addr.getPointer(), getSize(Offset), Name), Addr.getElementType(), - Addr.getAlignment().alignmentAtOffset(Offset)); + Addr.getAlignment().alignmentAtOffset(Offset), + NotKnownNonNull); } using CGBuilderBaseTy::CreateConstInBoundsGEP2_32; Address CreateConstInBoundsGEP2_32(Address Addr, unsigned Idx0, unsigned Idx1, const llvm::Twine &Name = "") { - return createConstGEP2_32(Addr, Idx0, Idx1, Name); - } - - using CGBuilderBaseTy::CreateConstGEP2_32; - Address CreateConstGEP2_32(Address Addr, unsigned Idx0, unsigned Idx1, - const llvm::Twine &Name = "") { - return createConstGEP2_32(Addr, Idx0, Idx1, Name); - } - - Address CreateGEP(Address Addr, ArrayRef IdxList, - llvm::Type *ElementType, CharUnits Align, - const Twine &Name = "") { - llvm::Value *Ptr = emitRawPointerFromAddress(Addr); - return RawAddress(CreateGEP(Addr.getElementType(), Ptr, IdxList, Name), - ElementType, Align); - } - - using CGBuilderBaseTy::CreateInBoundsGEP; - Address CreateInBoundsGEP(Address Addr, ArrayRef IdxList, - llvm::Type *ElementType, CharUnits Align, - const Twine &Name = "") { - return RawAddress(CreateInBoundsGEP(Addr.getElementType(), - emitRawPointerFromAddress(Addr), - IdxList, Name), - ElementType, Align, Addr.isKnownNonNull()); - } + const llvm::DataLayout &DL = BB->getParent()->getParent()->getDataLayout(); - using CGBuilderBaseTy::CreateIsNull; - llvm::Value *CreateIsNull(Address Addr, const Twine &Name = "") { - if (!Addr.hasOffset()) - return CreateIsNull(Addr.getBasePointer(), Name); - // The pointer isn't null if Addr has an offset since offsets can always - // be applied inbound. - return llvm::ConstantInt::getFalse(Context); + auto *GEP = cast(CreateConstInBoundsGEP2_32( + Addr.getElementType(), Addr.getPointer(), Idx0, Idx1, Name)); + llvm::APInt Offset( + DL.getIndexSizeInBits(Addr.getType()->getPointerAddressSpace()), 0, + /*isSigned=*/true); + if (!GEP->accumulateConstantOffset(DL, Offset)) + llvm_unreachable("offset of GEP with constants is always computable"); + return Address(GEP, GEP->getResultElementType(), + Addr.getAlignment().alignmentAtOffset( + CharUnits::fromQuantity(Offset.getSExtValue())), + Addr.isKnownNonNull()); } using CGBuilderBaseTy::CreateMemCpy; llvm::CallInst *CreateMemCpy(Address Dest, Address Src, llvm::Value *Size, bool IsVolatile = false) { - llvm::Value *DestPtr = emitRawPointerFromAddress(Dest); - llvm::Value *SrcPtr = emitRawPointerFromAddress(Src); - return CreateMemCpy(DestPtr, Dest.getAlignment().getAsAlign(), SrcPtr, - Src.getAlignment().getAsAlign(), Size, IsVolatile); + return CreateMemCpy(Dest.getPointer(), Dest.getAlignment().getAsAlign(), + Src.getPointer(), Src.getAlignment().getAsAlign(), Size, + IsVolatile); } llvm::CallInst *CreateMemCpy(Address Dest, Address Src, uint64_t Size, bool IsVolatile = false) { - llvm::Value *DestPtr = emitRawPointerFromAddress(Dest); - llvm::Value *SrcPtr = emitRawPointerFromAddress(Src); - return CreateMemCpy(DestPtr, Dest.getAlignment().getAsAlign(), SrcPtr, - Src.getAlignment().getAsAlign(), Size, IsVolatile); + return CreateMemCpy(Dest.getPointer(), Dest.getAlignment().getAsAlign(), + Src.getPointer(), Src.getAlignment().getAsAlign(), Size, + IsVolatile); } using CGBuilderBaseTy::CreateMemCpyInline; llvm::CallInst *CreateMemCpyInline(Address Dest, Address Src, uint64_t Size) { - llvm::Value *DestPtr = emitRawPointerFromAddress(Dest); - llvm::Value *SrcPtr = emitRawPointerFromAddress(Src); - return CreateMemCpyInline(DestPtr, Dest.getAlignment().getAsAlign(), SrcPtr, - Src.getAlignment().getAsAlign(), getInt64(Size)); + return CreateMemCpyInline( + Dest.getPointer(), Dest.getAlignment().getAsAlign(), Src.getPointer(), + Src.getAlignment().getAsAlign(), getInt64(Size)); } using CGBuilderBaseTy::CreateMemMove; llvm::CallInst *CreateMemMove(Address Dest, Address Src, llvm::Value *Size, bool IsVolatile = false) { - llvm::Value *DestPtr = emitRawPointerFromAddress(Dest); - llvm::Value *SrcPtr = emitRawPointerFromAddress(Src); - return CreateMemMove(DestPtr, Dest.getAlignment().getAsAlign(), SrcPtr, - Src.getAlignment().getAsAlign(), Size, IsVolatile); + return CreateMemMove(Dest.getPointer(), Dest.getAlignment().getAsAlign(), + Src.getPointer(), Src.getAlignment().getAsAlign(), + Size, IsVolatile); } using CGBuilderBaseTy::CreateMemSet; llvm::CallInst *CreateMemSet(Address Dest, llvm::Value *Value, llvm::Value *Size, bool IsVolatile = false) { - return CreateMemSet(emitRawPointerFromAddress(Dest), Value, Size, + return CreateMemSet(Dest.getPointer(), Value, Size, Dest.getAlignment().getAsAlign(), IsVolatile); } using CGBuilderBaseTy::CreateMemSetInline; llvm::CallInst *CreateMemSetInline(Address Dest, llvm::Value *Value, uint64_t Size) { - return CreateMemSetInline(emitRawPointerFromAddress(Dest), + return CreateMemSetInline(Dest.getPointer(), Dest.getAlignment().getAsAlign(), Value, getInt64(Size)); } @@ -417,31 +346,16 @@ public: const llvm::StructLayout *Layout = DL.getStructLayout(ElTy); auto Offset = CharUnits::fromQuantity(Layout->getElementOffset(Index)); - return Address( - CreatePreserveStructAccessIndex(ElTy, emitRawPointerFromAddress(Addr), - Index, FieldIndex, DbgInfo), - ElTy->getElementType(Index), - Addr.getAlignment().alignmentAtOffset(Offset)); - } - - using CGBuilderBaseTy::CreatePreserveUnionAccessIndex; - Address CreatePreserveUnionAccessIndex(Address Addr, unsigned FieldIndex, - llvm::MDNode *DbgInfo) { - Addr.replaceBasePointer(CreatePreserveUnionAccessIndex( - Addr.getBasePointer(), FieldIndex, DbgInfo)); - return Addr; + return Address(CreatePreserveStructAccessIndex(ElTy, Addr.getPointer(), + Index, FieldIndex, DbgInfo), + ElTy->getElementType(Index), + Addr.getAlignment().alignmentAtOffset(Offset)); } using CGBuilderBaseTy::CreateLaunderInvariantGroup; Address CreateLaunderInvariantGroup(Address Addr) { - Addr.replaceBasePointer(CreateLaunderInvariantGroup(Addr.getBasePointer())); - return Addr; - } - - using CGBuilderBaseTy::CreateStripInvariantGroup; - Address CreateStripInvariantGroup(Address Addr) { - Addr.replaceBasePointer(CreateStripInvariantGroup(Addr.getBasePointer())); - return Addr; + return Addr.withPointer(CreateLaunderInvariantGroup(Addr.getPointer()), + Addr.isKnownNonNull()); } }; diff --git a/clang/lib/CodeGen/CGBuiltin.cpp b/clang/lib/CodeGen/CGBuiltin.cpp index 5ab5917c0c8d..fdb517eb254d 100644 --- a/clang/lib/CodeGen/CGBuiltin.cpp +++ b/clang/lib/CodeGen/CGBuiltin.cpp @@ -2117,9 +2117,9 @@ llvm::Function *CodeGenFunction::generateBuiltinOSLogHelperFunction( auto AL = ApplyDebugLocation::CreateArtificial(*this); CharUnits Offset; - Address BufAddr = makeNaturalAddressForPointer( - Builder.CreateLoad(GetAddrOfLocalVar(Args[0]), "buf"), Ctx.VoidTy, - BufferAlignment); + Address BufAddr = + Address(Builder.CreateLoad(GetAddrOfLocalVar(Args[0]), "buf"), Int8Ty, + BufferAlignment); Builder.CreateStore(Builder.getInt8(Layout.getSummaryByte()), Builder.CreateConstByteGEP(BufAddr, Offset++, "summary")); Builder.CreateStore(Builder.getInt8(Layout.getNumArgsByte()), @@ -2162,7 +2162,7 @@ RValue CodeGenFunction::emitBuiltinOSLogFormat(const CallExpr &E) { // Ignore argument 1, the format string. It is not currently used. CallArgList Args; - Args.add(RValue::get(BufAddr.emitRawPointer(*this)), Ctx.VoidPtrTy); + Args.add(RValue::get(BufAddr.getPointer()), Ctx.VoidPtrTy); for (const auto &Item : Layout.Items) { int Size = Item.getSizeByte(); @@ -2202,8 +2202,8 @@ RValue CodeGenFunction::emitBuiltinOSLogFormat(const CallExpr &E) { if (!isa(ArgVal)) { CleanupKind Cleanup = getARCCleanupKind(); QualType Ty = TheExpr->getType(); - RawAddress Alloca = RawAddress::invalid(); - RawAddress Addr = CreateMemTemp(Ty, "os.log.arg", &Alloca); + Address Alloca = Address::invalid(); + Address Addr = CreateMemTemp(Ty, "os.log.arg", &Alloca); ArgVal = EmitARCRetain(Ty, ArgVal); Builder.CreateStore(ArgVal, Addr); pushLifetimeExtendedDestroy(Cleanup, Alloca, Ty, @@ -2236,7 +2236,7 @@ RValue CodeGenFunction::emitBuiltinOSLogFormat(const CallExpr &E) { llvm::Function *F = CodeGenFunction(CGM).generateBuiltinOSLogHelperFunction( Layout, BufAddr.getAlignment()); EmitCall(FI, CGCallee::forDirect(F), ReturnValueSlot(), Args); - return RValue::get(BufAddr, *this); + return RValue::get(BufAddr.getPointer()); } static bool isSpecialUnsignedMultiplySignedResult( @@ -2984,7 +2984,7 @@ RValue CodeGenFunction::EmitBuiltinExpr(const GlobalDecl GD, unsigned BuiltinID, // Check NonnullAttribute/NullabilityArg and Alignment. auto EmitArgCheck = [&](TypeCheckKind Kind, Address A, const Expr *Arg, unsigned ParmNum) { - Value *Val = A.emitRawPointer(*this); + Value *Val = A.getPointer(); EmitNonNullArgCheck(RValue::get(Val), Arg->getType(), Arg->getExprLoc(), FD, ParmNum); @@ -3013,12 +3013,12 @@ RValue CodeGenFunction::EmitBuiltinExpr(const GlobalDecl GD, unsigned BuiltinID, case Builtin::BI__builtin_va_end: EmitVAStartEnd(BuiltinID == Builtin::BI__va_start ? EmitScalarExpr(E->getArg(0)) - : EmitVAListRef(E->getArg(0)).emitRawPointer(*this), + : EmitVAListRef(E->getArg(0)).getPointer(), BuiltinID != Builtin::BI__builtin_va_end); return RValue::get(nullptr); case Builtin::BI__builtin_va_copy: { - Value *DstPtr = EmitVAListRef(E->getArg(0)).emitRawPointer(*this); - Value *SrcPtr = EmitVAListRef(E->getArg(1)).emitRawPointer(*this); + Value *DstPtr = EmitVAListRef(E->getArg(0)).getPointer(); + Value *SrcPtr = EmitVAListRef(E->getArg(1)).getPointer(); Builder.CreateCall(CGM.getIntrinsic(Intrinsic::vacopy, {DstPtr->getType()}), {DstPtr, SrcPtr}); return RValue::get(nullptr); @@ -3849,13 +3849,13 @@ RValue CodeGenFunction::EmitBuiltinExpr(const GlobalDecl GD, unsigned BuiltinID, bool IsVolatile = PtrTy->getPointeeType().isVolatileQualified(); Address Src = EmitPointerWithAlignment(E->getArg(0)); - EmitNonNullArgCheck(RValue::get(Src.emitRawPointer(*this)), - E->getArg(0)->getType(), E->getArg(0)->getExprLoc(), FD, - 0); + EmitNonNullArgCheck(RValue::get(Src.getPointer()), E->getArg(0)->getType(), + E->getArg(0)->getExprLoc(), FD, 0); Value *Result = MB.CreateColumnMajorLoad( - Src.getElementType(), Src.emitRawPointer(*this), + Src.getElementType(), Src.getPointer(), Align(Src.getAlignment().getQuantity()), Stride, IsVolatile, - ResultTy->getNumRows(), ResultTy->getNumColumns(), "matrix"); + ResultTy->getNumRows(), ResultTy->getNumColumns(), + "matrix"); return RValue::get(Result); } @@ -3870,13 +3870,11 @@ RValue CodeGenFunction::EmitBuiltinExpr(const GlobalDecl GD, unsigned BuiltinID, assert(PtrTy && "arg1 must be of pointer type"); bool IsVolatile = PtrTy->getPointeeType().isVolatileQualified(); - EmitNonNullArgCheck(RValue::get(Dst.emitRawPointer(*this)), - E->getArg(1)->getType(), E->getArg(1)->getExprLoc(), FD, - 0); + EmitNonNullArgCheck(RValue::get(Dst.getPointer()), E->getArg(1)->getType(), + E->getArg(1)->getExprLoc(), FD, 0); Value *Result = MB.CreateColumnMajorStore( - Matrix, Dst.emitRawPointer(*this), - Align(Dst.getAlignment().getQuantity()), Stride, IsVolatile, - MatrixTy->getNumRows(), MatrixTy->getNumColumns()); + Matrix, Dst.getPointer(), Align(Dst.getAlignment().getQuantity()), + Stride, IsVolatile, MatrixTy->getNumRows(), MatrixTy->getNumColumns()); return RValue::get(Result); } @@ -4035,7 +4033,7 @@ RValue CodeGenFunction::EmitBuiltinExpr(const GlobalDecl GD, unsigned BuiltinID, case Builtin::BI__builtin_bzero: { Address Dest = EmitPointerWithAlignment(E->getArg(0)); Value *SizeVal = EmitScalarExpr(E->getArg(1)); - EmitNonNullArgCheck(Dest, E->getArg(0)->getType(), + EmitNonNullArgCheck(RValue::get(Dest.getPointer()), E->getArg(0)->getType(), E->getArg(0)->getExprLoc(), FD, 0); Builder.CreateMemSet(Dest, Builder.getInt8(0), SizeVal, false); return RValue::get(nullptr); @@ -4046,12 +4044,10 @@ RValue CodeGenFunction::EmitBuiltinExpr(const GlobalDecl GD, unsigned BuiltinID, Address Src = EmitPointerWithAlignment(E->getArg(0)); Address Dest = EmitPointerWithAlignment(E->getArg(1)); Value *SizeVal = EmitScalarExpr(E->getArg(2)); - EmitNonNullArgCheck(RValue::get(Src.emitRawPointer(*this)), - E->getArg(0)->getType(), E->getArg(0)->getExprLoc(), FD, - 0); - EmitNonNullArgCheck(RValue::get(Dest.emitRawPointer(*this)), - E->getArg(1)->getType(), E->getArg(1)->getExprLoc(), FD, - 0); + EmitNonNullArgCheck(RValue::get(Src.getPointer()), E->getArg(0)->getType(), + E->getArg(0)->getExprLoc(), FD, 0); + EmitNonNullArgCheck(RValue::get(Dest.getPointer()), E->getArg(1)->getType(), + E->getArg(1)->getExprLoc(), FD, 0); Builder.CreateMemMove(Dest, Src, SizeVal, false); return RValue::get(nullptr); } @@ -4068,10 +4064,10 @@ RValue CodeGenFunction::EmitBuiltinExpr(const GlobalDecl GD, unsigned BuiltinID, Builder.CreateMemCpy(Dest, Src, SizeVal, false); if (BuiltinID == Builtin::BImempcpy || BuiltinID == Builtin::BI__builtin_mempcpy) - return RValue::get(Builder.CreateInBoundsGEP( - Dest.getElementType(), Dest.emitRawPointer(*this), SizeVal)); + return RValue::get(Builder.CreateInBoundsGEP(Dest.getElementType(), + Dest.getPointer(), SizeVal)); else - return RValue::get(Dest, *this); + return RValue::get(Dest.getPointer()); } case Builtin::BI__builtin_memcpy_inline: { @@ -4103,7 +4099,7 @@ RValue CodeGenFunction::EmitBuiltinExpr(const GlobalDecl GD, unsigned BuiltinID, Address Src = EmitPointerWithAlignment(E->getArg(1)); Value *SizeVal = llvm::ConstantInt::get(Builder.getContext(), Size); Builder.CreateMemCpy(Dest, Src, SizeVal, false); - return RValue::get(Dest, *this); + return RValue::get(Dest.getPointer()); } case Builtin::BI__builtin_objc_memmove_collectable: { @@ -4112,7 +4108,7 @@ RValue CodeGenFunction::EmitBuiltinExpr(const GlobalDecl GD, unsigned BuiltinID, Value *SizeVal = EmitScalarExpr(E->getArg(2)); CGM.getObjCRuntime().EmitGCMemmoveCollectable(*this, DestAddr, SrcAddr, SizeVal); - return RValue::get(DestAddr, *this); + return RValue::get(DestAddr.getPointer()); } case Builtin::BI__builtin___memmove_chk: { @@ -4129,7 +4125,7 @@ RValue CodeGenFunction::EmitBuiltinExpr(const GlobalDecl GD, unsigned BuiltinID, Address Src = EmitPointerWithAlignment(E->getArg(1)); Value *SizeVal = llvm::ConstantInt::get(Builder.getContext(), Size); Builder.CreateMemMove(Dest, Src, SizeVal, false); - return RValue::get(Dest, *this); + return RValue::get(Dest.getPointer()); } case Builtin::BImemmove: @@ -4140,7 +4136,7 @@ RValue CodeGenFunction::EmitBuiltinExpr(const GlobalDecl GD, unsigned BuiltinID, EmitArgCheck(TCK_Store, Dest, E->getArg(0), 0); EmitArgCheck(TCK_Load, Src, E->getArg(1), 1); Builder.CreateMemMove(Dest, Src, SizeVal, false); - return RValue::get(Dest, *this); + return RValue::get(Dest.getPointer()); } case Builtin::BImemset: case Builtin::BI__builtin_memset: { @@ -4148,10 +4144,10 @@ RValue CodeGenFunction::EmitBuiltinExpr(const GlobalDecl GD, unsigned BuiltinID, Value *ByteVal = Builder.CreateTrunc(EmitScalarExpr(E->getArg(1)), Builder.getInt8Ty()); Value *SizeVal = EmitScalarExpr(E->getArg(2)); - EmitNonNullArgCheck(Dest, E->getArg(0)->getType(), + EmitNonNullArgCheck(RValue::get(Dest.getPointer()), E->getArg(0)->getType(), E->getArg(0)->getExprLoc(), FD, 0); Builder.CreateMemSet(Dest, ByteVal, SizeVal, false); - return RValue::get(Dest, *this); + return RValue::get(Dest.getPointer()); } case Builtin::BI__builtin_memset_inline: { Address Dest = EmitPointerWithAlignment(E->getArg(0)); @@ -4159,9 +4155,8 @@ RValue CodeGenFunction::EmitBuiltinExpr(const GlobalDecl GD, unsigned BuiltinID, Builder.CreateTrunc(EmitScalarExpr(E->getArg(1)), Builder.getInt8Ty()); uint64_t Size = E->getArg(2)->EvaluateKnownConstInt(getContext()).getZExtValue(); - EmitNonNullArgCheck(RValue::get(Dest.emitRawPointer(*this)), - E->getArg(0)->getType(), E->getArg(0)->getExprLoc(), FD, - 0); + EmitNonNullArgCheck(RValue::get(Dest.getPointer()), E->getArg(0)->getType(), + E->getArg(0)->getExprLoc(), FD, 0); Builder.CreateMemSetInline(Dest, ByteVal, Size); return RValue::get(nullptr); } @@ -4180,7 +4175,7 @@ RValue CodeGenFunction::EmitBuiltinExpr(const GlobalDecl GD, unsigned BuiltinID, Builder.getInt8Ty()); Value *SizeVal = llvm::ConstantInt::get(Builder.getContext(), Size); Builder.CreateMemSet(Dest, ByteVal, SizeVal, false); - return RValue::get(Dest, *this); + return RValue::get(Dest.getPointer()); } case Builtin::BI__builtin_wmemchr: { // The MSVC runtime library does not provide a definition of wmemchr, so we @@ -4402,14 +4397,14 @@ RValue CodeGenFunction::EmitBuiltinExpr(const GlobalDecl GD, unsigned BuiltinID, // Store the stack pointer to the setjmp buffer. Value *StackAddr = Builder.CreateStackSave(); - assert(Buf.emitRawPointer(*this)->getType() == StackAddr->getType()); + assert(Buf.getPointer()->getType() == StackAddr->getType()); Address StackSaveSlot = Builder.CreateConstInBoundsGEP(Buf, 2); Builder.CreateStore(StackAddr, StackSaveSlot); // Call LLVM's EH setjmp, which is lightweight. Function *F = CGM.getIntrinsic(Intrinsic::eh_sjlj_setjmp); - return RValue::get(Builder.CreateCall(F, Buf.emitRawPointer(*this))); + return RValue::get(Builder.CreateCall(F, Buf.getPointer())); } case Builtin::BI__builtin_longjmp: { Value *Buf = EmitScalarExpr(E->getArg(0)); @@ -5582,7 +5577,7 @@ RValue CodeGenFunction::EmitBuiltinExpr(const GlobalDecl GD, unsigned BuiltinID, llvm::Value *Queue = EmitScalarExpr(E->getArg(0)); llvm::Value *Flags = EmitScalarExpr(E->getArg(1)); LValue NDRangeL = EmitAggExprToLValue(E->getArg(2)); - llvm::Value *Range = NDRangeL.getAddress(*this).emitRawPointer(*this); + llvm::Value *Range = NDRangeL.getAddress(*this).getPointer(); llvm::Type *RangeTy = NDRangeL.getAddress(*this).getType(); if (NumArgs == 4) { @@ -5691,10 +5686,9 @@ RValue CodeGenFunction::EmitBuiltinExpr(const GlobalDecl GD, unsigned BuiltinID, getContext(), Expr::NPC_ValueDependentIsNotNull)) { EventWaitList = llvm::ConstantPointerNull::get(PtrTy); } else { - EventWaitList = - E->getArg(4)->getType()->isArrayType() - ? EmitArrayToPointerDecay(E->getArg(4)).emitRawPointer(*this) - : EmitScalarExpr(E->getArg(4)); + EventWaitList = E->getArg(4)->getType()->isArrayType() + ? EmitArrayToPointerDecay(E->getArg(4)).getPointer() + : EmitScalarExpr(E->getArg(4)); // Convert to generic address space. EventWaitList = Builder.CreatePointerCast(EventWaitList, PtrTy); } @@ -5790,7 +5784,7 @@ RValue CodeGenFunction::EmitBuiltinExpr(const GlobalDecl GD, unsigned BuiltinID, llvm::Type *GenericVoidPtrTy = Builder.getPtrTy( getContext().getTargetAddressSpace(LangAS::opencl_generic)); LValue NDRangeL = EmitAggExprToLValue(E->getArg(0)); - llvm::Value *NDRange = NDRangeL.getAddress(*this).emitRawPointer(*this); + llvm::Value *NDRange = NDRangeL.getAddress(*this).getPointer(); auto Info = CGM.getOpenCLRuntime().emitOpenCLEnqueuedBlock(*this, E->getArg(1)); Value *Kernel = @@ -5875,7 +5869,7 @@ RValue CodeGenFunction::EmitBuiltinExpr(const GlobalDecl GD, unsigned BuiltinID, auto PTy0 = FTy->getParamType(0); if (PTy0 != Arg0Val->getType()) { if (Arg0Ty->isArrayType()) - Arg0Val = EmitArrayToPointerDecay(Arg0).emitRawPointer(*this); + Arg0Val = EmitArrayToPointerDecay(Arg0).getPointer(); else Arg0Val = Builder.CreatePointerCast(Arg0Val, PTy0); } @@ -5913,7 +5907,7 @@ RValue CodeGenFunction::EmitBuiltinExpr(const GlobalDecl GD, unsigned BuiltinID, auto PTy1 = FTy->getParamType(1); if (PTy1 != Arg1Val->getType()) { if (Arg1Ty->isArrayType()) - Arg1Val = EmitArrayToPointerDecay(Arg1).emitRawPointer(*this); + Arg1Val = EmitArrayToPointerDecay(Arg1).getPointer(); else Arg1Val = Builder.CreatePointerCast(Arg1Val, PTy1); } @@ -5927,7 +5921,7 @@ RValue CodeGenFunction::EmitBuiltinExpr(const GlobalDecl GD, unsigned BuiltinID, case Builtin::BI__builtin_ms_va_start: case Builtin::BI__builtin_ms_va_end: return RValue::get( - EmitVAStartEnd(EmitMSVAListRef(E->getArg(0)).emitRawPointer(*this), + EmitVAStartEnd(EmitMSVAListRef(E->getArg(0)).getPointer(), BuiltinID == Builtin::BI__builtin_ms_va_start)); case Builtin::BI__builtin_ms_va_copy: { @@ -5969,8 +5963,8 @@ RValue CodeGenFunction::EmitBuiltinExpr(const GlobalDecl GD, unsigned BuiltinID, // If this is a predefined lib function (e.g. malloc), emit the call // using exactly the normal call path. if (getContext().BuiltinInfo.isPredefinedLibFunction(BuiltinID)) - return emitLibraryCall( - *this, FD, E, cast(EmitScalarExpr(E->getCallee()))); + return emitLibraryCall(*this, FD, E, + cast(EmitScalarExpr(E->getCallee()))); // Check that a call to a target specific builtin has the correct target // features. @@ -6087,7 +6081,7 @@ RValue CodeGenFunction::EmitBuiltinExpr(const GlobalDecl GD, unsigned BuiltinID, return RValue::get(nullptr); return RValue::get(V); case TEK_Aggregate: - return RValue::getAggregate(ReturnValue.getAddress(), + return RValue::getAggregate(ReturnValue.getValue(), ReturnValue.isVolatile()); case TEK_Complex: llvm_unreachable("No current target builtin returns complex"); @@ -8857,7 +8851,7 @@ Value *CodeGenFunction::EmitARMBuiltinExpr(unsigned BuiltinID, // Get the alignment for the argument in addition to the value; // we'll use it later. PtrOp0 = EmitPointerWithAlignment(E->getArg(0)); - Ops.push_back(PtrOp0.emitRawPointer(*this)); + Ops.push_back(PtrOp0.getPointer()); continue; } } @@ -8884,7 +8878,7 @@ Value *CodeGenFunction::EmitARMBuiltinExpr(unsigned BuiltinID, // Get the alignment for the argument in addition to the value; // we'll use it later. PtrOp1 = EmitPointerWithAlignment(E->getArg(1)); - Ops.push_back(PtrOp1.emitRawPointer(*this)); + Ops.push_back(PtrOp1.getPointer()); continue; } } @@ -9305,7 +9299,7 @@ Value *CodeGenFunction::EmitARMMVEBuiltinExpr(unsigned BuiltinID, if (ReturnValue.isNull()) return MvecOut; else - return Builder.CreateStore(MvecOut, ReturnValue.getAddress()); + return Builder.CreateStore(MvecOut, ReturnValue.getValue()); } case CustomCodeGen::VST24: { @@ -11485,7 +11479,7 @@ Value *CodeGenFunction::EmitAArch64BuiltinExpr(unsigned BuiltinID, // Get the alignment for the argument in addition to the value; // we'll use it later. PtrOp0 = EmitPointerWithAlignment(E->getArg(0)); - Ops.push_back(PtrOp0.emitRawPointer(*this)); + Ops.push_back(PtrOp0.getPointer()); continue; } } @@ -13351,15 +13345,15 @@ Value *CodeGenFunction::EmitBPFBuiltinExpr(unsigned BuiltinID, if (!getDebugInfo()) { CGM.Error(E->getExprLoc(), "using __builtin_preserve_field_info() without -g"); - return IsBitField ? EmitLValue(Arg).getRawBitFieldPointer(*this) - : EmitLValue(Arg).emitRawPointer(*this); + return IsBitField ? EmitLValue(Arg).getBitFieldPointer() + : EmitLValue(Arg).getPointer(*this); } // Enable underlying preserve_*_access_index() generation. bool OldIsInPreservedAIRegion = IsInPreservedAIRegion; IsInPreservedAIRegion = true; - Value *FieldAddr = IsBitField ? EmitLValue(Arg).getRawBitFieldPointer(*this) - : EmitLValue(Arg).emitRawPointer(*this); + Value *FieldAddr = IsBitField ? EmitLValue(Arg).getBitFieldPointer() + : EmitLValue(Arg).getPointer(*this); IsInPreservedAIRegion = OldIsInPreservedAIRegion; ConstantInt *C = cast(EmitScalarExpr(E->getArg(1))); @@ -14351,14 +14345,14 @@ Value *CodeGenFunction::EmitX86BuiltinExpr(unsigned BuiltinID, } case X86::BI_mm_setcsr: case X86::BI__builtin_ia32_ldmxcsr: { - RawAddress Tmp = CreateMemTemp(E->getArg(0)->getType()); + Address Tmp = CreateMemTemp(E->getArg(0)->getType()); Builder.CreateStore(Ops[0], Tmp); return Builder.CreateCall(CGM.getIntrinsic(Intrinsic::x86_sse_ldmxcsr), Tmp.getPointer()); } case X86::BI_mm_getcsr: case X86::BI__builtin_ia32_stmxcsr: { - RawAddress Tmp = CreateMemTemp(E->getType()); + Address Tmp = CreateMemTemp(E->getType()); Builder.CreateCall(CGM.getIntrinsic(Intrinsic::x86_sse_stmxcsr), Tmp.getPointer()); return Builder.CreateLoad(Tmp, "stmxcsr"); @@ -17633,8 +17627,7 @@ Value *CodeGenFunction::EmitPPCBuiltinExpr(unsigned BuiltinID, SmallVector Ops; for (unsigned i = 0, e = E->getNumArgs(); i != e; i++) if (E->getArg(i)->getType()->isArrayType()) - Ops.push_back( - EmitArrayToPointerDecay(E->getArg(i)).emitRawPointer(*this)); + Ops.push_back(EmitArrayToPointerDecay(E->getArg(i)).getPointer()); else Ops.push_back(EmitScalarExpr(E->getArg(i))); // The first argument of these two builtins is a pointer used to store their @@ -20096,14 +20089,14 @@ Value *CodeGenFunction::EmitNVPTXBuiltinExpr(unsigned BuiltinID, // Save returned values. assert(II.NumResults); if (II.NumResults == 1) { - Builder.CreateAlignedStore(Result, Dst.emitRawPointer(*this), + Builder.CreateAlignedStore(Result, Dst.getPointer(), CharUnits::fromQuantity(4)); } else { for (unsigned i = 0; i < II.NumResults; ++i) { Builder.CreateAlignedStore( Builder.CreateBitCast(Builder.CreateExtractValue(Result, i), Dst.getElementType()), - Builder.CreateGEP(Dst.getElementType(), Dst.emitRawPointer(*this), + Builder.CreateGEP(Dst.getElementType(), Dst.getPointer(), llvm::ConstantInt::get(IntTy, i)), CharUnits::fromQuantity(4)); } @@ -20143,7 +20136,7 @@ Value *CodeGenFunction::EmitNVPTXBuiltinExpr(unsigned BuiltinID, for (unsigned i = 0; i < II.NumResults; ++i) { Value *V = Builder.CreateAlignedLoad( Src.getElementType(), - Builder.CreateGEP(Src.getElementType(), Src.emitRawPointer(*this), + Builder.CreateGEP(Src.getElementType(), Src.getPointer(), llvm::ConstantInt::get(IntTy, i)), CharUnits::fromQuantity(4)); Values.push_back(Builder.CreateBitCast(V, ParamType)); @@ -20215,7 +20208,7 @@ Value *CodeGenFunction::EmitNVPTXBuiltinExpr(unsigned BuiltinID, for (unsigned i = 0; i < MI.NumEltsA; ++i) { Value *V = Builder.CreateAlignedLoad( SrcA.getElementType(), - Builder.CreateGEP(SrcA.getElementType(), SrcA.emitRawPointer(*this), + Builder.CreateGEP(SrcA.getElementType(), SrcA.getPointer(), llvm::ConstantInt::get(IntTy, i)), CharUnits::fromQuantity(4)); Values.push_back(Builder.CreateBitCast(V, AType)); @@ -20225,7 +20218,7 @@ Value *CodeGenFunction::EmitNVPTXBuiltinExpr(unsigned BuiltinID, for (unsigned i = 0; i < MI.NumEltsB; ++i) { Value *V = Builder.CreateAlignedLoad( SrcB.getElementType(), - Builder.CreateGEP(SrcB.getElementType(), SrcB.emitRawPointer(*this), + Builder.CreateGEP(SrcB.getElementType(), SrcB.getPointer(), llvm::ConstantInt::get(IntTy, i)), CharUnits::fromQuantity(4)); Values.push_back(Builder.CreateBitCast(V, BType)); @@ -20236,7 +20229,7 @@ Value *CodeGenFunction::EmitNVPTXBuiltinExpr(unsigned BuiltinID, for (unsigned i = 0; i < MI.NumEltsC; ++i) { Value *V = Builder.CreateAlignedLoad( SrcC.getElementType(), - Builder.CreateGEP(SrcC.getElementType(), SrcC.emitRawPointer(*this), + Builder.CreateGEP(SrcC.getElementType(), SrcC.getPointer(), llvm::ConstantInt::get(IntTy, i)), CharUnits::fromQuantity(4)); Values.push_back(Builder.CreateBitCast(V, CType)); @@ -20246,7 +20239,7 @@ Value *CodeGenFunction::EmitNVPTXBuiltinExpr(unsigned BuiltinID, for (unsigned i = 0; i < MI.NumEltsD; ++i) Builder.CreateAlignedStore( Builder.CreateBitCast(Builder.CreateExtractValue(Result, i), DType), - Builder.CreateGEP(Dst.getElementType(), Dst.emitRawPointer(*this), + Builder.CreateGEP(Dst.getElementType(), Dst.getPointer(), llvm::ConstantInt::get(IntTy, i)), CharUnits::fromQuantity(4)); return Result; @@ -20504,7 +20497,7 @@ struct BuiltinAlignArgs { BuiltinAlignArgs(const CallExpr *E, CodeGenFunction &CGF) { QualType AstType = E->getArg(0)->getType(); if (AstType->isArrayType()) - Src = CGF.EmitArrayToPointerDecay(E->getArg(0)).emitRawPointer(CGF); + Src = CGF.EmitArrayToPointerDecay(E->getArg(0)).getPointer(); else Src = CGF.EmitScalarExpr(E->getArg(0)); SrcType = Src->getType(); @@ -21122,7 +21115,7 @@ Value *CodeGenFunction::EmitWebAssemblyBuiltinExpr(unsigned BuiltinID, } case WebAssembly::BI__builtin_wasm_table_get: { assert(E->getArg(0)->getType()->isArrayType()); - Value *Table = EmitArrayToPointerDecay(E->getArg(0)).emitRawPointer(*this); + Value *Table = EmitArrayToPointerDecay(E->getArg(0)).getPointer(); Value *Index = EmitScalarExpr(E->getArg(1)); Function *Callee; if (E->getType().isWebAssemblyExternrefType()) @@ -21136,7 +21129,7 @@ Value *CodeGenFunction::EmitWebAssemblyBuiltinExpr(unsigned BuiltinID, } case WebAssembly::BI__builtin_wasm_table_set: { assert(E->getArg(0)->getType()->isArrayType()); - Value *Table = EmitArrayToPointerDecay(E->getArg(0)).emitRawPointer(*this); + Value *Table = EmitArrayToPointerDecay(E->getArg(0)).getPointer(); Value *Index = EmitScalarExpr(E->getArg(1)); Value *Val = EmitScalarExpr(E->getArg(2)); Function *Callee; @@ -21151,13 +21144,13 @@ Value *CodeGenFunction::EmitWebAssemblyBuiltinExpr(unsigned BuiltinID, } case WebAssembly::BI__builtin_wasm_table_size: { assert(E->getArg(0)->getType()->isArrayType()); - Value *Value = EmitArrayToPointerDecay(E->getArg(0)).emitRawPointer(*this); + Value *Value = EmitArrayToPointerDecay(E->getArg(0)).getPointer(); Function *Callee = CGM.getIntrinsic(Intrinsic::wasm_table_size); return Builder.CreateCall(Callee, Value); } case WebAssembly::BI__builtin_wasm_table_grow: { assert(E->getArg(0)->getType()->isArrayType()); - Value *Table = EmitArrayToPointerDecay(E->getArg(0)).emitRawPointer(*this); + Value *Table = EmitArrayToPointerDecay(E->getArg(0)).getPointer(); Value *Val = EmitScalarExpr(E->getArg(1)); Value *NElems = EmitScalarExpr(E->getArg(2)); @@ -21174,7 +21167,7 @@ Value *CodeGenFunction::EmitWebAssemblyBuiltinExpr(unsigned BuiltinID, } case WebAssembly::BI__builtin_wasm_table_fill: { assert(E->getArg(0)->getType()->isArrayType()); - Value *Table = EmitArrayToPointerDecay(E->getArg(0)).emitRawPointer(*this); + Value *Table = EmitArrayToPointerDecay(E->getArg(0)).getPointer(); Value *Index = EmitScalarExpr(E->getArg(1)); Value *Val = EmitScalarExpr(E->getArg(2)); Value *NElems = EmitScalarExpr(E->getArg(3)); @@ -21192,8 +21185,8 @@ Value *CodeGenFunction::EmitWebAssemblyBuiltinExpr(unsigned BuiltinID, } case WebAssembly::BI__builtin_wasm_table_copy: { assert(E->getArg(0)->getType()->isArrayType()); - Value *TableX = EmitArrayToPointerDecay(E->getArg(0)).emitRawPointer(*this); - Value *TableY = EmitArrayToPointerDecay(E->getArg(1)).emitRawPointer(*this); + Value *TableX = EmitArrayToPointerDecay(E->getArg(0)).getPointer(); + Value *TableY = EmitArrayToPointerDecay(E->getArg(1)).getPointer(); Value *DstIdx = EmitScalarExpr(E->getArg(2)); Value *SrcIdx = EmitScalarExpr(E->getArg(3)); Value *NElems = EmitScalarExpr(E->getArg(4)); @@ -21272,7 +21265,7 @@ Value *CodeGenFunction::EmitHexagonBuiltinExpr(unsigned BuiltinID, auto MakeCircOp = [this, E](unsigned IntID, bool IsLoad) { // The base pointer is passed by address, so it needs to be loaded. Address A = EmitPointerWithAlignment(E->getArg(0)); - Address BP = Address(A.emitRawPointer(*this), Int8PtrTy, A.getAlignment()); + Address BP = Address(A.getPointer(), Int8PtrTy, A.getAlignment()); llvm::Value *Base = Builder.CreateLoad(BP); // The treatment of both loads and stores is the same: the arguments for // the builtin are the same as the arguments for the intrinsic. @@ -21313,8 +21306,8 @@ Value *CodeGenFunction::EmitHexagonBuiltinExpr(unsigned BuiltinID, // EmitPointerWithAlignment and EmitScalarExpr evaluates the expression // per call. Address DestAddr = EmitPointerWithAlignment(E->getArg(1)); - DestAddr = DestAddr.withElementType(Int8Ty); - llvm::Value *DestAddress = DestAddr.emitRawPointer(*this); + DestAddr = Address(DestAddr.getPointer(), Int8Ty, DestAddr.getAlignment()); + llvm::Value *DestAddress = DestAddr.getPointer(); // Operands are Base, Dest, Modifier. // The intrinsic format in LLVM IR is defined as @@ -21365,8 +21358,8 @@ Value *CodeGenFunction::EmitHexagonBuiltinExpr(unsigned BuiltinID, {EmitScalarExpr(E->getArg(0)), EmitScalarExpr(E->getArg(1)), PredIn}); llvm::Value *PredOut = Builder.CreateExtractValue(Result, 1); - Builder.CreateAlignedStore(Q2V(PredOut), PredAddr.emitRawPointer(*this), - PredAddr.getAlignment()); + Builder.CreateAlignedStore(Q2V(PredOut), PredAddr.getPointer(), + PredAddr.getAlignment()); return Builder.CreateExtractValue(Result, 0); } // These are identical to the builtins above, except they don't consume @@ -21384,8 +21377,8 @@ Value *CodeGenFunction::EmitHexagonBuiltinExpr(unsigned BuiltinID, {EmitScalarExpr(E->getArg(0)), EmitScalarExpr(E->getArg(1))}); llvm::Value *PredOut = Builder.CreateExtractValue(Result, 1); - Builder.CreateAlignedStore(Q2V(PredOut), PredAddr.emitRawPointer(*this), - PredAddr.getAlignment()); + Builder.CreateAlignedStore(Q2V(PredOut), PredAddr.getPointer(), + PredAddr.getAlignment()); return Builder.CreateExtractValue(Result, 0); } diff --git a/clang/lib/CodeGen/CGCUDANV.cpp b/clang/lib/CodeGen/CGCUDANV.cpp index 0cb5b06a519c..b756318c46a9 100644 --- a/clang/lib/CodeGen/CGCUDANV.cpp +++ b/clang/lib/CodeGen/CGCUDANV.cpp @@ -331,11 +331,11 @@ void CGNVCUDARuntime::emitDeviceStubBodyNew(CodeGenFunction &CGF, llvm::ConstantInt::get(SizeTy, std::max(1, Args.size()))); // Store pointers to the arguments in a locally allocated launch_args. for (unsigned i = 0; i < Args.size(); ++i) { - llvm::Value *VarPtr = CGF.GetAddrOfLocalVar(Args[i]).emitRawPointer(CGF); + llvm::Value* VarPtr = CGF.GetAddrOfLocalVar(Args[i]).getPointer(); llvm::Value *VoidVarPtr = CGF.Builder.CreatePointerCast(VarPtr, PtrTy); CGF.Builder.CreateDefaultAlignedStore( - VoidVarPtr, CGF.Builder.CreateConstGEP1_32( - PtrTy, KernelArgs.emitRawPointer(CGF), i)); + VoidVarPtr, + CGF.Builder.CreateConstGEP1_32(PtrTy, KernelArgs.getPointer(), i)); } llvm::BasicBlock *EndBlock = CGF.createBasicBlock("setup.end"); @@ -393,10 +393,9 @@ void CGNVCUDARuntime::emitDeviceStubBodyNew(CodeGenFunction &CGF, /*isVarArg=*/false), addUnderscoredPrefixToName("PopCallConfiguration")); - CGF.EmitRuntimeCallOrInvoke(cudaPopConfigFn, {GridDim.emitRawPointer(CGF), - BlockDim.emitRawPointer(CGF), - ShmemSize.emitRawPointer(CGF), - Stream.emitRawPointer(CGF)}); + CGF.EmitRuntimeCallOrInvoke(cudaPopConfigFn, + {GridDim.getPointer(), BlockDim.getPointer(), + ShmemSize.getPointer(), Stream.getPointer()}); // Emit the call to cudaLaunch llvm::Value *Kernel = @@ -406,7 +405,7 @@ void CGNVCUDARuntime::emitDeviceStubBodyNew(CodeGenFunction &CGF, cudaLaunchKernelFD->getParamDecl(0)->getType()); LaunchKernelArgs.add(RValue::getAggregate(GridDim), Dim3Ty); LaunchKernelArgs.add(RValue::getAggregate(BlockDim), Dim3Ty); - LaunchKernelArgs.add(RValue::get(KernelArgs, CGF), + LaunchKernelArgs.add(RValue::get(KernelArgs.getPointer()), cudaLaunchKernelFD->getParamDecl(3)->getType()); LaunchKernelArgs.add(RValue::get(CGF.Builder.CreateLoad(ShmemSize)), cudaLaunchKernelFD->getParamDecl(4)->getType()); @@ -439,8 +438,8 @@ void CGNVCUDARuntime::emitDeviceStubBodyLegacy(CodeGenFunction &CGF, auto TInfo = CGM.getContext().getTypeInfoInChars(A->getType()); Offset = Offset.alignTo(TInfo.Align); llvm::Value *Args[] = { - CGF.Builder.CreatePointerCast( - CGF.GetAddrOfLocalVar(A).emitRawPointer(CGF), PtrTy), + CGF.Builder.CreatePointerCast(CGF.GetAddrOfLocalVar(A).getPointer(), + PtrTy), llvm::ConstantInt::get(SizeTy, TInfo.Width.getQuantity()), llvm::ConstantInt::get(SizeTy, Offset.getQuantity()), }; diff --git a/clang/lib/CodeGen/CGCXXABI.cpp b/clang/lib/CodeGen/CGCXXABI.cpp index 7c6dfc3e59d8..a8bf57a277e9 100644 --- a/clang/lib/CodeGen/CGCXXABI.cpp +++ b/clang/lib/CodeGen/CGCXXABI.cpp @@ -20,12 +20,6 @@ using namespace CodeGen; CGCXXABI::~CGCXXABI() { } -Address CGCXXABI::getThisAddress(CodeGenFunction &CGF) { - return CGF.makeNaturalAddressForPointer( - CGF.CXXABIThisValue, CGF.CXXABIThisDecl->getType()->getPointeeType(), - CGF.CXXABIThisAlignment); -} - void CGCXXABI::ErrorUnsupportedABI(CodeGenFunction &CGF, StringRef S) { DiagnosticsEngine &Diags = CGF.CGM.getDiags(); unsigned DiagID = Diags.getCustomDiagID(DiagnosticsEngine::Error, @@ -50,12 +44,8 @@ CGCallee CGCXXABI::EmitLoadOfMemberFunctionPointer( llvm::Value *MemPtr, const MemberPointerType *MPT) { ErrorUnsupportedABI(CGF, "calls through member pointers"); - const auto *RD = - cast(MPT->getClass()->castAs()->getDecl()); - ThisPtrForCall = - CGF.getAsNaturalPointerTo(This, CGF.getContext().getRecordType(RD)); - const FunctionProtoType *FPT = - MPT->getPointeeType()->getAs(); + ThisPtrForCall = This.getPointer(); + const auto *FPT = MPT->getPointeeType()->castAs(); llvm::Constant *FnPtr = llvm::Constant::getNullValue( llvm::PointerType::getUnqual(CGM.getLLVMContext())); return CGCallee::forDirect(FnPtr, FPT); @@ -261,15 +251,16 @@ void CGCXXABI::ReadArrayCookie(CodeGenFunction &CGF, Address ptr, // If we don't need an array cookie, bail out early. if (!requiresArrayCookie(expr, eltTy)) { - allocPtr = ptr.emitRawPointer(CGF); + allocPtr = ptr.getPointer(); numElements = nullptr; cookieSize = CharUnits::Zero(); return; } cookieSize = getArrayCookieSizeImpl(eltTy); - Address allocAddr = CGF.Builder.CreateConstInBoundsByteGEP(ptr, -cookieSize); - allocPtr = allocAddr.emitRawPointer(CGF); + Address allocAddr = + CGF.Builder.CreateConstInBoundsByteGEP(ptr, -cookieSize); + allocPtr = allocAddr.getPointer(); numElements = readArrayCookieImpl(CGF, allocAddr, cookieSize); } diff --git a/clang/lib/CodeGen/CGCXXABI.h b/clang/lib/CodeGen/CGCXXABI.h index c7eccbd0095a..ad1ad08d0856 100644 --- a/clang/lib/CodeGen/CGCXXABI.h +++ b/clang/lib/CodeGen/CGCXXABI.h @@ -57,8 +57,12 @@ protected: llvm::Value *getThisValue(CodeGenFunction &CGF) { return CGF.CXXABIThisValue; } - - Address getThisAddress(CodeGenFunction &CGF); + Address getThisAddress(CodeGenFunction &CGF) { + return Address( + CGF.CXXABIThisValue, + CGF.ConvertTypeForMem(CGF.CXXABIThisDecl->getType()->getPointeeType()), + CGF.CXXABIThisAlignment); + } /// Issue a diagnostic about unsupported features in the ABI. void ErrorUnsupportedABI(CodeGenFunction &CGF, StringRef S); @@ -471,6 +475,12 @@ public: BaseSubobject Base, const CXXRecordDecl *NearestVBase) = 0; + /// Get the address point of the vtable for the given base subobject while + /// building a constexpr. + virtual llvm::Constant * + getVTableAddressPointForConstExpr(BaseSubobject Base, + const CXXRecordDecl *VTableClass) = 0; + /// Get the address of the vtable for the given record decl which should be /// used for the vptr at the given offset in RD. virtual llvm::GlobalVariable *getAddrOfVTable(const CXXRecordDecl *RD, diff --git a/clang/lib/CodeGen/CGCall.cpp b/clang/lib/CodeGen/CGCall.cpp index fb0078214b07..b8adf5c26b3a 100644 --- a/clang/lib/CodeGen/CGCall.cpp +++ b/clang/lib/CodeGen/CGCall.cpp @@ -1037,9 +1037,15 @@ static void forConstantArrayExpansion(CodeGenFunction &CGF, ConstantArrayExpansion *CAE, Address BaseAddr, llvm::function_ref Fn) { + CharUnits EltSize = CGF.getContext().getTypeSizeInChars(CAE->EltTy); + CharUnits EltAlign = + BaseAddr.getAlignment().alignmentOfArrayElement(EltSize); + llvm::Type *EltTy = CGF.ConvertTypeForMem(CAE->EltTy); + for (int i = 0, n = CAE->NumElts; i < n; i++) { - Address EltAddr = CGF.Builder.CreateConstGEP2_32(BaseAddr, 0, i); - Fn(EltAddr); + llvm::Value *EltAddr = CGF.Builder.CreateConstGEP2_32( + BaseAddr.getElementType(), BaseAddr.getPointer(), 0, i); + Fn(Address(EltAddr, EltTy, EltAlign)); } } @@ -1154,10 +1160,9 @@ void CodeGenFunction::ExpandTypeToArgs( } /// Create a temporary allocation for the purposes of coercion. -static RawAddress CreateTempAllocaForCoercion(CodeGenFunction &CGF, - llvm::Type *Ty, - CharUnits MinAlign, - const Twine &Name = "tmp") { +static Address CreateTempAllocaForCoercion(CodeGenFunction &CGF, llvm::Type *Ty, + CharUnits MinAlign, + const Twine &Name = "tmp") { // Don't use an alignment that's worse than what LLVM would prefer. auto PrefAlign = CGF.CGM.getDataLayout().getPrefTypeAlign(Ty); CharUnits Align = std::max(MinAlign, CharUnits::fromQuantity(PrefAlign)); @@ -1327,11 +1332,11 @@ static llvm::Value *CreateCoercedLoad(Address Src, llvm::Type *Ty, } // Otherwise do coercion through memory. This is stupid, but simple. - RawAddress Tmp = + Address Tmp = CreateTempAllocaForCoercion(CGF, Ty, Src.getAlignment(), Src.getName()); CGF.Builder.CreateMemCpy( - Tmp.getPointer(), Tmp.getAlignment().getAsAlign(), - Src.emitRawPointer(CGF), Src.getAlignment().getAsAlign(), + Tmp.getPointer(), Tmp.getAlignment().getAsAlign(), Src.getPointer(), + Src.getAlignment().getAsAlign(), llvm::ConstantInt::get(CGF.IntPtrTy, SrcSize.getKnownMinValue())); return CGF.Builder.CreateLoad(Tmp); } @@ -1415,12 +1420,11 @@ static void CreateCoercedStore(llvm::Value *Src, // // FIXME: Assert that we aren't truncating non-padding bits when have access // to that information. - RawAddress Tmp = - CreateTempAllocaForCoercion(CGF, SrcTy, Dst.getAlignment()); + Address Tmp = CreateTempAllocaForCoercion(CGF, SrcTy, Dst.getAlignment()); CGF.Builder.CreateStore(Src, Tmp); CGF.Builder.CreateMemCpy( - Dst.emitRawPointer(CGF), Dst.getAlignment().getAsAlign(), - Tmp.getPointer(), Tmp.getAlignment().getAsAlign(), + Dst.getPointer(), Dst.getAlignment().getAsAlign(), Tmp.getPointer(), + Tmp.getAlignment().getAsAlign(), llvm::ConstantInt::get(CGF.IntPtrTy, DstSize.getFixedValue())); } } @@ -3020,17 +3024,17 @@ void CodeGenFunction::EmitFunctionProlog(const CGFunctionInfo &FI, case ABIArgInfo::Indirect: case ABIArgInfo::IndirectAliased: { assert(NumIRArgs == 1); - Address ParamAddr = makeNaturalAddressForPointer( - Fn->getArg(FirstIRArg), Ty, ArgI.getIndirectAlign(), false, nullptr, - nullptr, KnownNonNull); + Address ParamAddr = Address(Fn->getArg(FirstIRArg), ConvertTypeForMem(Ty), + ArgI.getIndirectAlign(), KnownNonNull); if (!hasScalarEvaluationKind(Ty)) { // Aggregates and complex variables are accessed by reference. All we // need to do is realign the value, if requested. Also, if the address // may be aliased, copy it to ensure that the parameter variable is // mutable and has a unique adress, as C requires. + Address V = ParamAddr; if (ArgI.getIndirectRealign() || ArgI.isIndirectAliased()) { - RawAddress AlignedTemp = CreateMemTemp(Ty, "coerce"); + Address AlignedTemp = CreateMemTemp(Ty, "coerce"); // Copy from the incoming argument pointer to the temporary with the // appropriate alignment. @@ -3040,12 +3044,11 @@ void CodeGenFunction::EmitFunctionProlog(const CGFunctionInfo &FI, CharUnits Size = getContext().getTypeSizeInChars(Ty); Builder.CreateMemCpy( AlignedTemp.getPointer(), AlignedTemp.getAlignment().getAsAlign(), - ParamAddr.emitRawPointer(*this), - ParamAddr.getAlignment().getAsAlign(), + ParamAddr.getPointer(), ParamAddr.getAlignment().getAsAlign(), llvm::ConstantInt::get(IntPtrTy, Size.getQuantity())); - ParamAddr = AlignedTemp; + V = AlignedTemp; } - ArgVals.push_back(ParamValue::forIndirect(ParamAddr)); + ArgVals.push_back(ParamValue::forIndirect(V)); } else { // Load scalar value from indirect argument. llvm::Value *V = @@ -3159,10 +3162,10 @@ void CodeGenFunction::EmitFunctionProlog(const CGFunctionInfo &FI, == ParameterABI::SwiftErrorResult) { QualType pointeeTy = Ty->getPointeeType(); assert(pointeeTy->isPointerType()); - RawAddress temp = - CreateMemTemp(pointeeTy, getPointerAlign(), "swifterror.temp"); - Address arg = makeNaturalAddressForPointer( - V, pointeeTy, getContext().getTypeAlignInChars(pointeeTy)); + Address temp = + CreateMemTemp(pointeeTy, getPointerAlign(), "swifterror.temp"); + Address arg(V, ConvertTypeForMem(pointeeTy), + getContext().getTypeAlignInChars(pointeeTy)); llvm::Value *incomingErrorValue = Builder.CreateLoad(arg); Builder.CreateStore(incomingErrorValue, temp); V = temp.getPointer(); @@ -3499,7 +3502,7 @@ static llvm::Value *tryRemoveRetainOfSelf(CodeGenFunction &CGF, llvm::LoadInst *load = dyn_cast(retainedValue->stripPointerCasts()); if (!load || load->isAtomic() || load->isVolatile() || - load->getPointerOperand() != CGF.GetAddrOfLocalVar(self).getBasePointer()) + load->getPointerOperand() != CGF.GetAddrOfLocalVar(self).getPointer()) return nullptr; // Okay! Burn it all down. This relies for correctness on the @@ -3536,15 +3539,12 @@ static llvm::Value *emitAutoreleaseOfResult(CodeGenFunction &CGF, /// Heuristically search for a dominating store to the return-value slot. static llvm::StoreInst *findDominatingStoreToReturnValue(CodeGenFunction &CGF) { - llvm::Value *ReturnValuePtr = CGF.ReturnValue.getBasePointer(); - // Check if a User is a store which pointerOperand is the ReturnValue. // We are looking for stores to the ReturnValue, not for stores of the // ReturnValue to some other location. - auto GetStoreIfValid = [&CGF, - ReturnValuePtr](llvm::User *U) -> llvm::StoreInst * { + auto GetStoreIfValid = [&CGF](llvm::User *U) -> llvm::StoreInst * { auto *SI = dyn_cast(U); - if (!SI || SI->getPointerOperand() != ReturnValuePtr || + if (!SI || SI->getPointerOperand() != CGF.ReturnValue.getPointer() || SI->getValueOperand()->getType() != CGF.ReturnValue.getElementType()) return nullptr; // These aren't actually possible for non-coerced returns, and we @@ -3558,7 +3558,7 @@ static llvm::StoreInst *findDominatingStoreToReturnValue(CodeGenFunction &CGF) { // for something immediately preceding the IP. Sometimes this can // happen with how we generate implicit-returns; it can also happen // with noreturn cleanups. - if (!ReturnValuePtr->hasOneUse()) { + if (!CGF.ReturnValue.getPointer()->hasOneUse()) { llvm::BasicBlock *IP = CGF.Builder.GetInsertBlock(); if (IP->empty()) return nullptr; @@ -3576,7 +3576,8 @@ static llvm::StoreInst *findDominatingStoreToReturnValue(CodeGenFunction &CGF) { return nullptr; } - llvm::StoreInst *store = GetStoreIfValid(ReturnValuePtr->user_back()); + llvm::StoreInst *store = + GetStoreIfValid(CGF.ReturnValue.getPointer()->user_back()); if (!store) return nullptr; // Now do a first-and-dirty dominance check: just walk up the @@ -4120,11 +4121,7 @@ void CodeGenFunction::EmitDelegateCallArg(CallArgList &args, } static bool isProvablyNull(llvm::Value *addr) { - return llvm::isa_and_nonnull(addr); -} - -static bool isProvablyNonNull(Address Addr, CodeGenFunction &CGF) { - return llvm::isKnownNonZero(Addr.getBasePointer(), CGF.CGM.getDataLayout()); + return isa(addr); } /// Emit the actual writing-back of a writeback. @@ -4132,20 +4129,21 @@ static void emitWriteback(CodeGenFunction &CGF, const CallArgList::Writeback &writeback) { const LValue &srcLV = writeback.Source; Address srcAddr = srcLV.getAddress(CGF); - assert(!isProvablyNull(srcAddr.getBasePointer()) && + assert(!isProvablyNull(srcAddr.getPointer()) && "shouldn't have writeback for provably null argument"); llvm::BasicBlock *contBB = nullptr; // If the argument wasn't provably non-null, we need to null check // before doing the store. - bool provablyNonNull = isProvablyNonNull(srcAddr, CGF); - + bool provablyNonNull = llvm::isKnownNonZero(srcAddr.getPointer(), + CGF.CGM.getDataLayout()); if (!provablyNonNull) { llvm::BasicBlock *writebackBB = CGF.createBasicBlock("icr.writeback"); contBB = CGF.createBasicBlock("icr.done"); - llvm::Value *isNull = CGF.Builder.CreateIsNull(srcAddr, "icr.isnull"); + llvm::Value *isNull = + CGF.Builder.CreateIsNull(srcAddr.getPointer(), "icr.isnull"); CGF.Builder.CreateCondBr(isNull, contBB, writebackBB); CGF.EmitBlock(writebackBB); } @@ -4249,7 +4247,7 @@ static void emitWritebackArg(CodeGenFunction &CGF, CallArgList &args, CGF.ConvertTypeForMem(CRE->getType()->getPointeeType()); // If the address is a constant null, just pass the appropriate null. - if (isProvablyNull(srcAddr.getBasePointer())) { + if (isProvablyNull(srcAddr.getPointer())) { args.add(RValue::get(llvm::ConstantPointerNull::get(destType)), CRE->getType()); return; @@ -4278,16 +4276,17 @@ static void emitWritebackArg(CodeGenFunction &CGF, CallArgList &args, // If the address is *not* known to be non-null, we need to switch. llvm::Value *finalArgument; - bool provablyNonNull = isProvablyNonNull(srcAddr, CGF); - + bool provablyNonNull = llvm::isKnownNonZero(srcAddr.getPointer(), + CGF.CGM.getDataLayout()); if (provablyNonNull) { - finalArgument = temp.emitRawPointer(CGF); + finalArgument = temp.getPointer(); } else { - llvm::Value *isNull = CGF.Builder.CreateIsNull(srcAddr, "icr.isnull"); + llvm::Value *isNull = + CGF.Builder.CreateIsNull(srcAddr.getPointer(), "icr.isnull"); - finalArgument = CGF.Builder.CreateSelect( - isNull, llvm::ConstantPointerNull::get(destType), - temp.emitRawPointer(CGF), "icr.argument"); + finalArgument = CGF.Builder.CreateSelect(isNull, + llvm::ConstantPointerNull::get(destType), + temp.getPointer(), "icr.argument"); // If we need to copy, then the load has to be conditional, which // means we need control flow. @@ -4411,16 +4410,6 @@ void CodeGenFunction::EmitNonNullArgCheck(RValue RV, QualType ArgType, EmitCheck(std::make_pair(Cond, CheckKind), Handler, StaticData, std::nullopt); } -void CodeGenFunction::EmitNonNullArgCheck(Address Addr, QualType ArgType, - SourceLocation ArgLoc, - AbstractCallee AC, unsigned ParmNum) { - if (!AC.getDecl() || !(SanOpts.has(SanitizerKind::NonnullAttribute) || - SanOpts.has(SanitizerKind::NullabilityArg))) - return; - - EmitNonNullArgCheck(RValue::get(Addr, *this), ArgType, ArgLoc, AC, ParmNum); -} - // Check if the call is going to use the inalloca convention. This needs to // agree with CGFunctionInfo::usesInAlloca. The CGFunctionInfo is arranged // later, so we can't check it directly. @@ -4761,20 +4750,10 @@ CodeGenFunction::AddObjCARCExceptionMetadata(llvm::Instruction *Inst) { llvm::CallInst * CodeGenFunction::EmitNounwindRuntimeCall(llvm::FunctionCallee callee, const llvm::Twine &name) { - return EmitNounwindRuntimeCall(callee, ArrayRef(), name); + return EmitNounwindRuntimeCall(callee, std::nullopt, name); } /// Emits a call to the given nounwind runtime function. -llvm::CallInst * -CodeGenFunction::EmitNounwindRuntimeCall(llvm::FunctionCallee callee, - ArrayRef
args, - const llvm::Twine &name) { - SmallVector values; - for (auto arg : args) - values.push_back(arg.emitRawPointer(*this)); - return EmitNounwindRuntimeCall(callee, values, name); -} - llvm::CallInst * CodeGenFunction::EmitNounwindRuntimeCall(llvm::FunctionCallee callee, ArrayRef args, @@ -5053,7 +5032,7 @@ RValue CodeGenFunction::EmitCall(const CGFunctionInfo &CallInfo, // If we're using inalloca, insert the allocation after the stack save. // FIXME: Do this earlier rather than hacking it in here! - RawAddress ArgMemory = RawAddress::invalid(); + Address ArgMemory = Address::invalid(); if (llvm::StructType *ArgStruct = CallInfo.getArgStruct()) { const llvm::DataLayout &DL = CGM.getDataLayout(); llvm::Instruction *IP = CallArgs.getStackBase(); @@ -5069,7 +5048,7 @@ RValue CodeGenFunction::EmitCall(const CGFunctionInfo &CallInfo, AI->setAlignment(Align.getAsAlign()); AI->setUsedWithInAlloca(true); assert(AI->isUsedWithInAlloca() && !AI->isStaticAlloca()); - ArgMemory = RawAddress(AI, ArgStruct, Align); + ArgMemory = Address(AI, ArgStruct, Align); } ClangToLLVMArgMapping IRFunctionArgs(CGM.getContext(), CallInfo); @@ -5078,11 +5057,11 @@ RValue CodeGenFunction::EmitCall(const CGFunctionInfo &CallInfo, // If the call returns a temporary with struct return, create a temporary // alloca to hold the result, unless one is given to us. Address SRetPtr = Address::invalid(); - RawAddress SRetAlloca = RawAddress::invalid(); + Address SRetAlloca = Address::invalid(); llvm::Value *UnusedReturnSizePtr = nullptr; if (RetAI.isIndirect() || RetAI.isInAlloca() || RetAI.isCoerceAndExpand()) { if (!ReturnValue.isNull()) { - SRetPtr = ReturnValue.getAddress(); + SRetPtr = ReturnValue.getValue(); } else { SRetPtr = CreateMemTemp(RetTy, "tmp", &SRetAlloca); if (HaveInsertPoint() && ReturnValue.isUnused()) { @@ -5092,16 +5071,15 @@ RValue CodeGenFunction::EmitCall(const CGFunctionInfo &CallInfo, } } if (IRFunctionArgs.hasSRetArg()) { - IRCallArgs[IRFunctionArgs.getSRetArgNo()] = - getAsNaturalPointerTo(SRetPtr, RetTy); + IRCallArgs[IRFunctionArgs.getSRetArgNo()] = SRetPtr.getPointer(); } else if (RetAI.isInAlloca()) { Address Addr = Builder.CreateStructGEP(ArgMemory, RetAI.getInAllocaFieldIndex()); - Builder.CreateStore(getAsNaturalPointerTo(SRetPtr, RetTy), Addr); + Builder.CreateStore(SRetPtr.getPointer(), Addr); } } - RawAddress swiftErrorTemp = RawAddress::invalid(); + Address swiftErrorTemp = Address::invalid(); Address swiftErrorArg = Address::invalid(); // When passing arguments using temporary allocas, we need to add the @@ -5134,9 +5112,9 @@ RValue CodeGenFunction::EmitCall(const CGFunctionInfo &CallInfo, assert(NumIRArgs == 0); assert(getTarget().getTriple().getArch() == llvm::Triple::x86); if (I->isAggregate()) { - RawAddress Addr = I->hasLValue() - ? I->getKnownLValue().getAddress(*this) - : I->getKnownRValue().getAggregateAddress(); + Address Addr = I->hasLValue() + ? I->getKnownLValue().getAddress(*this) + : I->getKnownRValue().getAggregateAddress(); llvm::Instruction *Placeholder = cast(Addr.getPointer()); @@ -5160,7 +5138,7 @@ RValue CodeGenFunction::EmitCall(const CGFunctionInfo &CallInfo, } else if (ArgInfo.getInAllocaIndirect()) { // Make a temporary alloca and store the address of it into the argument // struct. - RawAddress Addr = CreateMemTempWithoutCast( + Address Addr = CreateMemTempWithoutCast( I->Ty, getContext().getTypeAlignInChars(I->Ty), "indirect-arg-temp"); I->copyInto(*this, Addr); @@ -5182,12 +5160,12 @@ RValue CodeGenFunction::EmitCall(const CGFunctionInfo &CallInfo, assert(NumIRArgs == 1); if (!I->isAggregate()) { // Make a temporary alloca to pass the argument. - RawAddress Addr = CreateMemTempWithoutCast( + Address Addr = CreateMemTempWithoutCast( I->Ty, ArgInfo.getIndirectAlign(), "indirect-arg-temp"); - llvm::Value *Val = getAsNaturalPointerTo(Addr, I->Ty); + llvm::Value *Val = Addr.getPointer(); if (ArgHasMaybeUndefAttr) - Val = Builder.CreateFreeze(Val); + Val = Builder.CreateFreeze(Addr.getPointer()); IRCallArgs[FirstIRArg] = Val; I->copyInto(*this, Addr); @@ -5203,6 +5181,7 @@ RValue CodeGenFunction::EmitCall(const CGFunctionInfo &CallInfo, Address Addr = I->hasLValue() ? I->getKnownLValue().getAddress(*this) : I->getKnownRValue().getAggregateAddress(); + llvm::Value *V = Addr.getPointer(); CharUnits Align = ArgInfo.getIndirectAlign(); const llvm::DataLayout *TD = &CGM.getDataLayout(); @@ -5213,9 +5192,8 @@ RValue CodeGenFunction::EmitCall(const CGFunctionInfo &CallInfo, bool NeedCopy = false; if (Addr.getAlignment() < Align && - llvm::getOrEnforceKnownAlignment(Addr.emitRawPointer(*this), - Align.getAsAlign(), - *TD) < Align.getAsAlign()) { + llvm::getOrEnforceKnownAlignment(V, Align.getAsAlign(), *TD) < + Align.getAsAlign()) { NeedCopy = true; } else if (I->hasLValue()) { auto LV = I->getKnownLValue(); @@ -5246,11 +5224,11 @@ RValue CodeGenFunction::EmitCall(const CGFunctionInfo &CallInfo, if (NeedCopy) { // Create an aligned temporary, and copy to it. - RawAddress AI = CreateMemTempWithoutCast( + Address AI = CreateMemTempWithoutCast( I->Ty, ArgInfo.getIndirectAlign(), "byval-temp"); - llvm::Value *Val = getAsNaturalPointerTo(AI, I->Ty); + llvm::Value *Val = AI.getPointer(); if (ArgHasMaybeUndefAttr) - Val = Builder.CreateFreeze(Val); + Val = Builder.CreateFreeze(AI.getPointer()); IRCallArgs[FirstIRArg] = Val; // Emit lifetime markers for the temporary alloca. @@ -5267,7 +5245,6 @@ RValue CodeGenFunction::EmitCall(const CGFunctionInfo &CallInfo, I->copyInto(*this, AI); } else { // Skip the extra memcpy call. - llvm::Value *V = getAsNaturalPointerTo(Addr, I->Ty); auto *T = llvm::PointerType::get( CGM.getLLVMContext(), CGM.getDataLayout().getAllocaAddrSpace()); @@ -5307,8 +5284,8 @@ RValue CodeGenFunction::EmitCall(const CGFunctionInfo &CallInfo, assert(!swiftErrorTemp.isValid() && "multiple swifterror args"); QualType pointeeTy = I->Ty->getPointeeType(); - swiftErrorArg = makeNaturalAddressForPointer( - V, pointeeTy, getContext().getTypeAlignInChars(pointeeTy)); + swiftErrorArg = Address(V, ConvertTypeForMem(pointeeTy), + getContext().getTypeAlignInChars(pointeeTy)); swiftErrorTemp = CreateMemTemp(pointeeTy, getPointerAlign(), "swifterror.temp"); @@ -5445,7 +5422,7 @@ RValue CodeGenFunction::EmitCall(const CGFunctionInfo &CallInfo, llvm::Value *tempSize = nullptr; Address addr = Address::invalid(); - RawAddress AllocaAddr = RawAddress::invalid(); + Address AllocaAddr = Address::invalid(); if (I->isAggregate()) { addr = I->hasLValue() ? I->getKnownLValue().getAddress(*this) : I->getKnownRValue().getAggregateAddress(); @@ -5879,7 +5856,7 @@ RValue CodeGenFunction::EmitCall(const CGFunctionInfo &CallInfo, return RValue::getComplex(std::make_pair(Real, Imag)); } case TEK_Aggregate: { - Address DestPtr = ReturnValue.getAddress(); + Address DestPtr = ReturnValue.getValue(); bool DestIsVolatile = ReturnValue.isVolatile(); if (!DestPtr.isValid()) { diff --git a/clang/lib/CodeGen/CGCall.h b/clang/lib/CodeGen/CGCall.h index 6b676ac196db..1bd48a072593 100644 --- a/clang/lib/CodeGen/CGCall.h +++ b/clang/lib/CodeGen/CGCall.h @@ -377,7 +377,6 @@ public: Address getValue() const { return Addr; } bool isUnused() const { return IsUnused; } bool isExternallyDestructed() const { return IsExternallyDestructed; } - Address getAddress() const { return Addr; } }; /// Adds attributes to \p F according to our \p CodeGenOpts and \p LangOpts, as diff --git a/clang/lib/CodeGen/CGClass.cpp b/clang/lib/CodeGen/CGClass.cpp index 8c1c8ee455d2..34319381901a 100644 --- a/clang/lib/CodeGen/CGClass.cpp +++ b/clang/lib/CodeGen/CGClass.cpp @@ -139,9 +139,8 @@ Address CodeGenFunction::LoadCXXThisAddress() { CXXThisAlignment = CGM.getClassPointerAlignment(MD->getParent()); } - return makeNaturalAddressForPointer( - LoadCXXThis(), MD->getFunctionObjectParameterType(), CXXThisAlignment, - false, nullptr, nullptr, KnownNonNull); + llvm::Type *Ty = ConvertType(MD->getFunctionObjectParameterType()); + return Address(LoadCXXThis(), Ty, CXXThisAlignment, KnownNonNull); } /// Emit the address of a field using a member data pointer. @@ -271,7 +270,7 @@ ApplyNonVirtualAndVirtualOffset(CodeGenFunction &CGF, Address addr, } // Apply the base offset. - llvm::Value *ptr = addr.emitRawPointer(CGF); + llvm::Value *ptr = addr.getPointer(); ptr = CGF.Builder.CreateInBoundsGEP(CGF.Int8Ty, ptr, baseOffset, "add.ptr"); // If we have a virtual component, the alignment of the result will @@ -339,8 +338,8 @@ Address CodeGenFunction::GetAddressOfBaseClass( if (sanitizePerformTypeCheck()) { SanitizerSet SkippedChecks; SkippedChecks.set(SanitizerKind::Null, !NullCheckValue); - EmitTypeCheck(TCK_Upcast, Loc, Value.emitRawPointer(*this), DerivedTy, - DerivedAlign, SkippedChecks); + EmitTypeCheck(TCK_Upcast, Loc, Value.getPointer(), + DerivedTy, DerivedAlign, SkippedChecks); } return Value.withElementType(BaseValueTy); } @@ -355,7 +354,7 @@ Address CodeGenFunction::GetAddressOfBaseClass( llvm::BasicBlock *notNullBB = createBasicBlock("cast.notnull"); endBB = createBasicBlock("cast.end"); - llvm::Value *isNull = Builder.CreateIsNull(Value); + llvm::Value *isNull = Builder.CreateIsNull(Value.getPointer()); Builder.CreateCondBr(isNull, endBB, notNullBB); EmitBlock(notNullBB); } @@ -364,15 +363,14 @@ Address CodeGenFunction::GetAddressOfBaseClass( SanitizerSet SkippedChecks; SkippedChecks.set(SanitizerKind::Null, true); EmitTypeCheck(VBase ? TCK_UpcastToVirtualBase : TCK_Upcast, Loc, - Value.emitRawPointer(*this), DerivedTy, DerivedAlign, - SkippedChecks); + Value.getPointer(), DerivedTy, DerivedAlign, SkippedChecks); } // Compute the virtual offset. llvm::Value *VirtualOffset = nullptr; if (VBase) { VirtualOffset = - CGM.getCXXABI().GetVirtualBaseClassOffset(*this, Value, Derived, VBase); + CGM.getCXXABI().GetVirtualBaseClassOffset(*this, Value, Derived, VBase); } // Apply both offsets. @@ -389,7 +387,7 @@ Address CodeGenFunction::GetAddressOfBaseClass( EmitBlock(endBB); llvm::PHINode *PHI = Builder.CreatePHI(PtrTy, 2, "cast.result"); - PHI->addIncoming(Value.emitRawPointer(*this), notNullBB); + PHI->addIncoming(Value.getPointer(), notNullBB); PHI->addIncoming(llvm::Constant::getNullValue(PtrTy), origBB); Value = Value.withPointer(PHI, NotKnownNonNull); } @@ -426,19 +424,15 @@ CodeGenFunction::GetAddressOfDerivedClass(Address BaseAddr, CastNotNull = createBasicBlock("cast.notnull"); CastEnd = createBasicBlock("cast.end"); - llvm::Value *IsNull = Builder.CreateIsNull(BaseAddr); + llvm::Value *IsNull = Builder.CreateIsNull(BaseAddr.getPointer()); Builder.CreateCondBr(IsNull, CastNull, CastNotNull); EmitBlock(CastNotNull); } // Apply the offset. - Address Addr = BaseAddr.withElementType(Int8Ty); - Addr = Builder.CreateInBoundsGEP( - Addr, Builder.CreateNeg(NonVirtualOffset), Int8Ty, - CGM.getClassPointerAlignment(Derived), "sub.ptr"); - - // Just cast. - Addr = Addr.withElementType(DerivedValueTy); + llvm::Value *Value = BaseAddr.getPointer(); + Value = Builder.CreateInBoundsGEP( + Int8Ty, Value, Builder.CreateNeg(NonVirtualOffset), "sub.ptr"); // Produce a PHI if we had a null-check. if (NullCheckValue) { @@ -447,15 +441,13 @@ CodeGenFunction::GetAddressOfDerivedClass(Address BaseAddr, Builder.CreateBr(CastEnd); EmitBlock(CastEnd); - llvm::Value *Value = Addr.emitRawPointer(*this); llvm::PHINode *PHI = Builder.CreatePHI(Value->getType(), 2); PHI->addIncoming(Value, CastNotNull); PHI->addIncoming(llvm::Constant::getNullValue(Value->getType()), CastNull); - return Address(PHI, Addr.getElementType(), - CGM.getClassPointerAlignment(Derived)); + Value = PHI; } - return Addr; + return Address(Value, DerivedValueTy, CGM.getClassPointerAlignment(Derived)); } llvm::Value *CodeGenFunction::GetVTTParameter(GlobalDecl GD, @@ -1727,7 +1719,7 @@ namespace { // Use the base class declaration location as inline DebugLocation. All // fields of the class are destroyed. DeclAsInlineDebugLocation InlineHere(CGF, *BaseClass); - EmitSanitizerDtorFieldsCallback(CGF, Addr.emitRawPointer(CGF), + EmitSanitizerDtorFieldsCallback(CGF, Addr.getPointer(), BaseSize.getQuantity()); // Prevent the current stack frame from disappearing from the stack trace. @@ -2030,7 +2022,7 @@ void CodeGenFunction::EmitCXXAggrConstructorCall(const CXXConstructorDecl *ctor, // Find the end of the array. llvm::Type *elementType = arrayBase.getElementType(); - llvm::Value *arrayBegin = arrayBase.emitRawPointer(*this); + llvm::Value *arrayBegin = arrayBase.getPointer(); llvm::Value *arrayEnd = Builder.CreateInBoundsGEP( elementType, arrayBegin, numElements, "arrayctor.end"); @@ -2126,15 +2118,14 @@ void CodeGenFunction::EmitCXXConstructorCall(const CXXConstructorDecl *D, Address This = ThisAVS.getAddress(); LangAS SlotAS = ThisAVS.getQualifiers().getAddressSpace(); LangAS ThisAS = D->getFunctionObjectParameterType().getAddressSpace(); - llvm::Value *ThisPtr = - getAsNaturalPointerTo(This, D->getThisType()->getPointeeType()); + llvm::Value *ThisPtr = This.getPointer(); if (SlotAS != ThisAS) { unsigned TargetThisAS = getContext().getTargetAddressSpace(ThisAS); llvm::Type *NewType = llvm::PointerType::get(getLLVMContext(), TargetThisAS); - ThisPtr = getTargetHooks().performAddrSpaceCast(*this, ThisPtr, ThisAS, - SlotAS, NewType); + ThisPtr = getTargetHooks().performAddrSpaceCast(*this, This.getPointer(), + ThisAS, SlotAS, NewType); } // Push the this ptr. @@ -2203,7 +2194,7 @@ void CodeGenFunction::EmitCXXConstructorCall(const CXXConstructorDecl *D, const CXXRecordDecl *ClassDecl = D->getParent(); if (!NewPointerIsChecked) - EmitTypeCheck(CodeGenFunction::TCK_ConstructorCall, Loc, This, + EmitTypeCheck(CodeGenFunction::TCK_ConstructorCall, Loc, This.getPointer(), getContext().getRecordType(ClassDecl), CharUnits::Zero()); if (D->isTrivial() && D->isDefaultConstructor()) { @@ -2216,9 +2207,10 @@ void CodeGenFunction::EmitCXXConstructorCall(const CXXConstructorDecl *D, // model that copy. if (isMemcpyEquivalentSpecialMember(D)) { assert(Args.size() == 2 && "unexpected argcount for trivial ctor"); + QualType SrcTy = D->getParamDecl(0)->getType().getNonReferenceType(); - Address Src = makeNaturalAddressForPointer( - Args[1].getRValue(*this).getScalarVal(), SrcTy); + Address Src = Address(Args[1].getRValue(*this).getScalarVal(), ConvertTypeForMem(SrcTy), + CGM.getNaturalTypeAlignment(SrcTy)); LValue SrcLVal = MakeAddrLValue(Src, SrcTy); QualType DestTy = getContext().getTypeDeclType(ClassDecl); LValue DestLVal = MakeAddrLValue(This, DestTy); @@ -2271,9 +2263,7 @@ void CodeGenFunction::EmitInheritedCXXConstructorCall( const CXXConstructorDecl *D, bool ForVirtualBase, Address This, bool InheritedFromVBase, const CXXInheritedCtorInitExpr *E) { CallArgList Args; - CallArg ThisArg(RValue::get(getAsNaturalPointerTo( - This, D->getThisType()->getPointeeType())), - D->getThisType()); + CallArg ThisArg(RValue::get(This.getPointer()), D->getThisType()); // Forward the parameters. if (InheritedFromVBase && @@ -2398,14 +2388,12 @@ CodeGenFunction::EmitSynthesizedCXXCopyCtorCall(const CXXConstructorDecl *D, CallArgList Args; // Push the this ptr. - Args.add(RValue::get(getAsNaturalPointerTo(This, D->getThisType())), - D->getThisType()); + Args.add(RValue::get(This.getPointer()), D->getThisType()); // Push the src ptr. QualType QT = *(FPT->param_type_begin()); llvm::Type *t = CGM.getTypes().ConvertType(QT); - llvm::Value *Val = getAsNaturalPointerTo(Src, D->getThisType()); - llvm::Value *SrcVal = Builder.CreateBitCast(Val, t); + llvm::Value *SrcVal = Builder.CreateBitCast(Src.getPointer(), t); Args.add(RValue::get(SrcVal), QT); // Skip over first argument (Src). @@ -2430,9 +2418,7 @@ CodeGenFunction::EmitDelegateCXXConstructorCall(const CXXConstructorDecl *Ctor, // this Address This = LoadCXXThisAddress(); - DelegateArgs.add(RValue::get(getAsNaturalPointerTo( - This, (*I)->getType()->getPointeeType())), - (*I)->getType()); + DelegateArgs.add(RValue::get(This.getPointer()), (*I)->getType()); ++I; // FIXME: The location of the VTT parameter in the parameter list is @@ -2789,7 +2775,7 @@ void CodeGenFunction::EmitVTablePtrCheckForCast(QualType T, Address Derived, if (MayBeNull) { llvm::Value *DerivedNotNull = - Builder.CreateIsNotNull(Derived.emitRawPointer(*this), "cast.nonnull"); + Builder.CreateIsNotNull(Derived.getPointer(), "cast.nonnull"); llvm::BasicBlock *CheckBlock = createBasicBlock("cast.check"); ContBlock = createBasicBlock("cast.cont"); @@ -2990,7 +2976,7 @@ void CodeGenFunction::EmitLambdaBlockInvokeBody() { QualType ThisType = getContext().getPointerType(getContext().getRecordType(Lambda)); Address ThisPtr = GetAddrOfBlockDecl(variable); - CallArgs.add(RValue::get(getAsNaturalPointerTo(ThisPtr, ThisType)), ThisType); + CallArgs.add(RValue::get(ThisPtr.getPointer()), ThisType); // Add the rest of the parameters. for (auto *param : BD->parameters()) @@ -3018,7 +3004,7 @@ void CodeGenFunction::EmitLambdaStaticInvokeBody(const CXXMethodDecl *MD) { QualType LambdaType = getContext().getRecordType(Lambda); QualType ThisType = getContext().getPointerType(LambdaType); Address ThisPtr = CreateMemTemp(LambdaType, "unused.capture"); - CallArgs.add(RValue::get(ThisPtr.emitRawPointer(*this)), ThisType); + CallArgs.add(RValue::get(ThisPtr.getPointer()), ThisType); EmitLambdaDelegatingInvokeBody(MD, CallArgs); } diff --git a/clang/lib/CodeGen/CGCleanup.cpp b/clang/lib/CodeGen/CGCleanup.cpp index e6f8e6873004..f87caf050eea 100644 --- a/clang/lib/CodeGen/CGCleanup.cpp +++ b/clang/lib/CodeGen/CGCleanup.cpp @@ -27,7 +27,7 @@ bool DominatingValue::saved_type::needsSaving(RValue rv) { if (rv.isScalar()) return DominatingLLVMValue::needsSaving(rv.getScalarVal()); if (rv.isAggregate()) - return DominatingValue
::needsSaving(rv.getAggregateAddress()); + return DominatingLLVMValue::needsSaving(rv.getAggregatePointer()); return true; } @@ -35,40 +35,69 @@ DominatingValue::saved_type DominatingValue::saved_type::save(CodeGenFunction &CGF, RValue rv) { if (rv.isScalar()) { llvm::Value *V = rv.getScalarVal(); - return saved_type(DominatingLLVMValue::save(CGF, V), - DominatingLLVMValue::needsSaving(V) ? ScalarAddress - : ScalarLiteral); + + // These automatically dominate and don't need to be saved. + if (!DominatingLLVMValue::needsSaving(V)) + return saved_type(V, nullptr, ScalarLiteral); + + // Everything else needs an alloca. + Address addr = + CGF.CreateDefaultAlignTempAlloca(V->getType(), "saved-rvalue"); + CGF.Builder.CreateStore(V, addr); + return saved_type(addr.getPointer(), nullptr, ScalarAddress); } if (rv.isComplex()) { CodeGenFunction::ComplexPairTy V = rv.getComplexVal(); - return saved_type(DominatingLLVMValue::save(CGF, V.first), - DominatingLLVMValue::save(CGF, V.second)); + llvm::Type *ComplexTy = + llvm::StructType::get(V.first->getType(), V.second->getType()); + Address addr = CGF.CreateDefaultAlignTempAlloca(ComplexTy, "saved-complex"); + CGF.Builder.CreateStore(V.first, CGF.Builder.CreateStructGEP(addr, 0)); + CGF.Builder.CreateStore(V.second, CGF.Builder.CreateStructGEP(addr, 1)); + return saved_type(addr.getPointer(), nullptr, ComplexAddress); } assert(rv.isAggregate()); - Address V = rv.getAggregateAddress(); - return saved_type( - DominatingValue
::save(CGF, V), rv.isVolatileQualified(), - DominatingValue
::needsSaving(V) ? AggregateAddress - : AggregateLiteral); + Address V = rv.getAggregateAddress(); // TODO: volatile? + if (!DominatingLLVMValue::needsSaving(V.getPointer())) + return saved_type(V.getPointer(), V.getElementType(), AggregateLiteral, + V.getAlignment().getQuantity()); + + Address addr = + CGF.CreateTempAlloca(V.getType(), CGF.getPointerAlign(), "saved-rvalue"); + CGF.Builder.CreateStore(V.getPointer(), addr); + return saved_type(addr.getPointer(), V.getElementType(), AggregateAddress, + V.getAlignment().getQuantity()); } /// Given a saved r-value produced by SaveRValue, perform the code /// necessary to restore it to usability at the current insertion /// point. RValue DominatingValue::saved_type::restore(CodeGenFunction &CGF) { + auto getSavingAddress = [&](llvm::Value *value) { + auto *AI = cast(value); + return Address(value, AI->getAllocatedType(), + CharUnits::fromQuantity(AI->getAlign().value())); + }; switch (K) { case ScalarLiteral: + return RValue::get(Value); case ScalarAddress: - return RValue::get(DominatingLLVMValue::restore(CGF, Vals.first)); + return RValue::get(CGF.Builder.CreateLoad(getSavingAddress(Value))); case AggregateLiteral: - case AggregateAddress: return RValue::getAggregate( - DominatingValue
::restore(CGF, AggregateAddr), IsVolatile); + Address(Value, ElementType, CharUnits::fromQuantity(Align))); + case AggregateAddress: { + auto addr = CGF.Builder.CreateLoad(getSavingAddress(Value)); + return RValue::getAggregate( + Address(addr, ElementType, CharUnits::fromQuantity(Align))); + } case ComplexAddress: { - llvm::Value *real = DominatingLLVMValue::restore(CGF, Vals.first); - llvm::Value *imag = DominatingLLVMValue::restore(CGF, Vals.second); + Address address = getSavingAddress(Value); + llvm::Value *real = + CGF.Builder.CreateLoad(CGF.Builder.CreateStructGEP(address, 0)); + llvm::Value *imag = + CGF.Builder.CreateLoad(CGF.Builder.CreateStructGEP(address, 1)); return RValue::getComplex(real, imag); } } @@ -265,14 +294,14 @@ void EHScopeStack::popNullFixups() { BranchFixups.pop_back(); } -RawAddress CodeGenFunction::createCleanupActiveFlag() { +Address CodeGenFunction::createCleanupActiveFlag() { // Create a variable to decide whether the cleanup needs to be run. - RawAddress active = CreateTempAllocaWithoutCast( + Address active = CreateTempAllocaWithoutCast( Builder.getInt1Ty(), CharUnits::One(), "cleanup.cond"); // Initialize it to false at a site that's guaranteed to be run // before each evaluation. - setBeforeOutermostConditional(Builder.getFalse(), active, *this); + setBeforeOutermostConditional(Builder.getFalse(), active); // Initialize it to true at the current location. Builder.CreateStore(Builder.getTrue(), active); @@ -280,7 +309,7 @@ RawAddress CodeGenFunction::createCleanupActiveFlag() { return active; } -void CodeGenFunction::initFullExprCleanupWithFlag(RawAddress ActiveFlag) { +void CodeGenFunction::initFullExprCleanupWithFlag(Address ActiveFlag) { // Set that as the active flag in the cleanup. EHCleanupScope &cleanup = cast(*EHStack.begin()); assert(!cleanup.hasActiveFlag() && "cleanup already has active flag?"); @@ -293,17 +322,15 @@ void CodeGenFunction::initFullExprCleanupWithFlag(RawAddress ActiveFlag) { void EHScopeStack::Cleanup::anchor() {} static void createStoreInstBefore(llvm::Value *value, Address addr, - llvm::Instruction *beforeInst, - CodeGenFunction &CGF) { - auto store = new llvm::StoreInst(value, addr.emitRawPointer(CGF), beforeInst); + llvm::Instruction *beforeInst) { + auto store = new llvm::StoreInst(value, addr.getPointer(), beforeInst); store->setAlignment(addr.getAlignment().getAsAlign()); } static llvm::LoadInst *createLoadInstBefore(Address addr, const Twine &name, - llvm::Instruction *beforeInst, - CodeGenFunction &CGF) { - return new llvm::LoadInst(addr.getElementType(), addr.emitRawPointer(CGF), - name, false, addr.getAlignment().getAsAlign(), + llvm::Instruction *beforeInst) { + return new llvm::LoadInst(addr.getElementType(), addr.getPointer(), name, + false, addr.getAlignment().getAsAlign(), beforeInst); } @@ -330,8 +357,8 @@ static void ResolveAllBranchFixups(CodeGenFunction &CGF, // entry which we're currently popping. if (Fixup.OptimisticBranchBlock == nullptr) { createStoreInstBefore(CGF.Builder.getInt32(Fixup.DestinationIndex), - CGF.getNormalCleanupDestSlot(), Fixup.InitialBranch, - CGF); + CGF.getNormalCleanupDestSlot(), + Fixup.InitialBranch); Fixup.InitialBranch->setSuccessor(0, CleanupEntry); } @@ -358,7 +385,7 @@ static llvm::SwitchInst *TransitionToCleanupSwitch(CodeGenFunction &CGF, if (llvm::BranchInst *Br = dyn_cast(Term)) { assert(Br->isUnconditional()); auto Load = createLoadInstBefore(CGF.getNormalCleanupDestSlot(), - "cleanup.dest", Term, CGF); + "cleanup.dest", Term); llvm::SwitchInst *Switch = llvm::SwitchInst::Create(Load, Br->getSuccessor(0), 4, Block); Br->eraseFromParent(); @@ -486,8 +513,8 @@ void CodeGenFunction::PopCleanupBlocks( I += Header.getSize(); if (Header.isConditional()) { - RawAddress ActiveFlag = - reinterpret_cast(LifetimeExtendedCleanupStack[I]); + Address ActiveFlag = + reinterpret_cast
(LifetimeExtendedCleanupStack[I]); initFullExprCleanupWithFlag(ActiveFlag); I += sizeof(ActiveFlag); } @@ -861,7 +888,7 @@ void CodeGenFunction::PopCleanupBlock(bool FallthroughIsBranchThrough) { if (NormalCleanupDestSlot->hasOneUse()) { NormalCleanupDestSlot->user_back()->eraseFromParent(); NormalCleanupDestSlot->eraseFromParent(); - NormalCleanupDest = RawAddress::invalid(); + NormalCleanupDest = Address::invalid(); } llvm::BasicBlock *BranchAfter = Scope.getBranchAfterBlock(0); @@ -885,8 +912,9 @@ void CodeGenFunction::PopCleanupBlock(bool FallthroughIsBranchThrough) { // pass the abnormal exit flag to Fn (SEH cleanup) cleanupFlags.setHasExitSwitch(); - llvm::LoadInst *Load = createLoadInstBefore( - getNormalCleanupDestSlot(), "cleanup.dest", nullptr, *this); + llvm::LoadInst *Load = + createLoadInstBefore(getNormalCleanupDestSlot(), "cleanup.dest", + nullptr); llvm::SwitchInst *Switch = llvm::SwitchInst::Create(Load, Default, SwitchCapacity); @@ -933,8 +961,8 @@ void CodeGenFunction::PopCleanupBlock(bool FallthroughIsBranchThrough) { if (!Fixup.Destination) continue; if (!Fixup.OptimisticBranchBlock) { createStoreInstBefore(Builder.getInt32(Fixup.DestinationIndex), - getNormalCleanupDestSlot(), Fixup.InitialBranch, - *this); + getNormalCleanupDestSlot(), + Fixup.InitialBranch); Fixup.InitialBranch->setSuccessor(0, NormalEntry); } Fixup.OptimisticBranchBlock = NormalExit; @@ -1107,7 +1135,7 @@ void CodeGenFunction::EmitBranchThroughCleanup(JumpDest Dest) { // Store the index at the start. llvm::ConstantInt *Index = Builder.getInt32(Dest.getDestIndex()); - createStoreInstBefore(Index, getNormalCleanupDestSlot(), BI, *this); + createStoreInstBefore(Index, getNormalCleanupDestSlot(), BI); // Adjust BI to point to the first cleanup block. { @@ -1241,9 +1269,9 @@ static void SetupCleanupBlockActivation(CodeGenFunction &CGF, // If we're in a conditional block, ignore the dominating IP and // use the outermost conditional branch. if (CGF.isInConditionalBranch()) { - CGF.setBeforeOutermostConditional(value, var, CGF); + CGF.setBeforeOutermostConditional(value, var); } else { - createStoreInstBefore(value, var, dominatingIP, CGF); + createStoreInstBefore(value, var, dominatingIP); } } @@ -1293,7 +1321,7 @@ void CodeGenFunction::DeactivateCleanupBlock(EHScopeStack::stable_iterator C, Scope.setActive(false); } -RawAddress CodeGenFunction::getNormalCleanupDestSlot() { +Address CodeGenFunction::getNormalCleanupDestSlot() { if (!NormalCleanupDest.isValid()) NormalCleanupDest = CreateDefaultAlignTempAlloca(Builder.getInt32Ty(), "cleanup.dest.slot"); diff --git a/clang/lib/CodeGen/CGCleanup.h b/clang/lib/CodeGen/CGCleanup.h index 03e4a29d7b3d..7a7344c07160 100644 --- a/clang/lib/CodeGen/CGCleanup.h +++ b/clang/lib/CodeGen/CGCleanup.h @@ -333,7 +333,7 @@ public: Address getActiveFlag() const { return ActiveFlag; } - void setActiveFlag(RawAddress Var) { + void setActiveFlag(Address Var) { assert(Var.getAlignment().isOne()); ActiveFlag = Var; } diff --git a/clang/lib/CodeGen/CGCoroutine.cpp b/clang/lib/CodeGen/CGCoroutine.cpp index 93ca711f716f..b7142ec08af9 100644 --- a/clang/lib/CodeGen/CGCoroutine.cpp +++ b/clang/lib/CodeGen/CGCoroutine.cpp @@ -867,8 +867,8 @@ void CodeGenFunction::EmitCoroutineBody(const CoroutineBodyStmt &S) { EmitStmt(S.getPromiseDeclStmt()); Address PromiseAddr = GetAddrOfLocalVar(S.getPromiseDecl()); - auto *PromiseAddrVoidPtr = new llvm::BitCastInst( - PromiseAddr.emitRawPointer(*this), VoidPtrTy, "", CoroId); + auto *PromiseAddrVoidPtr = + new llvm::BitCastInst(PromiseAddr.getPointer(), VoidPtrTy, "", CoroId); // Update CoroId to refer to the promise. We could not do it earlier because // promise local variable was not emitted yet. CoroId->setArgOperand(1, PromiseAddrVoidPtr); diff --git a/clang/lib/CodeGen/CGDecl.cpp b/clang/lib/CodeGen/CGDecl.cpp index 267f2e40a7bb..2ef5ed04af30 100644 --- a/clang/lib/CodeGen/CGDecl.cpp +++ b/clang/lib/CodeGen/CGDecl.cpp @@ -1461,7 +1461,7 @@ CodeGenFunction::EmitAutoVarAlloca(const VarDecl &D) { bool EmitDebugInfo = DI && CGM.getCodeGenOpts().hasReducedDebugInfo(); Address address = Address::invalid(); - RawAddress AllocaAddr = RawAddress::invalid(); + Address AllocaAddr = Address::invalid(); Address OpenMPLocalAddr = Address::invalid(); if (CGM.getLangOpts().OpenMPIRBuilder) OpenMPLocalAddr = OMPBuilderCBHelpers::getAddressOfLocalVariable(*this, &D); @@ -1524,10 +1524,7 @@ CodeGenFunction::EmitAutoVarAlloca(const VarDecl &D) { // return slot, so that we can elide the copy when returning this // variable (C++0x [class.copy]p34). address = ReturnValue; - AllocaAddr = - RawAddress(ReturnValue.emitRawPointer(*this), - ReturnValue.getElementType(), ReturnValue.getAlignment()); - ; + AllocaAddr = ReturnValue; if (const RecordType *RecordTy = Ty->getAs()) { const auto *RD = RecordTy->getDecl(); @@ -1538,7 +1535,7 @@ CodeGenFunction::EmitAutoVarAlloca(const VarDecl &D) { // to this variable. Set it to zero to indicate that NRVO was not // applied. llvm::Value *Zero = Builder.getFalse(); - RawAddress NRVOFlag = + Address NRVOFlag = CreateTempAlloca(Zero->getType(), CharUnits::One(), "nrvo"); EnsureInsertPoint(); Builder.CreateStore(Zero, NRVOFlag); @@ -1681,7 +1678,7 @@ CodeGenFunction::EmitAutoVarAlloca(const VarDecl &D) { } if (D.hasAttr() && HaveInsertPoint()) - EmitVarAnnotations(&D, address.emitRawPointer(*this)); + EmitVarAnnotations(&D, address.getPointer()); // Make sure we call @llvm.lifetime.end. if (emission.useLifetimeMarkers()) @@ -1854,13 +1851,12 @@ void CodeGenFunction::emitZeroOrPatternForAutoVarInit(QualType type, llvm::Value *BaseSizeInChars = llvm::ConstantInt::get(IntPtrTy, EltSize.getQuantity()); Address Begin = Loc.withElementType(Int8Ty); - llvm::Value *End = Builder.CreateInBoundsGEP(Begin.getElementType(), - Begin.emitRawPointer(*this), - SizeVal, "vla.end"); + llvm::Value *End = Builder.CreateInBoundsGEP( + Begin.getElementType(), Begin.getPointer(), SizeVal, "vla.end"); llvm::BasicBlock *OriginBB = Builder.GetInsertBlock(); EmitBlock(LoopBB); llvm::PHINode *Cur = Builder.CreatePHI(Begin.getType(), 2, "vla.cur"); - Cur->addIncoming(Begin.emitRawPointer(*this), OriginBB); + Cur->addIncoming(Begin.getPointer(), OriginBB); CharUnits CurAlign = Loc.getAlignment().alignmentOfArrayElement(EltSize); auto *I = Builder.CreateMemCpy(Address(Cur, Int8Ty, CurAlign), @@ -2287,7 +2283,7 @@ void CodeGenFunction::emitDestroy(Address addr, QualType type, checkZeroLength = false; } - llvm::Value *begin = addr.emitRawPointer(*this); + llvm::Value *begin = addr.getPointer(); llvm::Value *end = Builder.CreateInBoundsGEP(addr.getElementType(), begin, length); emitArrayDestroy(begin, end, type, elementAlign, destroyer, @@ -2547,7 +2543,7 @@ void CodeGenFunction::EmitParmDecl(const VarDecl &D, ParamValue Arg, } Address DeclPtr = Address::invalid(); - RawAddress AllocaPtr = Address::invalid(); + Address AllocaPtr = Address::invalid(); bool DoStore = false; bool IsScalar = hasScalarEvaluationKind(Ty); bool UseIndirectDebugAddress = false; @@ -2559,8 +2555,8 @@ void CodeGenFunction::EmitParmDecl(const VarDecl &D, ParamValue Arg, // Indirect argument is in alloca address space, which may be different // from the default address space. auto AllocaAS = CGM.getASTAllocaAddressSpace(); - auto *V = DeclPtr.emitRawPointer(*this); - AllocaPtr = RawAddress(V, DeclPtr.getElementType(), DeclPtr.getAlignment()); + auto *V = DeclPtr.getPointer(); + AllocaPtr = DeclPtr; // For truly ABI indirect arguments -- those that are not `byval` -- store // the address of the argument on the stack to preserve debug information. @@ -2699,7 +2695,7 @@ void CodeGenFunction::EmitParmDecl(const VarDecl &D, ParamValue Arg, } if (D.hasAttr()) - EmitVarAnnotations(&D, DeclPtr.emitRawPointer(*this)); + EmitVarAnnotations(&D, DeclPtr.getPointer()); // We can only check return value nullability if all arguments to the // function satisfy their nullability preconditions. This makes it necessary diff --git a/clang/lib/CodeGen/CGException.cpp b/clang/lib/CodeGen/CGException.cpp index 34f289334a7d..5a9d06da12de 100644 --- a/clang/lib/CodeGen/CGException.cpp +++ b/clang/lib/CodeGen/CGException.cpp @@ -397,7 +397,7 @@ namespace { void CodeGenFunction::EmitAnyExprToExn(const Expr *e, Address addr) { // Make sure the exception object is cleaned up if there's an // exception during initialization. - pushFullExprCleanup(EHCleanup, addr.emitRawPointer(*this)); + pushFullExprCleanup(EHCleanup, addr.getPointer()); EHScopeStack::stable_iterator cleanup = EHStack.stable_begin(); // __cxa_allocate_exception returns a void*; we need to cast this @@ -416,8 +416,8 @@ void CodeGenFunction::EmitAnyExprToExn(const Expr *e, Address addr) { /*IsInit*/ true); // Deactivate the cleanup block. - DeactivateCleanupBlock( - cleanup, cast(typedAddr.emitRawPointer(*this))); + DeactivateCleanupBlock(cleanup, + cast(typedAddr.getPointer())); } Address CodeGenFunction::getExceptionSlot() { @@ -1834,8 +1834,7 @@ Address CodeGenFunction::recoverAddrOfEscapedLocal(CodeGenFunction &ParentCGF, llvm::Value *ParentFP) { llvm::CallInst *RecoverCall = nullptr; CGBuilderTy Builder(*this, AllocaInsertPt); - if (auto *ParentAlloca = - dyn_cast_or_null(ParentVar.getBasePointer())) { + if (auto *ParentAlloca = dyn_cast(ParentVar.getPointer())) { // Mark the variable escaped if nobody else referenced it and compute the // localescape index. auto InsertPair = ParentCGF.EscapedLocals.insert( @@ -1852,8 +1851,8 @@ Address CodeGenFunction::recoverAddrOfEscapedLocal(CodeGenFunction &ParentCGF, // If the parent didn't have an alloca, we're doing some nested outlining. // Just clone the existing localrecover call, but tweak the FP argument to // use our FP value. All other arguments are constants. - auto *ParentRecover = cast( - ParentVar.emitRawPointer(*this)->stripPointerCasts()); + auto *ParentRecover = + cast(ParentVar.getPointer()->stripPointerCasts()); assert(ParentRecover->getIntrinsicID() == llvm::Intrinsic::localrecover && "expected alloca or localrecover in parent LocalDeclMap"); RecoverCall = cast(ParentRecover->clone()); @@ -1926,8 +1925,7 @@ void CodeGenFunction::EmitCapturedLocals(CodeGenFunction &ParentCGF, if (isa(D) && D->getType() == getContext().VoidPtrTy) { assert(D->getName().starts_with("frame_pointer")); - FramePtrAddrAlloca = - cast(I.second.getBasePointer()); + FramePtrAddrAlloca = cast(I.second.getPointer()); break; } } @@ -1988,8 +1986,7 @@ void CodeGenFunction::EmitCapturedLocals(CodeGenFunction &ParentCGF, LValue ThisFieldLValue = EmitLValueForLambdaField(LambdaThisCaptureField); if (!LambdaThisCaptureField->getType()->isPointerType()) { - CXXThisValue = - ThisFieldLValue.getAddress(*this).emitRawPointer(*this); + CXXThisValue = ThisFieldLValue.getAddress(*this).getPointer(); } else { CXXThisValue = EmitLoadOfLValue(ThisFieldLValue, SourceLocation()) .getScalarVal(); diff --git a/clang/lib/CodeGen/CGExpr.cpp b/clang/lib/CodeGen/CGExpr.cpp index 36872c0fedb7..6491835cf8ef 100644 --- a/clang/lib/CodeGen/CGExpr.cpp +++ b/clang/lib/CodeGen/CGExpr.cpp @@ -65,21 +65,21 @@ static llvm::cl::opt ClSanitizeDebugDeoptimization( /// CreateTempAlloca - This creates a alloca and inserts it into the entry /// block. -RawAddress -CodeGenFunction::CreateTempAllocaWithoutCast(llvm::Type *Ty, CharUnits Align, - const Twine &Name, - llvm::Value *ArraySize) { +Address CodeGenFunction::CreateTempAllocaWithoutCast(llvm::Type *Ty, + CharUnits Align, + const Twine &Name, + llvm::Value *ArraySize) { auto Alloca = CreateTempAlloca(Ty, Name, ArraySize); Alloca->setAlignment(Align.getAsAlign()); - return RawAddress(Alloca, Ty, Align, KnownNonNull); + return Address(Alloca, Ty, Align, KnownNonNull); } /// CreateTempAlloca - This creates a alloca and inserts it into the entry /// block. The alloca is casted to default address space if necessary. -RawAddress CodeGenFunction::CreateTempAlloca(llvm::Type *Ty, CharUnits Align, - const Twine &Name, - llvm::Value *ArraySize, - RawAddress *AllocaAddr) { +Address CodeGenFunction::CreateTempAlloca(llvm::Type *Ty, CharUnits Align, + const Twine &Name, + llvm::Value *ArraySize, + Address *AllocaAddr) { auto Alloca = CreateTempAllocaWithoutCast(Ty, Align, Name, ArraySize); if (AllocaAddr) *AllocaAddr = Alloca; @@ -101,7 +101,7 @@ RawAddress CodeGenFunction::CreateTempAlloca(llvm::Type *Ty, CharUnits Align, Ty->getPointerTo(DestAddrSpace), /*non-null*/ true); } - return RawAddress(V, Ty, Align, KnownNonNull); + return Address(V, Ty, Align, KnownNonNull); } /// CreateTempAlloca - This creates an alloca and inserts it into the entry @@ -120,29 +120,28 @@ llvm::AllocaInst *CodeGenFunction::CreateTempAlloca(llvm::Type *Ty, /// default alignment of the corresponding LLVM type, which is *not* /// guaranteed to be related in any way to the expected alignment of /// an AST type that might have been lowered to Ty. -RawAddress CodeGenFunction::CreateDefaultAlignTempAlloca(llvm::Type *Ty, - const Twine &Name) { +Address CodeGenFunction::CreateDefaultAlignTempAlloca(llvm::Type *Ty, + const Twine &Name) { CharUnits Align = CharUnits::fromQuantity(CGM.getDataLayout().getPrefTypeAlign(Ty)); return CreateTempAlloca(Ty, Align, Name); } -RawAddress CodeGenFunction::CreateIRTemp(QualType Ty, const Twine &Name) { +Address CodeGenFunction::CreateIRTemp(QualType Ty, const Twine &Name) { CharUnits Align = getContext().getTypeAlignInChars(Ty); return CreateTempAlloca(ConvertType(Ty), Align, Name); } -RawAddress CodeGenFunction::CreateMemTemp(QualType Ty, const Twine &Name, - RawAddress *Alloca) { +Address CodeGenFunction::CreateMemTemp(QualType Ty, const Twine &Name, + Address *Alloca) { // FIXME: Should we prefer the preferred type alignment here? return CreateMemTemp(Ty, getContext().getTypeAlignInChars(Ty), Name, Alloca); } -RawAddress CodeGenFunction::CreateMemTemp(QualType Ty, CharUnits Align, - const Twine &Name, - RawAddress *Alloca) { - RawAddress Result = CreateTempAlloca(ConvertTypeForMem(Ty), Align, Name, - /*ArraySize=*/nullptr, Alloca); +Address CodeGenFunction::CreateMemTemp(QualType Ty, CharUnits Align, + const Twine &Name, Address *Alloca) { + Address Result = CreateTempAlloca(ConvertTypeForMem(Ty), Align, Name, + /*ArraySize=*/nullptr, Alloca); if (Ty->isConstantMatrixType()) { auto *ArrayTy = cast(Result.getElementType()); @@ -155,14 +154,13 @@ RawAddress CodeGenFunction::CreateMemTemp(QualType Ty, CharUnits Align, return Result; } -RawAddress CodeGenFunction::CreateMemTempWithoutCast(QualType Ty, - CharUnits Align, - const Twine &Name) { +Address CodeGenFunction::CreateMemTempWithoutCast(QualType Ty, CharUnits Align, + const Twine &Name) { return CreateTempAllocaWithoutCast(ConvertTypeForMem(Ty), Align, Name); } -RawAddress CodeGenFunction::CreateMemTempWithoutCast(QualType Ty, - const Twine &Name) { +Address CodeGenFunction::CreateMemTempWithoutCast(QualType Ty, + const Twine &Name) { return CreateMemTempWithoutCast(Ty, getContext().getTypeAlignInChars(Ty), Name); } @@ -361,7 +359,7 @@ pushTemporaryCleanup(CodeGenFunction &CGF, const MaterializeTemporaryExpr *M, } else { CleanupFn = CGF.CGM.getAddrAndTypeOfCXXStructor( GlobalDecl(ReferenceTemporaryDtor, Dtor_Complete)); - CleanupArg = cast(ReferenceTemporary.emitRawPointer(CGF)); + CleanupArg = cast(ReferenceTemporary.getPointer()); } CGF.CGM.getCXXABI().registerGlobalDtor( CGF, *cast(M->getExtendingDecl()), CleanupFn, CleanupArg); @@ -386,10 +384,10 @@ pushTemporaryCleanup(CodeGenFunction &CGF, const MaterializeTemporaryExpr *M, } } -static RawAddress createReferenceTemporary(CodeGenFunction &CGF, - const MaterializeTemporaryExpr *M, - const Expr *Inner, - RawAddress *Alloca = nullptr) { +static Address createReferenceTemporary(CodeGenFunction &CGF, + const MaterializeTemporaryExpr *M, + const Expr *Inner, + Address *Alloca = nullptr) { auto &TCG = CGF.getTargetHooks(); switch (M->getStorageDuration()) { case SD_FullExpression: @@ -418,7 +416,7 @@ static RawAddress createReferenceTemporary(CodeGenFunction &CGF, GV->getValueType()->getPointerTo( CGF.getContext().getTargetAddressSpace(LangAS::Default))); // FIXME: Should we put the new global into a COMDAT? - return RawAddress(C, GV->getValueType(), alignment); + return Address(C, GV->getValueType(), alignment); } return CGF.CreateMemTemp(Ty, "ref.tmp", Alloca); } @@ -450,7 +448,7 @@ EmitMaterializeTemporaryExpr(const MaterializeTemporaryExpr *M) { auto ownership = M->getType().getObjCLifetime(); if (ownership != Qualifiers::OCL_None && ownership != Qualifiers::OCL_ExplicitNone) { - RawAddress Object = createReferenceTemporary(*this, M, E); + Address Object = createReferenceTemporary(*this, M, E); if (auto *Var = dyn_cast(Object.getPointer())) { llvm::Type *Ty = ConvertTypeForMem(E->getType()); Object = Object.withElementType(Ty); @@ -504,8 +502,8 @@ EmitMaterializeTemporaryExpr(const MaterializeTemporaryExpr *M) { } // Create and initialize the reference temporary. - RawAddress Alloca = Address::invalid(); - RawAddress Object = createReferenceTemporary(*this, M, E, &Alloca); + Address Alloca = Address::invalid(); + Address Object = createReferenceTemporary(*this, M, E, &Alloca); if (auto *Var = dyn_cast( Object.getPointer()->stripPointerCasts())) { llvm::Type *TemporaryType = ConvertTypeForMem(E->getType()); @@ -1113,12 +1111,12 @@ llvm::Value *CodeGenFunction::EmitCountedByFieldExpr( } else if (const MemberExpr *ME = dyn_cast(StructBase)) { LValue LV = EmitMemberExpr(ME); Address Addr = LV.getAddress(*this); - Res = Addr.emitRawPointer(*this); + Res = Addr.getPointer(); } else if (StructBase->getType()->isPointerType()) { LValueBaseInfo BaseInfo; TBAAAccessInfo TBAAInfo; Address Addr = EmitPointerWithAlignment(StructBase, &BaseInfo, &TBAAInfo); - Res = Addr.emitRawPointer(*this); + Res = Addr.getPointer(); } else { return nullptr; } @@ -1284,7 +1282,8 @@ static Address EmitPointerWithAlignment(const Expr *E, LValueBaseInfo *BaseInfo, if (InnerBaseInfo.getAlignmentSource() != AlignmentSource::Decl) { if (BaseInfo) BaseInfo->mergeForCast(TargetTypeBaseInfo); - Addr.setAlignment(Align); + Addr = Address(Addr.getPointer(), Addr.getElementType(), Align, + IsKnownNonNull); } } @@ -1301,8 +1300,8 @@ static Address EmitPointerWithAlignment(const Expr *E, LValueBaseInfo *BaseInfo, CGF.ConvertTypeForMem(E->getType()->getPointeeType()); Addr = Addr.withElementType(ElemTy); if (CE->getCastKind() == CK_AddressSpaceConversion) - Addr = CGF.Builder.CreateAddrSpaceCast( - Addr, CGF.ConvertType(E->getType()), ElemTy); + Addr = CGF.Builder.CreateAddrSpaceCast(Addr, + CGF.ConvertType(E->getType())); return Addr; } break; @@ -1365,9 +1364,10 @@ static Address EmitPointerWithAlignment(const Expr *E, LValueBaseInfo *BaseInfo, // TODO: conditional operators, comma. // Otherwise, use the alignment of the type. - return CGF.makeNaturalAddressForPointer( - CGF.EmitScalarExpr(E), E->getType()->getPointeeType(), CharUnits(), - /*ForPointeeType=*/true, BaseInfo, TBAAInfo, IsKnownNonNull); + CharUnits Align = + CGF.CGM.getNaturalPointeeTypeAlignment(E->getType(), BaseInfo, TBAAInfo); + llvm::Type *ElemTy = CGF.ConvertTypeForMem(E->getType()->getPointeeType()); + return Address(CGF.EmitScalarExpr(E), ElemTy, Align, IsKnownNonNull); } /// EmitPointerWithAlignment - Given an expression of pointer type, try to @@ -1468,7 +1468,8 @@ LValue CodeGenFunction::EmitCheckedLValue(const Expr *E, TypeCheckKind TCK) { if (IsBaseCXXThis || isa(ME->getBase())) SkippedChecks.set(SanitizerKind::Null, true); } - EmitTypeCheck(TCK, E->getExprLoc(), LV, E->getType(), SkippedChecks); + EmitTypeCheck(TCK, E->getExprLoc(), LV.getPointer(*this), E->getType(), + LV.getAlignment(), SkippedChecks); } return LV; } @@ -1580,11 +1581,11 @@ LValue CodeGenFunction::EmitLValueHelper(const Expr *E, // Defend against branches out of gnu statement expressions surrounded by // cleanups. Address Addr = LV.getAddress(*this); - llvm::Value *V = Addr.getBasePointer(); + llvm::Value *V = Addr.getPointer(); Scope.ForceCleanup({&V}); - Addr.replaceBasePointer(V); - return LValue::MakeAddr(Addr, LV.getType(), getContext(), - LV.getBaseInfo(), LV.getTBAAInfo()); + return LValue::MakeAddr(Addr.withPointer(V, Addr.isKnownNonNull()), + LV.getType(), getContext(), LV.getBaseInfo(), + LV.getTBAAInfo()); } // FIXME: Is it possible to create an ExprWithCleanups that produces a // bitfield lvalue or some other non-simple lvalue? @@ -1928,7 +1929,7 @@ llvm::Value *CodeGenFunction::EmitLoadOfScalar(Address Addr, bool Volatile, LValueBaseInfo BaseInfo, TBAAAccessInfo TBAAInfo, bool isNontemporal) { - if (auto *GV = dyn_cast(Addr.getBasePointer())) + if (auto *GV = dyn_cast(Addr.getPointer())) if (GV->isThreadLocal()) Addr = Addr.withPointer(Builder.CreateThreadLocalAddress(GV), NotKnownNonNull); @@ -2038,9 +2039,8 @@ llvm::Value *CodeGenFunction::EmitFromMemory(llvm::Value *Value, QualType Ty) { // Convert the pointer of \p Addr to a pointer to a vector (the value type of // MatrixType), if it points to a array (the memory type of MatrixType). -static RawAddress MaybeConvertMatrixAddress(RawAddress Addr, - CodeGenFunction &CGF, - bool IsVector = true) { +static Address MaybeConvertMatrixAddress(Address Addr, CodeGenFunction &CGF, + bool IsVector = true) { auto *ArrayTy = dyn_cast(Addr.getElementType()); if (ArrayTy && IsVector) { auto *VectorTy = llvm::FixedVectorType::get(ArrayTy->getElementType(), @@ -2077,7 +2077,7 @@ void CodeGenFunction::EmitStoreOfScalar(llvm::Value *Value, Address Addr, LValueBaseInfo BaseInfo, TBAAAccessInfo TBAAInfo, bool isInit, bool isNontemporal) { - if (auto *GV = dyn_cast(Addr.getBasePointer())) + if (auto *GV = dyn_cast(Addr.getPointer())) if (GV->isThreadLocal()) Addr = Addr.withPointer(Builder.CreateThreadLocalAddress(GV), NotKnownNonNull); @@ -2432,12 +2432,14 @@ void CodeGenFunction::EmitStoreThroughLValue(RValue Src, LValue Dst, assert(Dst.getBaseIvarExp() && "BaseIvarExp is NULL"); llvm::Type *ResultType = IntPtrTy; Address dst = EmitPointerWithAlignment(Dst.getBaseIvarExp()); - llvm::Value *RHS = dst.emitRawPointer(*this); + llvm::Value *RHS = dst.getPointer(); RHS = Builder.CreatePtrToInt(RHS, ResultType, "sub.ptr.rhs.cast"); - llvm::Value *LHS = Builder.CreatePtrToInt(LvalueDst.emitRawPointer(*this), - ResultType, "sub.ptr.lhs.cast"); + llvm::Value *LHS = + Builder.CreatePtrToInt(LvalueDst.getPointer(), ResultType, + "sub.ptr.lhs.cast"); llvm::Value *BytesBetween = Builder.CreateSub(LHS, RHS, "ivar.offset"); - CGM.getObjCRuntime().EmitObjCIvarAssign(*this, src, dst, BytesBetween); + CGM.getObjCRuntime().EmitObjCIvarAssign(*this, src, dst, + BytesBetween); } else if (Dst.isGlobalObjCRef()) { CGM.getObjCRuntime().EmitObjCGlobalAssign(*this, src, LvalueDst, Dst.isThreadLocalRef()); @@ -2768,9 +2770,12 @@ CodeGenFunction::EmitLoadOfReference(LValue RefLVal, llvm::LoadInst *Load = Builder.CreateLoad(RefLVal.getAddress(*this), RefLVal.isVolatile()); CGM.DecorateInstructionWithTBAA(Load, RefLVal.getTBAAInfo()); - return makeNaturalAddressForPointer(Load, RefLVal.getType()->getPointeeType(), - CharUnits(), /*ForPointeeType=*/true, - PointeeBaseInfo, PointeeTBAAInfo); + + QualType PointeeType = RefLVal.getType()->getPointeeType(); + CharUnits Align = CGM.getNaturalTypeAlignment( + PointeeType, PointeeBaseInfo, PointeeTBAAInfo, + /* forPointeeType= */ true); + return Address(Load, ConvertTypeForMem(PointeeType), Align); } LValue CodeGenFunction::EmitLoadOfReferenceLValue(LValue RefLVal) { @@ -2787,9 +2792,10 @@ Address CodeGenFunction::EmitLoadOfPointer(Address Ptr, LValueBaseInfo *BaseInfo, TBAAAccessInfo *TBAAInfo) { llvm::Value *Addr = Builder.CreateLoad(Ptr); - return makeNaturalAddressForPointer(Addr, PtrTy->getPointeeType(), - CharUnits(), /*ForPointeeType=*/true, - BaseInfo, TBAAInfo); + return Address(Addr, ConvertTypeForMem(PtrTy->getPointeeType()), + CGM.getNaturalTypeAlignment(PtrTy->getPointeeType(), BaseInfo, + TBAAInfo, + /*forPointeeType=*/true)); } LValue CodeGenFunction::EmitLoadOfPointerLValue(Address PtrAddr, @@ -2985,7 +2991,7 @@ LValue CodeGenFunction::EmitDeclRefLValue(const DeclRefExpr *E) { /* BaseInfo= */ nullptr, /* TBAAInfo= */ nullptr, /* forPointeeType= */ true); - Addr = makeNaturalAddressForPointer(Val, T, Alignment); + Addr = Address(Val, ConvertTypeForMem(E->getType()), Alignment); } return MakeAddrLValue(Addr, T, AlignmentSource::Decl); } @@ -3017,12 +3023,11 @@ LValue CodeGenFunction::EmitDeclRefLValue(const DeclRefExpr *E) { EmitCapturedFieldLValue(*this, CapturedStmtInfo->lookup(VD), CapturedStmtInfo->getContextValue()); Address LValueAddress = CapLVal.getAddress(*this); - CapLVal = MakeAddrLValue(Address(LValueAddress.emitRawPointer(*this), - LValueAddress.getElementType(), - getContext().getDeclAlign(VD)), - CapLVal.getType(), - LValueBaseInfo(AlignmentSource::Decl), - CapLVal.getTBAAInfo()); + CapLVal = MakeAddrLValue( + Address(LValueAddress.getPointer(), LValueAddress.getElementType(), + getContext().getDeclAlign(VD)), + CapLVal.getType(), LValueBaseInfo(AlignmentSource::Decl), + CapLVal.getTBAAInfo()); // Mark lvalue as nontemporal if the variable is marked as nontemporal // in simd context. if (getLangOpts().OpenMP && @@ -3078,8 +3083,7 @@ LValue CodeGenFunction::EmitDeclRefLValue(const DeclRefExpr *E) { // Handle threadlocal function locals. if (VD->getTLSKind() != VarDecl::TLS_None) addr = addr.withPointer( - Builder.CreateThreadLocalAddress(addr.getBasePointer()), - NotKnownNonNull); + Builder.CreateThreadLocalAddress(addr.getPointer()), NotKnownNonNull); // Check for OpenMP threadprivate variables. if (getLangOpts().OpenMP && !getLangOpts().OpenMPSimd && @@ -3347,7 +3351,7 @@ llvm::Value *CodeGenFunction::EmitCheckValue(llvm::Value *V) { // Pointers are passed directly, everything else is passed by address. if (!V->getType()->isPointerTy()) { - RawAddress Ptr = CreateDefaultAlignTempAlloca(V->getType()); + Address Ptr = CreateDefaultAlignTempAlloca(V->getType()); Builder.CreateStore(V, Ptr); V = Ptr.getPointer(); } @@ -3920,21 +3924,6 @@ static llvm::Value *emitArraySubscriptGEP(CodeGenFunction &CGF, } } -static Address emitArraySubscriptGEP(CodeGenFunction &CGF, Address addr, - ArrayRef indices, - llvm::Type *elementType, bool inbounds, - bool signedIndices, SourceLocation loc, - CharUnits align, - const llvm::Twine &name = "arrayidx") { - if (inbounds) { - return CGF.EmitCheckedInBoundsGEP(addr, indices, elementType, signedIndices, - CodeGenFunction::NotSubtraction, loc, - align, name); - } else { - return CGF.Builder.CreateGEP(addr, indices, elementType, align, name); - } -} - static CharUnits getArrayElementAlign(CharUnits arrayAlign, llvm::Value *idx, CharUnits eltSize) { @@ -3982,7 +3971,7 @@ static Address wrapWithBPFPreserveStaticOffset(CodeGenFunction &CGF, llvm::Function *Fn = CGF.CGM.getIntrinsic(llvm::Intrinsic::preserve_static_offset); - llvm::CallInst *Call = CGF.Builder.CreateCall(Fn, {Addr.emitRawPointer(CGF)}); + llvm::CallInst *Call = CGF.Builder.CreateCall(Fn, {Addr.getPointer()}); return Address(Call, Addr.getElementType(), Addr.getAlignment()); } @@ -4045,7 +4034,7 @@ static Address emitArraySubscriptGEP(CodeGenFunction &CGF, Address addr, // We can use that to compute the best alignment of the element. CharUnits eltSize = CGF.getContext().getTypeSizeInChars(eltType); CharUnits eltAlign = - getArrayElementAlign(addr.getAlignment(), indices.back(), eltSize); + getArrayElementAlign(addr.getAlignment(), indices.back(), eltSize); if (hasBPFPreserveStaticOffset(Base)) addr = wrapWithBPFPreserveStaticOffset(CGF, addr); @@ -4054,19 +4043,19 @@ static Address emitArraySubscriptGEP(CodeGenFunction &CGF, Address addr, auto LastIndex = dyn_cast(indices.back()); if (!LastIndex || (!CGF.IsInPreservedAIRegion && !IsPreserveAIArrayBase(CGF, Base))) { - addr = emitArraySubscriptGEP(CGF, addr, indices, - CGF.ConvertTypeForMem(eltType), inbounds, - signedIndices, loc, eltAlign, name); - return addr; + eltPtr = emitArraySubscriptGEP( + CGF, addr.getElementType(), addr.getPointer(), indices, inbounds, + signedIndices, loc, name); } else { // Remember the original array subscript for bpf target unsigned idx = LastIndex->getZExtValue(); llvm::DIType *DbgInfo = nullptr; if (arrayType) DbgInfo = CGF.getDebugInfo()->getOrCreateStandaloneType(*arrayType, loc); - eltPtr = CGF.Builder.CreatePreserveArrayAccessIndex( - addr.getElementType(), addr.emitRawPointer(CGF), indices.size() - 1, - idx, DbgInfo); + eltPtr = CGF.Builder.CreatePreserveArrayAccessIndex(addr.getElementType(), + addr.getPointer(), + indices.size() - 1, + idx, DbgInfo); } return Address(eltPtr, CGF.ConvertTypeForMem(eltType), eltAlign); @@ -4235,8 +4224,8 @@ LValue CodeGenFunction::EmitArraySubscriptExpr(const ArraySubscriptExpr *E, CharUnits EltAlign = getArrayElementAlign(Addr.getAlignment(), Idx, InterfaceSize); llvm::Value *EltPtr = - emitArraySubscriptGEP(*this, Int8Ty, Addr.emitRawPointer(*this), - ScaledIdx, false, SignedIndices, E->getExprLoc()); + emitArraySubscriptGEP(*this, Int8Ty, Addr.getPointer(), ScaledIdx, + false, SignedIndices, E->getExprLoc()); Addr = Address(EltPtr, OrigBaseElemTy, EltAlign); } else if (const Expr *Array = isSimpleArrayDecayOperand(E->getBase())) { // If this is A[i] where A is an array, the frontend will have decayed the @@ -4282,7 +4271,7 @@ LValue CodeGenFunction::EmitArraySubscriptExpr(const ArraySubscriptExpr *E, llvm::Type *CountTy = ConvertType(CountFD->getType()); llvm::Value *Res = Builder.CreateInBoundsGEP( - Int8Ty, Addr.emitRawPointer(*this), + Int8Ty, Addr.getPointer(), Builder.getInt32(OffsetDiff.getQuantity()), ".counted_by.gep"); Res = Builder.CreateAlignedLoad(CountTy, Res, getIntAlign(), ".counted_by.load"); @@ -4528,9 +4517,9 @@ LValue CodeGenFunction::EmitOMPArraySectionExpr(const OMPArraySectionExpr *E, BaseInfo = ArrayLV.getBaseInfo(); TBAAInfo = CGM.getTBAAInfoForSubobject(ArrayLV, ResultExprTy); } else { - Address Base = - emitOMPArraySectionBase(*this, E->getBase(), BaseInfo, TBAAInfo, BaseTy, - ResultExprTy, IsLowerBound); + Address Base = emitOMPArraySectionBase(*this, E->getBase(), BaseInfo, + TBAAInfo, BaseTy, ResultExprTy, + IsLowerBound); EltPtr = emitArraySubscriptGEP(*this, Base, Idx, ResultExprTy, !getLangOpts().isSignedOverflowDefined(), /*signedIndices=*/false, E->getExprLoc()); @@ -4617,7 +4606,7 @@ LValue CodeGenFunction::EmitMemberExpr(const MemberExpr *E) { SkippedChecks.set(SanitizerKind::Alignment, true); if (IsBaseCXXThis || isa(BaseExpr)) SkippedChecks.set(SanitizerKind::Null, true); - EmitTypeCheck(TCK_MemberAccess, E->getExprLoc(), Addr, PtrTy, + EmitTypeCheck(TCK_MemberAccess, E->getExprLoc(), Addr.getPointer(), PtrTy, /*Alignment=*/CharUnits::Zero(), SkippedChecks); BaseLV = MakeAddrLValue(Addr, PtrTy, BaseInfo, TBAAInfo); } else @@ -4666,8 +4655,8 @@ LValue CodeGenFunction::EmitLValueForLambdaField(const FieldDecl *Field, LambdaLV = EmitLoadOfReferenceLValue(AddrOfExplicitObject, D->getType(), AlignmentSource::Decl); else - LambdaLV = MakeAddrLValue(AddrOfExplicitObject, - D->getType().getNonReferenceType()); + LambdaLV = MakeNaturalAlignAddrLValue(AddrOfExplicitObject.getPointer(), + D->getType().getNonReferenceType()); } else { QualType LambdaTagType = getContext().getTagDeclType(Field->getParent()); LambdaLV = MakeNaturalAlignAddrLValue(ThisValue, LambdaTagType); @@ -4857,8 +4846,7 @@ LValue CodeGenFunction::EmitLValueForField(LValue base, // information provided by invariant.group. This is because accessing // fields may leak the real address of dynamic object, which could result // in miscompilation when leaked pointer would be compared. - auto *stripped = - Builder.CreateStripInvariantGroup(addr.emitRawPointer(*this)); + auto *stripped = Builder.CreateStripInvariantGroup(addr.getPointer()); addr = Address(stripped, addr.getElementType(), addr.getAlignment()); } } @@ -4877,11 +4865,10 @@ LValue CodeGenFunction::EmitLValueForField(LValue base, // Remember the original union field index llvm::DIType *DbgInfo = getDebugInfo()->getOrCreateStandaloneType(base.getType(), rec->getLocation()); - addr = - Address(Builder.CreatePreserveUnionAccessIndex( - addr.emitRawPointer(*this), - getDebugInfoFIndex(rec, field->getFieldIndex()), DbgInfo), - addr.getElementType(), addr.getAlignment()); + addr = Address( + Builder.CreatePreserveUnionAccessIndex( + addr.getPointer(), getDebugInfoFIndex(rec, field->getFieldIndex()), DbgInfo), + addr.getElementType(), addr.getAlignment()); } if (FieldType->isReferenceType()) @@ -5118,9 +5105,11 @@ LValue CodeGenFunction::EmitConditionalOperatorLValue( if (Info.LHS && Info.RHS) { Address lhsAddr = Info.LHS->getAddress(*this); Address rhsAddr = Info.RHS->getAddress(*this); - Address result = mergeAddressesInConditionalExpr( - lhsAddr, rhsAddr, Info.lhsBlock, Info.rhsBlock, - Builder.GetInsertBlock(), expr->getType()); + llvm::PHINode *phi = Builder.CreatePHI(lhsAddr.getType(), 2, "cond-lvalue"); + phi->addIncoming(lhsAddr.getPointer(), Info.lhsBlock); + phi->addIncoming(rhsAddr.getPointer(), Info.rhsBlock); + Address result(phi, lhsAddr.getElementType(), + std::min(lhsAddr.getAlignment(), rhsAddr.getAlignment())); AlignmentSource alignSource = std::max(Info.LHS->getBaseInfo().getAlignmentSource(), Info.RHS->getBaseInfo().getAlignmentSource()); @@ -5207,7 +5196,7 @@ LValue CodeGenFunction::EmitCastLValue(const CastExpr *E) { LValue LV = EmitLValue(E->getSubExpr()); Address V = LV.getAddress(*this); const auto *DCE = cast(E); - return MakeNaturalAlignRawAddrLValue(EmitDynamicCast(V, DCE), E->getType()); + return MakeNaturalAlignAddrLValue(EmitDynamicCast(V, DCE), E->getType()); } case CK_ConstructorConversion: @@ -5272,8 +5261,8 @@ LValue CodeGenFunction::EmitCastLValue(const CastExpr *E) { // C++11 [expr.static.cast]p2: Behavior is undefined if a downcast is // performed and the object is not of the derived type. if (sanitizePerformTypeCheck()) - EmitTypeCheck(TCK_DowncastReference, E->getExprLoc(), Derived, - E->getType()); + EmitTypeCheck(TCK_DowncastReference, E->getExprLoc(), + Derived.getPointer(), E->getType()); if (SanOpts.has(SanitizerKind::CFIDerivedCast)) EmitVTablePtrCheckForCast(E->getType(), Derived, @@ -5629,7 +5618,7 @@ LValue CodeGenFunction::EmitCXXConstructLValue(const CXXConstructExpr *E) { LValue CodeGenFunction::EmitCXXTypeidLValue(const CXXTypeidExpr *E) { - return MakeNaturalAlignRawAddrLValue(EmitCXXTypeidExpr(E), E->getType()); + return MakeNaturalAlignAddrLValue(EmitCXXTypeidExpr(E), E->getType()); } Address CodeGenFunction::EmitCXXUuidofExpr(const CXXUuidofExpr *E) { diff --git a/clang/lib/CodeGen/CGExprAgg.cpp b/clang/lib/CodeGen/CGExprAgg.cpp index 143855aa84ca..5190b22bcc16 100644 --- a/clang/lib/CodeGen/CGExprAgg.cpp +++ b/clang/lib/CodeGen/CGExprAgg.cpp @@ -294,10 +294,10 @@ void AggExprEmitter::withReturnValueSlot( // Otherwise, EmitCall will emit its own, notice that it's "unused", and end // its lifetime before we have the chance to emit a proper destructor call. bool UseTemp = Dest.isPotentiallyAliased() || Dest.requiresGCollection() || - (RequiresDestruction && Dest.isIgnored()); + (RequiresDestruction && !Dest.getAddress().isValid()); Address RetAddr = Address::invalid(); - RawAddress RetAllocaAddr = RawAddress::invalid(); + Address RetAllocaAddr = Address::invalid(); EHScopeStack::stable_iterator LifetimeEndBlock; llvm::Value *LifetimeSizePtr = nullptr; @@ -329,8 +329,7 @@ void AggExprEmitter::withReturnValueSlot( if (!UseTemp) return; - assert(Dest.isIgnored() || Dest.emitRawPointer(CGF) != - Src.getAggregatePointer(E->getType(), CGF)); + assert(Dest.isIgnored() || Dest.getPointer() != Src.getAggregatePointer()); EmitFinalDestCopy(E->getType(), Src); if (!RequiresDestruction && LifetimeStartInst) { @@ -449,8 +448,7 @@ AggExprEmitter::VisitCXXStdInitializerListExpr(CXXStdInitializerListExpr *E) { llvm::Value *Zero = llvm::ConstantInt::get(CGF.PtrDiffTy, 0); llvm::Value *IdxStart[] = { Zero, Zero }; llvm::Value *ArrayStart = Builder.CreateInBoundsGEP( - ArrayPtr.getElementType(), ArrayPtr.emitRawPointer(CGF), IdxStart, - "arraystart"); + ArrayPtr.getElementType(), ArrayPtr.getPointer(), IdxStart, "arraystart"); CGF.EmitStoreThroughLValue(RValue::get(ArrayStart), Start); ++Field; @@ -467,8 +465,7 @@ AggExprEmitter::VisitCXXStdInitializerListExpr(CXXStdInitializerListExpr *E) { // End pointer. llvm::Value *IdxEnd[] = { Zero, Size }; llvm::Value *ArrayEnd = Builder.CreateInBoundsGEP( - ArrayPtr.getElementType(), ArrayPtr.emitRawPointer(CGF), IdxEnd, - "arrayend"); + ArrayPtr.getElementType(), ArrayPtr.getPointer(), IdxEnd, "arrayend"); CGF.EmitStoreThroughLValue(RValue::get(ArrayEnd), EndOrLength); } else if (Ctx.hasSameType(Field->getType(), Ctx.getSizeType())) { // Length. @@ -519,9 +516,9 @@ void AggExprEmitter::EmitArrayInit(Address DestPtr, llvm::ArrayType *AType, // down a level. llvm::Value *zero = llvm::ConstantInt::get(CGF.SizeTy, 0); llvm::Value *indices[] = { zero, zero }; - llvm::Value *begin = Builder.CreateInBoundsGEP(DestPtr.getElementType(), - DestPtr.emitRawPointer(CGF), - indices, "arrayinit.begin"); + llvm::Value *begin = Builder.CreateInBoundsGEP( + DestPtr.getElementType(), DestPtr.getPointer(), indices, + "arrayinit.begin"); CharUnits elementSize = CGF.getContext().getTypeSizeInChars(elementType); CharUnits elementAlign = @@ -1062,7 +1059,7 @@ void AggExprEmitter::VisitBinCmp(const BinaryOperator *E) { if (RV.isScalar()) return {RV.getScalarVal(), nullptr}; if (RV.isAggregate()) - return {RV.getAggregatePointer(E->getType(), CGF), nullptr}; + return {RV.getAggregatePointer(), nullptr}; assert(RV.isComplex()); return RV.getComplexVal(); }; @@ -1821,7 +1818,7 @@ void AggExprEmitter::VisitCXXParenListOrInitListExpr( // else, clean it up for -O0 builds and general tidiness. if (!pushedCleanup && LV.isSimple()) if (llvm::GetElementPtrInst *GEP = - dyn_cast(LV.emitRawPointer(CGF))) + dyn_cast(LV.getPointer(CGF))) if (GEP->use_empty()) GEP->eraseFromParent(); } @@ -1852,9 +1849,9 @@ void AggExprEmitter::VisitArrayInitLoopExpr(const ArrayInitLoopExpr *E, // destPtr is an array*. Construct an elementType* by drilling down a level. llvm::Value *zero = llvm::ConstantInt::get(CGF.SizeTy, 0); llvm::Value *indices[] = {zero, zero}; - llvm::Value *begin = Builder.CreateInBoundsGEP(destPtr.getElementType(), - destPtr.emitRawPointer(CGF), - indices, "arrayinit.begin"); + llvm::Value *begin = Builder.CreateInBoundsGEP( + destPtr.getElementType(), destPtr.getPointer(), indices, + "arrayinit.begin"); // Prepare to special-case multidimensional array initialization: we avoid // emitting multiple destructor loops in that case. diff --git a/clang/lib/CodeGen/CGExprCXX.cpp b/clang/lib/CodeGen/CGExprCXX.cpp index 5c16a48d3ee6..35da0f1a89bc 100644 --- a/clang/lib/CodeGen/CGExprCXX.cpp +++ b/clang/lib/CodeGen/CGExprCXX.cpp @@ -280,8 +280,7 @@ RValue CodeGenFunction::EmitCXXMemberOrOperatorMemberCallExpr( LValueBaseInfo BaseInfo; TBAAAccessInfo TBAAInfo; Address ThisValue = EmitPointerWithAlignment(Base, &BaseInfo, &TBAAInfo); - This = MakeAddrLValue(ThisValue, Base->getType()->getPointeeType(), - BaseInfo, TBAAInfo); + This = MakeAddrLValue(ThisValue, Base->getType(), BaseInfo, TBAAInfo); } else { This = EmitLValue(Base); } @@ -354,8 +353,10 @@ RValue CodeGenFunction::EmitCXXMemberOrOperatorMemberCallExpr( if (IsImplicitObjectCXXThis || isa(IOA)) SkippedChecks.set(SanitizerKind::Null, true); } - EmitTypeCheck(CodeGenFunction::TCK_MemberCall, CallLoc, This, - C.getRecordType(CalleeDecl->getParent()), SkippedChecks); + EmitTypeCheck(CodeGenFunction::TCK_MemberCall, CallLoc, + This.getPointer(*this), + C.getRecordType(CalleeDecl->getParent()), + /*Alignment=*/CharUnits::Zero(), SkippedChecks); // C++ [class.virtual]p12: // Explicit qualification with the scope operator (5.1) suppresses the @@ -454,7 +455,7 @@ CodeGenFunction::EmitCXXMemberPointerCallExpr(const CXXMemberCallExpr *E, else This = EmitLValue(BaseExpr, KnownNonNull).getAddress(*this); - EmitTypeCheck(TCK_MemberCall, E->getExprLoc(), This.emitRawPointer(*this), + EmitTypeCheck(TCK_MemberCall, E->getExprLoc(), This.getPointer(), QualType(MPT->getClass(), 0)); // Get the member function pointer. @@ -1108,10 +1109,9 @@ void CodeGenFunction::EmitNewArrayInitializer( // alloca. EndOfInit = CreateTempAlloca(BeginPtr.getType(), getPointerAlign(), "array.init.end"); - CleanupDominator = - Builder.CreateStore(BeginPtr.emitRawPointer(*this), EndOfInit); - pushIrregularPartialArrayCleanup(BeginPtr.emitRawPointer(*this), - EndOfInit, ElementType, ElementAlign, + CleanupDominator = Builder.CreateStore(BeginPtr.getPointer(), EndOfInit); + pushIrregularPartialArrayCleanup(BeginPtr.getPointer(), EndOfInit, + ElementType, ElementAlign, getDestroyer(DtorKind)); Cleanup = EHStack.stable_begin(); } @@ -1123,17 +1123,16 @@ void CodeGenFunction::EmitNewArrayInitializer( // element. TODO: some of these stores can be trivially // observed to be unnecessary. if (EndOfInit.isValid()) { - Builder.CreateStore(CurPtr.emitRawPointer(*this), EndOfInit); + Builder.CreateStore(CurPtr.getPointer(), EndOfInit); } // FIXME: If the last initializer is an incomplete initializer list for // an array, and we have an array filler, we can fold together the two // initialization loops. StoreAnyExprIntoOneUnit(*this, IE, IE->getType(), CurPtr, AggValueSlot::DoesNotOverlap); - CurPtr = Address(Builder.CreateInBoundsGEP(CurPtr.getElementType(), - CurPtr.emitRawPointer(*this), - Builder.getSize(1), - "array.exp.next"), + CurPtr = Address(Builder.CreateInBoundsGEP( + CurPtr.getElementType(), CurPtr.getPointer(), + Builder.getSize(1), "array.exp.next"), CurPtr.getElementType(), StartAlign.alignmentAtOffset((++i) * ElementSize)); } @@ -1187,7 +1186,7 @@ void CodeGenFunction::EmitNewArrayInitializer( // FIXME: Share this cleanup with the constructor call emission rather than // having it create a cleanup of its own. if (EndOfInit.isValid()) - Builder.CreateStore(CurPtr.emitRawPointer(*this), EndOfInit); + Builder.CreateStore(CurPtr.getPointer(), EndOfInit); // Emit a constructor call loop to initialize the remaining elements. if (InitListElements) @@ -1250,15 +1249,15 @@ void CodeGenFunction::EmitNewArrayInitializer( llvm::BasicBlock *ContBB = createBasicBlock("new.loop.end"); // Find the end of the array, hoisted out of the loop. - llvm::Value *EndPtr = Builder.CreateInBoundsGEP( - BeginPtr.getElementType(), BeginPtr.emitRawPointer(*this), NumElements, - "array.end"); + llvm::Value *EndPtr = + Builder.CreateInBoundsGEP(BeginPtr.getElementType(), BeginPtr.getPointer(), + NumElements, "array.end"); // If the number of elements isn't constant, we have to now check if there is // anything left to initialize. if (!ConstNum) { - llvm::Value *IsEmpty = Builder.CreateICmpEQ(CurPtr.emitRawPointer(*this), - EndPtr, "array.isempty"); + llvm::Value *IsEmpty = + Builder.CreateICmpEQ(CurPtr.getPointer(), EndPtr, "array.isempty"); Builder.CreateCondBr(IsEmpty, ContBB, LoopBB); } @@ -1268,20 +1267,19 @@ void CodeGenFunction::EmitNewArrayInitializer( // Set up the current-element phi. llvm::PHINode *CurPtrPhi = Builder.CreatePHI(CurPtr.getType(), 2, "array.cur"); - CurPtrPhi->addIncoming(CurPtr.emitRawPointer(*this), EntryBB); + CurPtrPhi->addIncoming(CurPtr.getPointer(), EntryBB); CurPtr = Address(CurPtrPhi, CurPtr.getElementType(), ElementAlign); // Store the new Cleanup position for irregular Cleanups. if (EndOfInit.isValid()) - Builder.CreateStore(CurPtr.emitRawPointer(*this), EndOfInit); + Builder.CreateStore(CurPtr.getPointer(), EndOfInit); // Enter a partial-destruction Cleanup if necessary. if (!CleanupDominator && needsEHCleanup(DtorKind)) { - llvm::Value *BeginPtrRaw = BeginPtr.emitRawPointer(*this); - llvm::Value *CurPtrRaw = CurPtr.emitRawPointer(*this); - pushRegularPartialArrayCleanup(BeginPtrRaw, CurPtrRaw, ElementType, - ElementAlign, getDestroyer(DtorKind)); + pushRegularPartialArrayCleanup(BeginPtr.getPointer(), CurPtr.getPointer(), + ElementType, ElementAlign, + getDestroyer(DtorKind)); Cleanup = EHStack.stable_begin(); CleanupDominator = Builder.CreateUnreachable(); } @@ -1297,8 +1295,9 @@ void CodeGenFunction::EmitNewArrayInitializer( } // Advance to the next element by adjusting the pointer type as necessary. - llvm::Value *NextPtr = Builder.CreateConstInBoundsGEP1_32( - ElementTy, CurPtr.emitRawPointer(*this), 1, "array.next"); + llvm::Value *NextPtr = + Builder.CreateConstInBoundsGEP1_32(ElementTy, CurPtr.getPointer(), 1, + "array.next"); // Check whether we've gotten to the end of the array and, if so, // exit the loop. @@ -1524,9 +1523,14 @@ static void EnterNewDeleteCleanup(CodeGenFunction &CGF, typedef CallDeleteDuringNew DirectCleanup; - DirectCleanup *Cleanup = CGF.EHStack.pushCleanupWithExtra( - EHCleanup, E->getNumPlacementArgs(), E->getOperatorDelete(), - NewPtr.emitRawPointer(CGF), AllocSize, E->passAlignment(), AllocAlign); + DirectCleanup *Cleanup = CGF.EHStack + .pushCleanupWithExtra(EHCleanup, + E->getNumPlacementArgs(), + E->getOperatorDelete(), + NewPtr.getPointer(), + AllocSize, + E->passAlignment(), + AllocAlign); for (unsigned I = 0, N = E->getNumPlacementArgs(); I != N; ++I) { auto &Arg = NewArgs[I + NumNonPlacementArgs]; Cleanup->setPlacementArg(I, Arg.getRValue(CGF), Arg.Ty); @@ -1537,7 +1541,7 @@ static void EnterNewDeleteCleanup(CodeGenFunction &CGF, // Otherwise, we need to save all this stuff. DominatingValue::saved_type SavedNewPtr = - DominatingValue::save(CGF, RValue::get(NewPtr, CGF)); + DominatingValue::save(CGF, RValue::get(NewPtr.getPointer())); DominatingValue::saved_type SavedAllocSize = DominatingValue::save(CGF, RValue::get(AllocSize)); @@ -1614,14 +1618,14 @@ llvm::Value *CodeGenFunction::EmitCXXNewExpr(const CXXNewExpr *E) { // In these cases, discard the computed alignment and use the // formal alignment of the allocated type. if (BaseInfo.getAlignmentSource() != AlignmentSource::Decl) - allocation.setAlignment(allocAlign); + allocation = allocation.withAlignment(allocAlign); // Set up allocatorArgs for the call to operator delete if it's not // the reserved global operator. if (E->getOperatorDelete() && !E->getOperatorDelete()->isReservedGlobalPlacementOperator()) { allocatorArgs.add(RValue::get(allocSize), getContext().getSizeType()); - allocatorArgs.add(RValue::get(allocation, *this), arg->getType()); + allocatorArgs.add(RValue::get(allocation.getPointer()), arg->getType()); } } else { @@ -1709,7 +1713,8 @@ llvm::Value *CodeGenFunction::EmitCXXNewExpr(const CXXNewExpr *E) { llvm::BasicBlock *notNullBB = createBasicBlock("new.notnull"); contBB = createBasicBlock("new.cont"); - llvm::Value *isNull = Builder.CreateIsNull(allocation, "new.isnull"); + llvm::Value *isNull = + Builder.CreateIsNull(allocation.getPointer(), "new.isnull"); Builder.CreateCondBr(isNull, contBB, notNullBB); EmitBlock(notNullBB); } @@ -1755,12 +1760,12 @@ llvm::Value *CodeGenFunction::EmitCXXNewExpr(const CXXNewExpr *E) { SkippedChecks.set(SanitizerKind::Null, nullCheck); EmitTypeCheck(CodeGenFunction::TCK_ConstructorCall, E->getAllocatedTypeSourceInfo()->getTypeLoc().getBeginLoc(), - result, allocType, result.getAlignment(), SkippedChecks, - numElements); + result.getPointer(), allocType, result.getAlignment(), + SkippedChecks, numElements); EmitNewInitializer(*this, E, allocType, elementTy, result, numElements, allocSizeWithoutCookie); - llvm::Value *resultPtr = result.emitRawPointer(*this); + llvm::Value *resultPtr = result.getPointer(); if (E->isArray()) { // NewPtr is a pointer to the base element type. If we're // allocating an array of arrays, we'll need to cast back to the @@ -1904,8 +1909,7 @@ static void EmitDestroyingObjectDelete(CodeGenFunction &CGF, CGF.CGM.getCXXABI().emitVirtualObjectDelete(CGF, DE, Ptr, ElementType, Dtor); else - CGF.EmitDeleteCall(DE->getOperatorDelete(), Ptr.emitRawPointer(CGF), - ElementType); + CGF.EmitDeleteCall(DE->getOperatorDelete(), Ptr.getPointer(), ElementType); } /// Emit the code for deleting a single object. @@ -1921,7 +1925,8 @@ static bool EmitObjectDelete(CodeGenFunction &CGF, // dynamic type, the static type shall be a base class of the dynamic type // of the object to be deleted and the static type shall have a virtual // destructor or the behavior is undefined. - CGF.EmitTypeCheck(CodeGenFunction::TCK_MemberCall, DE->getExprLoc(), Ptr, + CGF.EmitTypeCheck(CodeGenFunction::TCK_MemberCall, + DE->getExprLoc(), Ptr.getPointer(), ElementType); const FunctionDecl *OperatorDelete = DE->getOperatorDelete(); @@ -1970,8 +1975,9 @@ static bool EmitObjectDelete(CodeGenFunction &CGF, // Make sure that we call delete even if the dtor throws. // This doesn't have to a conditional cleanup because we're going // to pop it off in a second. - CGF.EHStack.pushCleanup( - NormalAndEHCleanup, Ptr.emitRawPointer(CGF), OperatorDelete, ElementType); + CGF.EHStack.pushCleanup(NormalAndEHCleanup, + Ptr.getPointer(), + OperatorDelete, ElementType); if (Dtor) CGF.EmitCXXDestructorCall(Dtor, Dtor_Complete, @@ -2058,7 +2064,7 @@ static void EmitArrayDelete(CodeGenFunction &CGF, CharUnits elementAlign = deletedPtr.getAlignment().alignmentOfArrayElement(elementSize); - llvm::Value *arrayBegin = deletedPtr.emitRawPointer(CGF); + llvm::Value *arrayBegin = deletedPtr.getPointer(); llvm::Value *arrayEnd = CGF.Builder.CreateInBoundsGEP( deletedPtr.getElementType(), arrayBegin, numElements, "delete.end"); @@ -2089,7 +2095,7 @@ void CodeGenFunction::EmitCXXDeleteExpr(const CXXDeleteExpr *E) { llvm::BasicBlock *DeleteNotNull = createBasicBlock("delete.notnull"); llvm::BasicBlock *DeleteEnd = createBasicBlock("delete.end"); - llvm::Value *IsNull = Builder.CreateIsNull(Ptr, "isnull"); + llvm::Value *IsNull = Builder.CreateIsNull(Ptr.getPointer(), "isnull"); Builder.CreateCondBr(IsNull, DeleteEnd, DeleteNotNull); EmitBlock(DeleteNotNull); @@ -2124,8 +2130,10 @@ void CodeGenFunction::EmitCXXDeleteExpr(const CXXDeleteExpr *E) { GEP.push_back(Zero); } - Ptr = Builder.CreateInBoundsGEP(Ptr, GEP, ConvertTypeForMem(DeleteTy), - Ptr.getAlignment(), "del.first"); + Ptr = Address(Builder.CreateInBoundsGEP(Ptr.getElementType(), + Ptr.getPointer(), GEP, "del.first"), + ConvertTypeForMem(DeleteTy), Ptr.getAlignment(), + Ptr.isKnownNonNull()); } assert(ConvertTypeForMem(DeleteTy) == Ptr.getElementType()); @@ -2183,7 +2191,7 @@ static llvm::Value *EmitTypeidFromVTable(CodeGenFunction &CGF, const Expr *E, // destruction and the static type of the operand is neither the constructor // or destructor’s class nor one of its bases, the behavior is undefined. CGF.EmitTypeCheck(CodeGenFunction::TCK_DynamicOperation, E->getExprLoc(), - ThisPtr, SrcRecordTy); + ThisPtr.getPointer(), SrcRecordTy); // C++ [expr.typeid]p2: // If the glvalue expression is obtained by applying the unary * operator to @@ -2199,7 +2207,7 @@ static llvm::Value *EmitTypeidFromVTable(CodeGenFunction &CGF, const Expr *E, CGF.createBasicBlock("typeid.bad_typeid"); llvm::BasicBlock *EndBlock = CGF.createBasicBlock("typeid.end"); - llvm::Value *IsNull = CGF.Builder.CreateIsNull(ThisPtr); + llvm::Value *IsNull = CGF.Builder.CreateIsNull(ThisPtr.getPointer()); CGF.Builder.CreateCondBr(IsNull, BadTypeidBlock, EndBlock); CGF.EmitBlock(BadTypeidBlock); @@ -2285,7 +2293,8 @@ llvm::Value *CodeGenFunction::EmitDynamicCast(Address ThisAddr, // construction or destruction and the static type of the operand is not a // pointer to or object of the constructor or destructor’s own class or one // of its bases, the dynamic_cast results in undefined behavior. - EmitTypeCheck(TCK_DynamicOperation, DCE->getExprLoc(), ThisAddr, SrcRecordTy); + EmitTypeCheck(TCK_DynamicOperation, DCE->getExprLoc(), ThisAddr.getPointer(), + SrcRecordTy); if (DCE->isAlwaysNull()) { if (llvm::Value *T = EmitDynamicCastToNull(*this, DestTy)) { @@ -2320,7 +2329,7 @@ llvm::Value *CodeGenFunction::EmitDynamicCast(Address ThisAddr, CastNull = createBasicBlock("dynamic_cast.null"); CastNotNull = createBasicBlock("dynamic_cast.notnull"); - llvm::Value *IsNull = Builder.CreateIsNull(ThisAddr); + llvm::Value *IsNull = Builder.CreateIsNull(ThisAddr.getPointer()); Builder.CreateCondBr(IsNull, CastNull, CastNotNull); EmitBlock(CastNotNull); } diff --git a/clang/lib/CodeGen/CGExprConstant.cpp b/clang/lib/CodeGen/CGExprConstant.cpp index 36d7493d9a6b..67a3cdc77042 100644 --- a/clang/lib/CodeGen/CGExprConstant.cpp +++ b/clang/lib/CodeGen/CGExprConstant.cpp @@ -800,8 +800,8 @@ bool ConstStructBuilder::Build(const APValue &Val, const RecordDecl *RD, // Add a vtable pointer, if we need one and it hasn't already been added. if (Layout.hasOwnVFPtr()) { llvm::Constant *VTableAddressPoint = - CGM.getCXXABI().getVTableAddressPoint(BaseSubobject(CD, Offset), - VTableClass); + CGM.getCXXABI().getVTableAddressPointForConstExpr( + BaseSubobject(CD, Offset), VTableClass); if (!AppendBytes(Offset, VTableAddressPoint)) return false; } diff --git a/clang/lib/CodeGen/CGExprScalar.cpp b/clang/lib/CodeGen/CGExprScalar.cpp index 83247aa48f86..8536570087ad 100644 --- a/clang/lib/CodeGen/CGExprScalar.cpp +++ b/clang/lib/CodeGen/CGExprScalar.cpp @@ -2250,7 +2250,7 @@ Value *ScalarExprEmitter::VisitCastExpr(CastExpr *CE) { // performed and the object is not of the derived type. if (CGF.sanitizePerformTypeCheck()) CGF.EmitTypeCheck(CodeGenFunction::TCK_DowncastPointer, CE->getExprLoc(), - Derived, DestTy->getPointeeType()); + Derived.getPointer(), DestTy->getPointeeType()); if (CGF.SanOpts.has(SanitizerKind::CFIDerivedCast)) CGF.EmitVTablePtrCheckForCast(DestTy->getPointeeType(), Derived, @@ -2258,14 +2258,13 @@ Value *ScalarExprEmitter::VisitCastExpr(CastExpr *CE) { CodeGenFunction::CFITCK_DerivedCast, CE->getBeginLoc()); - return CGF.getAsNaturalPointerTo(Derived, CE->getType()->getPointeeType()); + return Derived.getPointer(); } case CK_UncheckedDerivedToBase: case CK_DerivedToBase: { // The EmitPointerWithAlignment path does this fine; just discard // the alignment. - return CGF.getAsNaturalPointerTo(CGF.EmitPointerWithAlignment(CE), - CE->getType()->getPointeeType()); + return CGF.EmitPointerWithAlignment(CE).getPointer(); } case CK_Dynamic: { @@ -2275,8 +2274,7 @@ Value *ScalarExprEmitter::VisitCastExpr(CastExpr *CE) { } case CK_ArrayToPointerDecay: - return CGF.getAsNaturalPointerTo(CGF.EmitArrayToPointerDecay(E), - CE->getType()->getPointeeType()); + return CGF.EmitArrayToPointerDecay(E).getPointer(); case CK_FunctionToPointerDecay: return EmitLValue(E).getPointer(CGF); @@ -5590,16 +5588,3 @@ CodeGenFunction::EmitCheckedInBoundsGEP(llvm::Type *ElemTy, Value *Ptr, return GEPVal; } - -Address CodeGenFunction::EmitCheckedInBoundsGEP( - Address Addr, ArrayRef IdxList, llvm::Type *elementType, - bool SignedIndices, bool IsSubtraction, SourceLocation Loc, CharUnits Align, - const Twine &Name) { - if (!SanOpts.has(SanitizerKind::PointerOverflow)) - return Builder.CreateInBoundsGEP(Addr, IdxList, elementType, Align, Name); - - return RawAddress( - EmitCheckedInBoundsGEP(Addr.getElementType(), Addr.emitRawPointer(*this), - IdxList, SignedIndices, IsSubtraction, Loc, Name), - elementType, Align); -} diff --git a/clang/lib/CodeGen/CGNonTrivialStruct.cpp b/clang/lib/CodeGen/CGNonTrivialStruct.cpp index 8fade0fac21e..75c1d7fbea84 100644 --- a/clang/lib/CodeGen/CGNonTrivialStruct.cpp +++ b/clang/lib/CodeGen/CGNonTrivialStruct.cpp @@ -366,7 +366,7 @@ template struct GenFuncBase { llvm::Value *SizeInBytes = CGF.Builder.CreateNUWMul(BaseEltSizeVal, NumElts); llvm::Value *DstArrayEnd = CGF.Builder.CreateInBoundsGEP( - CGF.Int8Ty, DstAddr.emitRawPointer(CGF), SizeInBytes); + CGF.Int8Ty, DstAddr.getPointer(), SizeInBytes); llvm::BasicBlock *PreheaderBB = CGF.Builder.GetInsertBlock(); // Create the header block and insert the phi instructions. @@ -376,7 +376,7 @@ template struct GenFuncBase { for (unsigned I = 0; I < N; ++I) { PHIs[I] = CGF.Builder.CreatePHI(CGF.CGM.Int8PtrPtrTy, 2, "addr.cur"); - PHIs[I]->addIncoming(StartAddrs[I].emitRawPointer(CGF), PreheaderBB); + PHIs[I]->addIncoming(StartAddrs[I].getPointer(), PreheaderBB); } // Create the exit and loop body blocks. @@ -410,7 +410,7 @@ template struct GenFuncBase { // Instrs to update the destination and source addresses. // Update phi instructions. NewAddrs[I] = getAddrWithOffset(NewAddrs[I], EltSize); - PHIs[I]->addIncoming(NewAddrs[I].emitRawPointer(CGF), LoopBB); + PHIs[I]->addIncoming(NewAddrs[I].getPointer(), LoopBB); } // Insert an unconditional branch to the header block. @@ -488,7 +488,7 @@ template struct GenFuncBase { for (unsigned I = 0; I < N; ++I) { Alignments[I] = Addrs[I].getAlignment(); - Ptrs[I] = Addrs[I].emitRawPointer(CallerCGF); + Ptrs[I] = Addrs[I].getPointer(); } if (llvm::Function *F = diff --git a/clang/lib/CodeGen/CGObjC.cpp b/clang/lib/CodeGen/CGObjC.cpp index c7f497a7c845..f3a948cf13f9 100644 --- a/clang/lib/CodeGen/CGObjC.cpp +++ b/clang/lib/CodeGen/CGObjC.cpp @@ -94,8 +94,8 @@ CodeGenFunction::EmitObjCBoxedExpr(const ObjCBoxedExpr *E) { // and cast value to correct type Address Temporary = CreateMemTemp(SubExpr->getType()); EmitAnyExprToMem(SubExpr, Temporary, Qualifiers(), /*isInit*/ true); - llvm::Value *BitCast = Builder.CreateBitCast( - Temporary.emitRawPointer(*this), ConvertType(ArgQT)); + llvm::Value *BitCast = + Builder.CreateBitCast(Temporary.getPointer(), ConvertType(ArgQT)); Args.add(RValue::get(BitCast), ArgQT); // Create char array to store type encoding @@ -204,11 +204,11 @@ llvm::Value *CodeGenFunction::EmitObjCCollectionLiteral(const Expr *E, ObjCMethodDecl::param_const_iterator PI = MethodWithObjects->param_begin(); const ParmVarDecl *argDecl = *PI++; QualType ArgQT = argDecl->getType().getUnqualifiedType(); - Args.add(RValue::get(Objects, *this), ArgQT); + Args.add(RValue::get(Objects.getPointer()), ArgQT); if (DLE) { argDecl = *PI++; ArgQT = argDecl->getType().getUnqualifiedType(); - Args.add(RValue::get(Keys, *this), ArgQT); + Args.add(RValue::get(Keys.getPointer()), ArgQT); } argDecl = *PI; ArgQT = argDecl->getType().getUnqualifiedType(); @@ -827,7 +827,7 @@ static void emitStructGetterCall(CodeGenFunction &CGF, ObjCIvarDecl *ivar, // sizeof (Type of Ivar), isAtomic, false); CallArgList args; - llvm::Value *dest = CGF.ReturnValue.emitRawPointer(CGF); + llvm::Value *dest = CGF.ReturnValue.getPointer(); args.add(RValue::get(dest), Context.VoidPtrTy); args.add(RValue::get(src), Context.VoidPtrTy); @@ -1147,8 +1147,8 @@ CodeGenFunction::generateObjCGetterBody(const ObjCImplementationDecl *classImpl, callCStructCopyConstructor(Dst, Src); } else { ObjCIvarDecl *ivar = propImpl->getPropertyIvarDecl(); - emitCPPObjectAtomicGetterCall(*this, ReturnValue.emitRawPointer(*this), - ivar, AtomicHelperFn); + emitCPPObjectAtomicGetterCall(*this, ReturnValue.getPointer(), ivar, + AtomicHelperFn); } return; } @@ -1163,7 +1163,7 @@ CodeGenFunction::generateObjCGetterBody(const ObjCImplementationDecl *classImpl, } else { ObjCIvarDecl *ivar = propImpl->getPropertyIvarDecl(); - emitCPPObjectAtomicGetterCall(*this, ReturnValue.emitRawPointer(*this), + emitCPPObjectAtomicGetterCall(*this, ReturnValue.getPointer(), ivar, AtomicHelperFn); } return; @@ -1287,7 +1287,7 @@ CodeGenFunction::generateObjCGetterBody(const ObjCImplementationDecl *classImpl, case TEK_Scalar: { llvm::Value *value; if (propType->isReferenceType()) { - value = LV.getAddress(*this).emitRawPointer(*this); + value = LV.getAddress(*this).getPointer(); } else { // We want to load and autoreleaseReturnValue ARC __weak ivars. if (LV.getQuals().getObjCLifetime() == Qualifiers::OCL_Weak) { @@ -1821,14 +1821,16 @@ void CodeGenFunction::EmitObjCForCollectionStmt(const ObjCForCollectionStmt &S){ CallArgList Args; // The first argument is a temporary of the enumeration-state type. - Args.add(RValue::get(StatePtr, *this), getContext().getPointerType(StateTy)); + Args.add(RValue::get(StatePtr.getPointer()), + getContext().getPointerType(StateTy)); // The second argument is a temporary array with space for NumItems // pointers. We'll actually be loading elements from the array // pointer written into the control state; this buffer is so that // collections that *aren't* backed by arrays can still queue up // batches of elements. - Args.add(RValue::get(ItemsPtr, *this), getContext().getPointerType(ItemsTy)); + Args.add(RValue::get(ItemsPtr.getPointer()), + getContext().getPointerType(ItemsTy)); // The third argument is the capacity of that temporary array. llvm::Type *NSUIntegerTy = ConvertType(getContext().getNSUIntegerType()); @@ -2196,7 +2198,7 @@ static llvm::Value *emitARCLoadOperation(CodeGenFunction &CGF, Address addr, if (!fn) fn = getARCIntrinsic(IntID, CGF.CGM); - return CGF.EmitNounwindRuntimeCall(fn, addr.emitRawPointer(CGF)); + return CGF.EmitNounwindRuntimeCall(fn, addr.getPointer()); } /// Perform an operation having the following signature: @@ -2214,8 +2216,9 @@ static llvm::Value *emitARCStoreOperation(CodeGenFunction &CGF, Address addr, llvm::Type *origType = value->getType(); llvm::Value *args[] = { - CGF.Builder.CreateBitCast(addr.emitRawPointer(CGF), CGF.Int8PtrPtrTy), - CGF.Builder.CreateBitCast(value, CGF.Int8PtrTy)}; + CGF.Builder.CreateBitCast(addr.getPointer(), CGF.Int8PtrPtrTy), + CGF.Builder.CreateBitCast(value, CGF.Int8PtrTy) + }; llvm::CallInst *result = CGF.EmitNounwindRuntimeCall(fn, args); if (ignored) return nullptr; @@ -2234,8 +2237,9 @@ static void emitARCCopyOperation(CodeGenFunction &CGF, Address dst, Address src, fn = getARCIntrinsic(IntID, CGF.CGM); llvm::Value *args[] = { - CGF.Builder.CreateBitCast(dst.emitRawPointer(CGF), CGF.Int8PtrPtrTy), - CGF.Builder.CreateBitCast(src.emitRawPointer(CGF), CGF.Int8PtrPtrTy)}; + CGF.Builder.CreateBitCast(dst.getPointer(), CGF.Int8PtrPtrTy), + CGF.Builder.CreateBitCast(src.getPointer(), CGF.Int8PtrPtrTy) + }; CGF.EmitNounwindRuntimeCall(fn, args); } @@ -2486,8 +2490,9 @@ llvm::Value *CodeGenFunction::EmitARCStoreStrongCall(Address addr, fn = getARCIntrinsic(llvm::Intrinsic::objc_storeStrong, CGM); llvm::Value *args[] = { - Builder.CreateBitCast(addr.emitRawPointer(*this), Int8PtrPtrTy), - Builder.CreateBitCast(value, Int8PtrTy)}; + Builder.CreateBitCast(addr.getPointer(), Int8PtrPtrTy), + Builder.CreateBitCast(value, Int8PtrTy) + }; EmitNounwindRuntimeCall(fn, args); if (ignored) return nullptr; @@ -2638,7 +2643,7 @@ void CodeGenFunction::EmitARCDestroyWeak(Address addr) { if (!fn) fn = getARCIntrinsic(llvm::Intrinsic::objc_destroyWeak, CGM); - EmitNounwindRuntimeCall(fn, addr.emitRawPointer(*this)); + EmitNounwindRuntimeCall(fn, addr.getPointer()); } /// void \@objc_moveWeak(i8** %dest, i8** %src) diff --git a/clang/lib/CodeGen/CGObjCGNU.cpp b/clang/lib/CodeGen/CGObjCGNU.cpp index 4e7f777ba1d9..a36b0cdddaf0 100644 --- a/clang/lib/CodeGen/CGObjCGNU.cpp +++ b/clang/lib/CodeGen/CGObjCGNU.cpp @@ -706,8 +706,7 @@ protected: llvm::Value *cmd, MessageSendInfo &MSI) override { CGBuilderTy &Builder = CGF.Builder; llvm::Value *lookupArgs[] = { - EnforceType(Builder, ObjCSuper.emitRawPointer(CGF), PtrToObjCSuperTy), - cmd}; + EnforceType(Builder, ObjCSuper.getPointer(), PtrToObjCSuperTy), cmd}; return CGF.EmitNounwindRuntimeCall(MsgLookupSuperFn, lookupArgs); } @@ -762,8 +761,8 @@ class CGObjCGNUstep : public CGObjCGNU { llvm::FunctionCallee LookupFn = SlotLookupFn; // Store the receiver on the stack so that we can reload it later - RawAddress ReceiverPtr = - CGF.CreateTempAlloca(Receiver->getType(), CGF.getPointerAlign()); + Address ReceiverPtr = + CGF.CreateTempAlloca(Receiver->getType(), CGF.getPointerAlign()); Builder.CreateStore(Receiver, ReceiverPtr); llvm::Value *self; @@ -779,9 +778,9 @@ class CGObjCGNUstep : public CGObjCGNU { LookupFn2->addParamAttr(0, llvm::Attribute::NoCapture); llvm::Value *args[] = { - EnforceType(Builder, ReceiverPtr.getPointer(), PtrToIdTy), - EnforceType(Builder, cmd, SelectorTy), - EnforceType(Builder, self, IdTy)}; + EnforceType(Builder, ReceiverPtr.getPointer(), PtrToIdTy), + EnforceType(Builder, cmd, SelectorTy), + EnforceType(Builder, self, IdTy) }; llvm::CallBase *slot = CGF.EmitRuntimeCallOrInvoke(LookupFn, args); slot->setOnlyReadsMemory(); slot->setMetadata(msgSendMDKind, node); @@ -801,7 +800,7 @@ class CGObjCGNUstep : public CGObjCGNU { llvm::Value *cmd, MessageSendInfo &MSI) override { CGBuilderTy &Builder = CGF.Builder; - llvm::Value *lookupArgs[] = {ObjCSuper.emitRawPointer(CGF), cmd}; + llvm::Value *lookupArgs[] = {ObjCSuper.getPointer(), cmd}; llvm::CallInst *slot = CGF.EmitNounwindRuntimeCall(SlotLookupSuperFn, lookupArgs); @@ -1222,10 +1221,10 @@ class CGObjCGNUstep2 : public CGObjCGNUstep { llvm::Value *cmd, MessageSendInfo &MSI) override { // Don't access the slot unless we're trying to cache the result. CGBuilderTy &Builder = CGF.Builder; - llvm::Value *lookupArgs[] = { - CGObjCGNU::EnforceType(Builder, ObjCSuper.emitRawPointer(CGF), - PtrToObjCSuperTy), - cmd}; + llvm::Value *lookupArgs[] = {CGObjCGNU::EnforceType(Builder, + ObjCSuper.getPointer(), + PtrToObjCSuperTy), + cmd}; return CGF.EmitNounwindRuntimeCall(MsgLookupSuperFn, lookupArgs); } @@ -2187,8 +2186,7 @@ protected: llvm::Value *cmd, MessageSendInfo &MSI) override { CGBuilderTy &Builder = CGF.Builder; llvm::Value *lookupArgs[] = { - EnforceType(Builder, ObjCSuper.emitRawPointer(CGF), PtrToObjCSuperTy), - cmd, + EnforceType(Builder, ObjCSuper.getPointer(), PtrToObjCSuperTy), cmd, }; if (CGM.ReturnTypeUsesSRet(MSI.CallInfo)) @@ -4203,15 +4201,15 @@ void CGObjCGNU::EmitThrowStmt(CodeGenFunction &CGF, llvm::Value * CGObjCGNU::EmitObjCWeakRead(CodeGenFunction &CGF, Address AddrWeakObj) { CGBuilderTy &B = CGF.Builder; - return B.CreateCall( - WeakReadFn, EnforceType(B, AddrWeakObj.emitRawPointer(CGF), PtrToIdTy)); + return B.CreateCall(WeakReadFn, + EnforceType(B, AddrWeakObj.getPointer(), PtrToIdTy)); } void CGObjCGNU::EmitObjCWeakAssign(CodeGenFunction &CGF, llvm::Value *src, Address dst) { CGBuilderTy &B = CGF.Builder; src = EnforceType(B, src, IdTy); - llvm::Value *dstVal = EnforceType(B, dst.emitRawPointer(CGF), PtrToIdTy); + llvm::Value *dstVal = EnforceType(B, dst.getPointer(), PtrToIdTy); B.CreateCall(WeakAssignFn, {src, dstVal}); } @@ -4220,7 +4218,7 @@ void CGObjCGNU::EmitObjCGlobalAssign(CodeGenFunction &CGF, bool threadlocal) { CGBuilderTy &B = CGF.Builder; src = EnforceType(B, src, IdTy); - llvm::Value *dstVal = EnforceType(B, dst.emitRawPointer(CGF), PtrToIdTy); + llvm::Value *dstVal = EnforceType(B, dst.getPointer(), PtrToIdTy); // FIXME. Add threadloca assign API assert(!threadlocal && "EmitObjCGlobalAssign - Threal Local API NYI"); B.CreateCall(GlobalAssignFn, {src, dstVal}); @@ -4231,7 +4229,7 @@ void CGObjCGNU::EmitObjCIvarAssign(CodeGenFunction &CGF, llvm::Value *ivarOffset) { CGBuilderTy &B = CGF.Builder; src = EnforceType(B, src, IdTy); - llvm::Value *dstVal = EnforceType(B, dst.emitRawPointer(CGF), IdTy); + llvm::Value *dstVal = EnforceType(B, dst.getPointer(), IdTy); B.CreateCall(IvarAssignFn, {src, dstVal, ivarOffset}); } @@ -4239,7 +4237,7 @@ void CGObjCGNU::EmitObjCStrongCastAssign(CodeGenFunction &CGF, llvm::Value *src, Address dst) { CGBuilderTy &B = CGF.Builder; src = EnforceType(B, src, IdTy); - llvm::Value *dstVal = EnforceType(B, dst.emitRawPointer(CGF), PtrToIdTy); + llvm::Value *dstVal = EnforceType(B, dst.getPointer(), PtrToIdTy); B.CreateCall(StrongCastAssignFn, {src, dstVal}); } @@ -4248,8 +4246,8 @@ void CGObjCGNU::EmitGCMemmoveCollectable(CodeGenFunction &CGF, Address SrcPtr, llvm::Value *Size) { CGBuilderTy &B = CGF.Builder; - llvm::Value *DestPtrVal = EnforceType(B, DestPtr.emitRawPointer(CGF), PtrTy); - llvm::Value *SrcPtrVal = EnforceType(B, SrcPtr.emitRawPointer(CGF), PtrTy); + llvm::Value *DestPtrVal = EnforceType(B, DestPtr.getPointer(), PtrTy); + llvm::Value *SrcPtrVal = EnforceType(B, SrcPtr.getPointer(), PtrTy); B.CreateCall(MemMoveFn, {DestPtrVal, SrcPtrVal, Size}); } diff --git a/clang/lib/CodeGen/CGObjCMac.cpp b/clang/lib/CodeGen/CGObjCMac.cpp index 8a599c10e1ca..ed8d7b9a065d 100644 --- a/clang/lib/CodeGen/CGObjCMac.cpp +++ b/clang/lib/CodeGen/CGObjCMac.cpp @@ -1310,7 +1310,7 @@ private: /// EmitSelector - Return a Value*, of type ObjCTypes.SelectorPtrTy, /// for the given selector. llvm::Value *EmitSelector(CodeGenFunction &CGF, Selector Sel); - ConstantAddress EmitSelectorAddr(Selector Sel); + Address EmitSelectorAddr(Selector Sel); public: CGObjCMac(CodeGen::CodeGenModule &cgm); @@ -1538,7 +1538,7 @@ private: /// EmitSelector - Return a Value*, of type ObjCTypes.SelectorPtrTy, /// for the given selector. llvm::Value *EmitSelector(CodeGenFunction &CGF, Selector Sel); - ConstantAddress EmitSelectorAddr(Selector Sel); + Address EmitSelectorAddr(Selector Sel); /// GetInterfaceEHType - Get the cached ehtype for the given Objective-C /// interface. The return value has type EHTypePtrTy. @@ -2064,8 +2064,9 @@ CGObjCMac::GenerateMessageSendSuper(CodeGen::CodeGenFunction &CGF, const ObjCMethodDecl *Method) { // Create and init a super structure; this is a (receiver, class) // pair we will pass to objc_msgSendSuper. - RawAddress ObjCSuper = CGF.CreateTempAlloca( - ObjCTypes.SuperTy, CGF.getPointerAlign(), "objc_super"); + Address ObjCSuper = + CGF.CreateTempAlloca(ObjCTypes.SuperTy, CGF.getPointerAlign(), + "objc_super"); llvm::Value *ReceiverAsObject = CGF.Builder.CreateBitCast(Receiver, ObjCTypes.ObjectPtrTy); CGF.Builder.CreateStore(ReceiverAsObject, @@ -4258,7 +4259,7 @@ namespace { CGF.EmitBlock(FinallyCallExit); CGF.EmitNounwindRuntimeCall(ObjCTypes.getExceptionTryExitFn(), - ExceptionData.emitRawPointer(CGF)); + ExceptionData.getPointer()); CGF.EmitBlock(FinallyNoCallExit); @@ -4424,9 +4425,7 @@ void FragileHazards::emitHazardsInNewBlocks() { } static void addIfPresent(llvm::DenseSet &S, Address V) { - if (V.isValid()) - if (llvm::Value *Ptr = V.getBasePointer()) - S.insert(Ptr); + if (V.isValid()) S.insert(V.getPointer()); } void FragileHazards::collectLocals() { @@ -4629,13 +4628,13 @@ void CGObjCMac::EmitTryOrSynchronizedStmt(CodeGen::CodeGenFunction &CGF, // - Call objc_exception_try_enter to push ExceptionData on top of // the EH stack. CGF.EmitNounwindRuntimeCall(ObjCTypes.getExceptionTryEnterFn(), - ExceptionData.emitRawPointer(CGF)); + ExceptionData.getPointer()); // - Call setjmp on the exception data buffer. llvm::Constant *Zero = llvm::ConstantInt::get(CGF.Builder.getInt32Ty(), 0); llvm::Value *GEPIndexes[] = { Zero, Zero, Zero }; llvm::Value *SetJmpBuffer = CGF.Builder.CreateGEP( - ObjCTypes.ExceptionDataTy, ExceptionData.emitRawPointer(CGF), GEPIndexes, + ObjCTypes.ExceptionDataTy, ExceptionData.getPointer(), GEPIndexes, "setjmp_buffer"); llvm::CallInst *SetJmpResult = CGF.EmitNounwindRuntimeCall( ObjCTypes.getSetJmpFn(), SetJmpBuffer, "setjmp_result"); @@ -4674,9 +4673,9 @@ void CGObjCMac::EmitTryOrSynchronizedStmt(CodeGen::CodeGenFunction &CGF, } else { // Retrieve the exception object. We may emit multiple blocks but // nothing can cross this so the value is already in SSA form. - llvm::CallInst *Caught = CGF.EmitNounwindRuntimeCall( - ObjCTypes.getExceptionExtractFn(), ExceptionData.emitRawPointer(CGF), - "caught"); + llvm::CallInst *Caught = + CGF.EmitNounwindRuntimeCall(ObjCTypes.getExceptionExtractFn(), + ExceptionData.getPointer(), "caught"); // Push the exception to rethrow onto the EH value stack for the // benefit of any @throws in the handlers. @@ -4699,7 +4698,7 @@ void CGObjCMac::EmitTryOrSynchronizedStmt(CodeGen::CodeGenFunction &CGF, // Enter a new exception try block (in case a @catch block // throws an exception). CGF.EmitNounwindRuntimeCall(ObjCTypes.getExceptionTryEnterFn(), - ExceptionData.emitRawPointer(CGF)); + ExceptionData.getPointer()); llvm::CallInst *SetJmpResult = CGF.EmitNounwindRuntimeCall(ObjCTypes.getSetJmpFn(), @@ -4830,9 +4829,9 @@ void CGObjCMac::EmitTryOrSynchronizedStmt(CodeGen::CodeGenFunction &CGF, // Extract the new exception and save it to the // propagating-exception slot. assert(PropagatingExnVar.isValid()); - llvm::CallInst *NewCaught = CGF.EmitNounwindRuntimeCall( - ObjCTypes.getExceptionExtractFn(), ExceptionData.emitRawPointer(CGF), - "caught"); + llvm::CallInst *NewCaught = + CGF.EmitNounwindRuntimeCall(ObjCTypes.getExceptionExtractFn(), + ExceptionData.getPointer(), "caught"); CGF.Builder.CreateStore(NewCaught, PropagatingExnVar); // Don't pop the catch handler; the throw already did. @@ -4862,8 +4861,9 @@ void CGObjCMac::EmitTryOrSynchronizedStmt(CodeGen::CodeGenFunction &CGF, // Otherwise, just look in the buffer for the exception to throw. } else { - llvm::CallInst *Caught = CGF.EmitNounwindRuntimeCall( - ObjCTypes.getExceptionExtractFn(), ExceptionData.emitRawPointer(CGF)); + llvm::CallInst *Caught = + CGF.EmitNounwindRuntimeCall(ObjCTypes.getExceptionExtractFn(), + ExceptionData.getPointer()); PropagatingExn = Caught; } @@ -4906,7 +4906,7 @@ llvm::Value * CGObjCMac::EmitObjCWeakRead(CodeGen::CodeGenFunction &CGF, Address AddrWeakObj) { llvm::Type* DestTy = AddrWeakObj.getElementType(); llvm::Value *AddrWeakObjVal = CGF.Builder.CreateBitCast( - AddrWeakObj.emitRawPointer(CGF), ObjCTypes.PtrObjectPtrTy); + AddrWeakObj.getPointer(), ObjCTypes.PtrObjectPtrTy); llvm::Value *read_weak = CGF.EmitNounwindRuntimeCall(ObjCTypes.getGcReadWeakFn(), AddrWeakObjVal, "weakread"); @@ -4928,8 +4928,8 @@ void CGObjCMac::EmitObjCWeakAssign(CodeGen::CodeGenFunction &CGF, src = CGF.Builder.CreateIntToPtr(src, ObjCTypes.Int8PtrTy); } src = CGF.Builder.CreateBitCast(src, ObjCTypes.ObjectPtrTy); - llvm::Value *dstVal = CGF.Builder.CreateBitCast(dst.emitRawPointer(CGF), - ObjCTypes.PtrObjectPtrTy); + llvm::Value *dstVal = + CGF.Builder.CreateBitCast(dst.getPointer(), ObjCTypes.PtrObjectPtrTy); llvm::Value *args[] = { src, dstVal }; CGF.EmitNounwindRuntimeCall(ObjCTypes.getGcAssignWeakFn(), args, "weakassign"); @@ -4950,8 +4950,8 @@ void CGObjCMac::EmitObjCGlobalAssign(CodeGen::CodeGenFunction &CGF, src = CGF.Builder.CreateIntToPtr(src, ObjCTypes.Int8PtrTy); } src = CGF.Builder.CreateBitCast(src, ObjCTypes.ObjectPtrTy); - llvm::Value *dstVal = CGF.Builder.CreateBitCast(dst.emitRawPointer(CGF), - ObjCTypes.PtrObjectPtrTy); + llvm::Value *dstVal = + CGF.Builder.CreateBitCast(dst.getPointer(), ObjCTypes.PtrObjectPtrTy); llvm::Value *args[] = {src, dstVal}; if (!threadlocal) CGF.EmitNounwindRuntimeCall(ObjCTypes.getGcAssignGlobalFn(), @@ -4977,8 +4977,8 @@ void CGObjCMac::EmitObjCIvarAssign(CodeGen::CodeGenFunction &CGF, src = CGF.Builder.CreateIntToPtr(src, ObjCTypes.Int8PtrTy); } src = CGF.Builder.CreateBitCast(src, ObjCTypes.ObjectPtrTy); - llvm::Value *dstVal = CGF.Builder.CreateBitCast(dst.emitRawPointer(CGF), - ObjCTypes.PtrObjectPtrTy); + llvm::Value *dstVal = + CGF.Builder.CreateBitCast(dst.getPointer(), ObjCTypes.PtrObjectPtrTy); llvm::Value *args[] = {src, dstVal, ivarOffset}; CGF.EmitNounwindRuntimeCall(ObjCTypes.getGcAssignIvarFn(), args); } @@ -4997,8 +4997,8 @@ void CGObjCMac::EmitObjCStrongCastAssign(CodeGen::CodeGenFunction &CGF, src = CGF.Builder.CreateIntToPtr(src, ObjCTypes.Int8PtrTy); } src = CGF.Builder.CreateBitCast(src, ObjCTypes.ObjectPtrTy); - llvm::Value *dstVal = CGF.Builder.CreateBitCast(dst.emitRawPointer(CGF), - ObjCTypes.PtrObjectPtrTy); + llvm::Value *dstVal = + CGF.Builder.CreateBitCast(dst.getPointer(), ObjCTypes.PtrObjectPtrTy); llvm::Value *args[] = {src, dstVal}; CGF.EmitNounwindRuntimeCall(ObjCTypes.getGcAssignStrongCastFn(), args, "strongassign"); @@ -5007,8 +5007,7 @@ void CGObjCMac::EmitObjCStrongCastAssign(CodeGen::CodeGenFunction &CGF, void CGObjCMac::EmitGCMemmoveCollectable(CodeGen::CodeGenFunction &CGF, Address DestPtr, Address SrcPtr, llvm::Value *size) { - llvm::Value *args[] = {DestPtr.emitRawPointer(CGF), - SrcPtr.emitRawPointer(CGF), size}; + llvm::Value *args[] = { DestPtr.getPointer(), SrcPtr.getPointer(), size }; CGF.EmitNounwindRuntimeCall(ObjCTypes.GcMemmoveCollectableFn(), args); } @@ -5244,7 +5243,7 @@ llvm::Value *CGObjCMac::EmitSelector(CodeGenFunction &CGF, Selector Sel) { return CGF.Builder.CreateLoad(EmitSelectorAddr(Sel)); } -ConstantAddress CGObjCMac::EmitSelectorAddr(Selector Sel) { +Address CGObjCMac::EmitSelectorAddr(Selector Sel) { CharUnits Align = CGM.getPointerAlign(); llvm::GlobalVariable *&Entry = SelectorReferences[Sel]; @@ -5255,7 +5254,7 @@ ConstantAddress CGObjCMac::EmitSelectorAddr(Selector Sel) { Entry->setExternallyInitialized(true); } - return ConstantAddress(Entry, ObjCTypes.SelectorPtrTy, Align); + return Address(Entry, ObjCTypes.SelectorPtrTy, Align); } llvm::Constant *CGObjCCommonMac::GetClassName(StringRef RuntimeName) { @@ -7324,7 +7323,7 @@ CGObjCNonFragileABIMac::EmitVTableMessageSend(CodeGenFunction &CGF, ObjCTypes.MessageRefTy, CGF.getPointerAlign()); // Update the message ref argument. - args[1].setRValue(RValue::get(mref, CGF)); + args[1].setRValue(RValue::get(mref.getPointer())); // Load the function to call from the message ref table. Address calleeAddr = CGF.Builder.CreateStructGEP(mref, 0); @@ -7553,8 +7552,9 @@ CGObjCNonFragileABIMac::GenerateMessageSendSuper(CodeGen::CodeGenFunction &CGF, // ... // Create and init a super structure; this is a (receiver, class) // pair we will pass to objc_msgSendSuper. - RawAddress ObjCSuper = CGF.CreateTempAlloca( - ObjCTypes.SuperTy, CGF.getPointerAlign(), "objc_super"); + Address ObjCSuper = + CGF.CreateTempAlloca(ObjCTypes.SuperTy, CGF.getPointerAlign(), + "objc_super"); llvm::Value *ReceiverAsObject = CGF.Builder.CreateBitCast(Receiver, ObjCTypes.ObjectPtrTy); @@ -7594,7 +7594,7 @@ llvm::Value *CGObjCNonFragileABIMac::EmitSelector(CodeGenFunction &CGF, return LI; } -ConstantAddress CGObjCNonFragileABIMac::EmitSelectorAddr(Selector Sel) { +Address CGObjCNonFragileABIMac::EmitSelectorAddr(Selector Sel) { llvm::GlobalVariable *&Entry = SelectorReferences[Sel]; CharUnits Align = CGM.getPointerAlign(); if (!Entry) { @@ -7610,7 +7610,7 @@ ConstantAddress CGObjCNonFragileABIMac::EmitSelectorAddr(Selector Sel) { CGM.addCompilerUsedGlobal(Entry); } - return ConstantAddress(Entry, ObjCTypes.SelectorPtrTy, Align); + return Address(Entry, ObjCTypes.SelectorPtrTy, Align); } /// EmitObjCIvarAssign - Code gen for assigning to a __strong object. @@ -7629,8 +7629,8 @@ void CGObjCNonFragileABIMac::EmitObjCIvarAssign(CodeGen::CodeGenFunction &CGF, src = CGF.Builder.CreateIntToPtr(src, ObjCTypes.Int8PtrTy); } src = CGF.Builder.CreateBitCast(src, ObjCTypes.ObjectPtrTy); - llvm::Value *dstVal = CGF.Builder.CreateBitCast(dst.emitRawPointer(CGF), - ObjCTypes.PtrObjectPtrTy); + llvm::Value *dstVal = + CGF.Builder.CreateBitCast(dst.getPointer(), ObjCTypes.PtrObjectPtrTy); llvm::Value *args[] = {src, dstVal, ivarOffset}; CGF.EmitNounwindRuntimeCall(ObjCTypes.getGcAssignIvarFn(), args); } @@ -7650,8 +7650,8 @@ void CGObjCNonFragileABIMac::EmitObjCStrongCastAssign( src = CGF.Builder.CreateIntToPtr(src, ObjCTypes.Int8PtrTy); } src = CGF.Builder.CreateBitCast(src, ObjCTypes.ObjectPtrTy); - llvm::Value *dstVal = CGF.Builder.CreateBitCast(dst.emitRawPointer(CGF), - ObjCTypes.PtrObjectPtrTy); + llvm::Value *dstVal = + CGF.Builder.CreateBitCast(dst.getPointer(), ObjCTypes.PtrObjectPtrTy); llvm::Value *args[] = {src, dstVal}; CGF.EmitNounwindRuntimeCall(ObjCTypes.getGcAssignStrongCastFn(), args, "weakassign"); @@ -7660,8 +7660,7 @@ void CGObjCNonFragileABIMac::EmitObjCStrongCastAssign( void CGObjCNonFragileABIMac::EmitGCMemmoveCollectable( CodeGen::CodeGenFunction &CGF, Address DestPtr, Address SrcPtr, llvm::Value *Size) { - llvm::Value *args[] = {DestPtr.emitRawPointer(CGF), - SrcPtr.emitRawPointer(CGF), Size}; + llvm::Value *args[] = { DestPtr.getPointer(), SrcPtr.getPointer(), Size }; CGF.EmitNounwindRuntimeCall(ObjCTypes.GcMemmoveCollectableFn(), args); } @@ -7673,7 +7672,7 @@ llvm::Value * CGObjCNonFragileABIMac::EmitObjCWeakRead( Address AddrWeakObj) { llvm::Type *DestTy = AddrWeakObj.getElementType(); llvm::Value *AddrWeakObjVal = CGF.Builder.CreateBitCast( - AddrWeakObj.emitRawPointer(CGF), ObjCTypes.PtrObjectPtrTy); + AddrWeakObj.getPointer(), ObjCTypes.PtrObjectPtrTy); llvm::Value *read_weak = CGF.EmitNounwindRuntimeCall(ObjCTypes.getGcReadWeakFn(), AddrWeakObjVal, "weakread"); @@ -7695,8 +7694,8 @@ void CGObjCNonFragileABIMac::EmitObjCWeakAssign(CodeGen::CodeGenFunction &CGF, src = CGF.Builder.CreateIntToPtr(src, ObjCTypes.Int8PtrTy); } src = CGF.Builder.CreateBitCast(src, ObjCTypes.ObjectPtrTy); - llvm::Value *dstVal = CGF.Builder.CreateBitCast(dst.emitRawPointer(CGF), - ObjCTypes.PtrObjectPtrTy); + llvm::Value *dstVal = + CGF.Builder.CreateBitCast(dst.getPointer(), ObjCTypes.PtrObjectPtrTy); llvm::Value *args[] = {src, dstVal}; CGF.EmitNounwindRuntimeCall(ObjCTypes.getGcAssignWeakFn(), args, "weakassign"); @@ -7717,8 +7716,8 @@ void CGObjCNonFragileABIMac::EmitObjCGlobalAssign(CodeGen::CodeGenFunction &CGF, src = CGF.Builder.CreateIntToPtr(src, ObjCTypes.Int8PtrTy); } src = CGF.Builder.CreateBitCast(src, ObjCTypes.ObjectPtrTy); - llvm::Value *dstVal = CGF.Builder.CreateBitCast(dst.emitRawPointer(CGF), - ObjCTypes.PtrObjectPtrTy); + llvm::Value *dstVal = + CGF.Builder.CreateBitCast(dst.getPointer(), ObjCTypes.PtrObjectPtrTy); llvm::Value *args[] = {src, dstVal}; if (!threadlocal) CGF.EmitNounwindRuntimeCall(ObjCTypes.getGcAssignGlobalFn(), diff --git a/clang/lib/CodeGen/CGObjCRuntime.cpp b/clang/lib/CodeGen/CGObjCRuntime.cpp index 01d0f35da196..424564f97599 100644 --- a/clang/lib/CodeGen/CGObjCRuntime.cpp +++ b/clang/lib/CodeGen/CGObjCRuntime.cpp @@ -67,7 +67,7 @@ LValue CGObjCRuntime::EmitValueForIvarAtOffset(CodeGen::CodeGenFunction &CGF, V = CGF.Builder.CreateInBoundsGEP(CGF.Int8Ty, V, Offset, "add.ptr"); if (!Ivar->isBitField()) { - LValue LV = CGF.MakeNaturalAlignRawAddrLValue(V, IvarTy); + LValue LV = CGF.MakeNaturalAlignAddrLValue(V, IvarTy); return LV; } @@ -233,7 +233,7 @@ void CGObjCRuntime::EmitTryCatchStmt(CodeGenFunction &CGF, llvm::Instruction *CPICandidate = Handler.Block->getFirstNonPHI(); if (auto *CPI = dyn_cast_or_null(CPICandidate)) { CGF.CurrentFuncletPad = CPI; - CPI->setOperand(2, CGF.getExceptionSlot().emitRawPointer(CGF)); + CPI->setOperand(2, CGF.getExceptionSlot().getPointer()); CGF.EHStack.pushCleanup(NormalCleanup, CPI); } } @@ -405,7 +405,7 @@ bool CGObjCRuntime::canMessageReceiverBeNull(CodeGenFunction &CGF, auto self = curMethod->getSelfDecl(); if (self->getType().isConstQualified()) { if (auto LI = dyn_cast(receiver->stripPointerCasts())) { - llvm::Value *selfAddr = CGF.GetAddrOfLocalVar(self).emitRawPointer(CGF); + llvm::Value *selfAddr = CGF.GetAddrOfLocalVar(self).getPointer(); if (selfAddr == LI->getPointerOperand()) { return false; } diff --git a/clang/lib/CodeGen/CGOpenMPRuntime.cpp b/clang/lib/CodeGen/CGOpenMPRuntime.cpp index bc363313dec6..00e395c2a207 100644 --- a/clang/lib/CodeGen/CGOpenMPRuntime.cpp +++ b/clang/lib/CodeGen/CGOpenMPRuntime.cpp @@ -622,7 +622,7 @@ static void emitInitWithReductionInitializer(CodeGenFunction &CGF, auto *GV = new llvm::GlobalVariable( CGF.CGM.getModule(), Init->getType(), /*isConstant=*/true, llvm::GlobalValue::PrivateLinkage, Init, Name); - LValue LV = CGF.MakeNaturalAlignRawAddrLValue(GV, Ty); + LValue LV = CGF.MakeNaturalAlignAddrLValue(GV, Ty); RValue InitRVal; switch (CGF.getEvaluationKind(Ty)) { case TEK_Scalar: @@ -668,8 +668,8 @@ static void EmitOMPAggregateInit(CodeGenFunction &CGF, Address DestAddr, llvm::Value *SrcBegin = nullptr; if (DRD) - SrcBegin = SrcAddr.emitRawPointer(CGF); - llvm::Value *DestBegin = DestAddr.emitRawPointer(CGF); + SrcBegin = SrcAddr.getPointer(); + llvm::Value *DestBegin = DestAddr.getPointer(); // Cast from pointer to array type to pointer to single element. llvm::Value *DestEnd = CGF.Builder.CreateGEP(DestAddr.getElementType(), DestBegin, NumElements); @@ -912,7 +912,7 @@ static LValue loadToBegin(CodeGenFunction &CGF, QualType BaseTy, QualType ElTy, static Address castToBase(CodeGenFunction &CGF, QualType BaseTy, QualType ElTy, Address OriginalBaseAddress, llvm::Value *Addr) { - RawAddress Tmp = RawAddress::invalid(); + Address Tmp = Address::invalid(); Address TopTmp = Address::invalid(); Address MostTopTmp = Address::invalid(); BaseTy = BaseTy.getNonReferenceType(); @@ -971,10 +971,10 @@ Address ReductionCodeGen::adjustPrivateAddress(CodeGenFunction &CGF, unsigned N, Address SharedAddr = SharedAddresses[N].first.getAddress(CGF); llvm::Value *Adjustment = CGF.Builder.CreatePtrDiff( SharedAddr.getElementType(), BaseLValue.getPointer(CGF), - SharedAddr.emitRawPointer(CGF)); + SharedAddr.getPointer()); llvm::Value *PrivatePointer = CGF.Builder.CreatePointerBitCastOrAddrSpaceCast( - PrivateAddr.emitRawPointer(CGF), SharedAddr.getType()); + PrivateAddr.getPointer(), SharedAddr.getType()); llvm::Value *Ptr = CGF.Builder.CreateGEP( SharedAddr.getElementType(), PrivatePointer, Adjustment); return castToBase(CGF, OrigVD->getType(), @@ -1557,7 +1557,7 @@ static llvm::TargetRegionEntryInfo getEntryInfoFromPresumedLoc( return OMPBuilder.getTargetEntryUniqueInfo(FileInfoCallBack, ParentName); } -ConstantAddress CGOpenMPRuntime::getAddrOfDeclareTargetVar(const VarDecl *VD) { +Address CGOpenMPRuntime::getAddrOfDeclareTargetVar(const VarDecl *VD) { auto AddrOfGlobal = [&VD, this]() { return CGM.GetAddrOfGlobal(VD); }; auto LinkageForVariable = [&VD, this]() { @@ -1579,8 +1579,8 @@ ConstantAddress CGOpenMPRuntime::getAddrOfDeclareTargetVar(const VarDecl *VD) { LinkageForVariable); if (!addr) - return ConstantAddress::invalid(); - return ConstantAddress(addr, LlvmPtrTy, CGM.getContext().getDeclAlign(VD)); + return Address::invalid(); + return Address(addr, LlvmPtrTy, CGM.getContext().getDeclAlign(VD)); } llvm::Constant * @@ -1604,7 +1604,7 @@ Address CGOpenMPRuntime::getAddrOfThreadPrivate(CodeGenFunction &CGF, llvm::Type *VarTy = VDAddr.getElementType(); llvm::Value *Args[] = { emitUpdateLocation(CGF, Loc), getThreadID(CGF, Loc), - CGF.Builder.CreatePointerCast(VDAddr.emitRawPointer(CGF), CGM.Int8PtrTy), + CGF.Builder.CreatePointerCast(VDAddr.getPointer(), CGM.Int8PtrTy), CGM.getSize(CGM.GetTargetTypeStoreSize(VarTy)), getOrCreateThreadPrivateCache(VD)}; return Address( @@ -1627,8 +1627,7 @@ void CGOpenMPRuntime::emitThreadPrivateVarInit( // Call __kmpc_threadprivate_register(&loc, &var, ctor, cctor/*NULL*/, dtor) // to register constructor/destructor for variable. llvm::Value *Args[] = { - OMPLoc, - CGF.Builder.CreatePointerCast(VDAddr.emitRawPointer(CGF), CGM.VoidPtrTy), + OMPLoc, CGF.Builder.CreatePointerCast(VDAddr.getPointer(), CGM.VoidPtrTy), Ctor, CopyCtor, Dtor}; CGF.EmitRuntimeCall( OMPBuilder.getOrCreateRuntimeFunction( @@ -1901,13 +1900,13 @@ void CGOpenMPRuntime::emitParallelCall(CodeGenFunction &CGF, SourceLocation Loc, // OutlinedFn(>id, &zero_bound, CapturedStruct); Address ThreadIDAddr = RT.emitThreadIDAddress(CGF, Loc); - RawAddress ZeroAddrBound = + Address ZeroAddrBound = CGF.CreateDefaultAlignTempAlloca(CGF.Int32Ty, /*Name=*/".bound.zero.addr"); CGF.Builder.CreateStore(CGF.Builder.getInt32(/*C*/ 0), ZeroAddrBound); llvm::SmallVector OutlinedFnArgs; // ThreadId for serialized parallels is 0. - OutlinedFnArgs.push_back(ThreadIDAddr.emitRawPointer(CGF)); + OutlinedFnArgs.push_back(ThreadIDAddr.getPointer()); OutlinedFnArgs.push_back(ZeroAddrBound.getPointer()); OutlinedFnArgs.append(CapturedVars.begin(), CapturedVars.end()); @@ -2273,7 +2272,7 @@ void CGOpenMPRuntime::emitSingleRegion(CodeGenFunction &CGF, emitUpdateLocation(CGF, Loc), // ident_t * getThreadID(CGF, Loc), // i32 BufSize, // size_t - CL.emitRawPointer(CGF), // void * + CL.getPointer(), // void * CpyFn, // void (*) (void *, void *) DidItVal // i32 did_it }; @@ -2592,10 +2591,10 @@ static void emitForStaticInitCall( ThreadId, CGF.Builder.getInt32(addMonoNonMonoModifier(CGF.CGM, Schedule, M1, M2)), // Schedule type - Values.IL.emitRawPointer(CGF), // &isLastIter - Values.LB.emitRawPointer(CGF), // &LB - Values.UB.emitRawPointer(CGF), // &UB - Values.ST.emitRawPointer(CGF), // &Stride + Values.IL.getPointer(), // &isLastIter + Values.LB.getPointer(), // &LB + Values.UB.getPointer(), // &UB + Values.ST.getPointer(), // &Stride CGF.Builder.getIntN(Values.IVSize, 1), // Incr Chunk // Chunk }; @@ -2698,11 +2697,12 @@ llvm::Value *CGOpenMPRuntime::emitForNext(CodeGenFunction &CGF, // kmp_int[32|64] *p_lower, kmp_int[32|64] *p_upper, // kmp_int[32|64] *p_stride); llvm::Value *Args[] = { - emitUpdateLocation(CGF, Loc), getThreadID(CGF, Loc), - IL.emitRawPointer(CGF), // &isLastIter - LB.emitRawPointer(CGF), // &Lower - UB.emitRawPointer(CGF), // &Upper - ST.emitRawPointer(CGF) // &Stride + emitUpdateLocation(CGF, Loc), + getThreadID(CGF, Loc), + IL.getPointer(), // &isLastIter + LB.getPointer(), // &Lower + UB.getPointer(), // &Upper + ST.getPointer() // &Stride }; llvm::Value *Call = CGF.EmitRuntimeCall( OMPBuilder.createDispatchNextFunction(IVSize, IVSigned), Args); @@ -3047,7 +3047,7 @@ emitProxyTaskFunction(CodeGenModule &CGM, SourceLocation Loc, CGF.Builder .CreatePointerBitCastOrAddrSpaceCast(TDBase.getAddress(CGF), CGF.VoidPtrTy, CGF.Int8Ty) - .emitRawPointer(CGF)}; + .getPointer()}; SmallVector CallArgs(std::begin(CommonArgs), std::end(CommonArgs)); if (isOpenMPTaskLoopDirective(Kind)) { @@ -3574,8 +3574,7 @@ getPointerAndSize(CodeGenFunction &CGF, const Expr *E) { CGF.EmitOMPArraySectionExpr(ASE, /*IsLowerBound=*/false); Address UpAddrAddress = UpAddrLVal.getAddress(CGF); llvm::Value *UpAddr = CGF.Builder.CreateConstGEP1_32( - UpAddrAddress.getElementType(), UpAddrAddress.emitRawPointer(CGF), - /*Idx0=*/1); + UpAddrAddress.getElementType(), UpAddrAddress.getPointer(), /*Idx0=*/1); llvm::Value *LowIntPtr = CGF.Builder.CreatePtrToInt(Addr, CGF.SizeTy); llvm::Value *UpIntPtr = CGF.Builder.CreatePtrToInt(UpAddr, CGF.SizeTy); SizeVal = CGF.Builder.CreateNUWSub(UpIntPtr, LowIntPtr); @@ -3889,9 +3888,8 @@ CGOpenMPRuntime::emitTaskInit(CodeGenFunction &CGF, SourceLocation Loc, llvm::Value *Size; std::tie(Addr, Size) = getPointerAndSize(CGF, E); llvm::Value *Idx = CGF.EmitLoadOfScalar(PosLVal, E->getExprLoc()); - LValue Base = - CGF.MakeAddrLValue(CGF.Builder.CreateGEP(CGF, AffinitiesArray, Idx), - KmpTaskAffinityInfoTy); + LValue Base = CGF.MakeAddrLValue( + CGF.Builder.CreateGEP(AffinitiesArray, Idx), KmpTaskAffinityInfoTy); // affs[i].base_addr = &; LValue BaseAddrLVal = CGF.EmitLValueForField( Base, *std::next(KmpAffinityInfoRD->field_begin(), BaseAddr)); @@ -3912,7 +3910,7 @@ CGOpenMPRuntime::emitTaskInit(CodeGenFunction &CGF, SourceLocation Loc, llvm::Value *LocRef = emitUpdateLocation(CGF, Loc); llvm::Value *GTid = getThreadID(CGF, Loc); llvm::Value *AffinListPtr = CGF.Builder.CreatePointerBitCastOrAddrSpaceCast( - AffinitiesArray.emitRawPointer(CGF), CGM.VoidPtrTy); + AffinitiesArray.getPointer(), CGM.VoidPtrTy); // FIXME: Emit the function and ignore its result for now unless the // runtime function is properly implemented. (void)CGF.EmitRuntimeCall( @@ -3923,8 +3921,8 @@ CGOpenMPRuntime::emitTaskInit(CodeGenFunction &CGF, SourceLocation Loc, llvm::Value *NewTaskNewTaskTTy = CGF.Builder.CreatePointerBitCastOrAddrSpaceCast( NewTask, KmpTaskTWithPrivatesPtrTy); - LValue Base = CGF.MakeNaturalAlignRawAddrLValue(NewTaskNewTaskTTy, - KmpTaskTWithPrivatesQTy); + LValue Base = CGF.MakeNaturalAlignAddrLValue(NewTaskNewTaskTTy, + KmpTaskTWithPrivatesQTy); LValue TDBase = CGF.EmitLValueForField(Base, *KmpTaskTWithPrivatesQTyRD->field_begin()); // Fill the data in the resulting kmp_task_t record. @@ -4049,7 +4047,7 @@ CGOpenMPRuntime::getDepobjElements(CodeGenFunction &CGF, LValue DepobjLVal, CGF.ConvertTypeForMem(KmpDependInfoPtrTy)), KmpDependInfoPtrTy->castAs()); Address DepObjAddr = CGF.Builder.CreateGEP( - CGF, Base.getAddress(CGF), + Base.getAddress(CGF), llvm::ConstantInt::get(CGF.IntPtrTy, -1, /*isSigned=*/true)); LValue NumDepsBase = CGF.MakeAddrLValue( DepObjAddr, KmpDependInfoTy, Base.getBaseInfo(), Base.getTBAAInfo()); @@ -4099,7 +4097,7 @@ static void emitDependData(CodeGenFunction &CGF, QualType &KmpDependInfoTy, LValue &PosLVal = *Pos.get(); llvm::Value *Idx = CGF.EmitLoadOfScalar(PosLVal, E->getExprLoc()); Base = CGF.MakeAddrLValue( - CGF.Builder.CreateGEP(CGF, DependenciesArray, Idx), KmpDependInfoTy); + CGF.Builder.CreateGEP(DependenciesArray, Idx), KmpDependInfoTy); } // deps[i].base_addr = &; LValue BaseAddrLVal = CGF.EmitLValueForField( @@ -4197,7 +4195,7 @@ void CGOpenMPRuntime::emitDepobjElements(CodeGenFunction &CGF, ElSize, CGF.Builder.CreateIntCast(NumDeps, CGF.SizeTy, /*isSigned=*/false)); llvm::Value *Pos = CGF.EmitLoadOfScalar(PosLVal, E->getExprLoc()); - Address DepAddr = CGF.Builder.CreateGEP(CGF, DependenciesArray, Pos); + Address DepAddr = CGF.Builder.CreateGEP(DependenciesArray, Pos); CGF.Builder.CreateMemCpy(DepAddr, Base.getAddress(CGF), Size); // Increase pos. @@ -4432,7 +4430,7 @@ void CGOpenMPRuntime::emitDestroyClause(CodeGenFunction &CGF, LValue DepobjLVal, Base.getAddress(CGF), CGF.ConvertTypeForMem(KmpDependInfoPtrTy), CGF.ConvertTypeForMem(KmpDependInfoTy)); llvm::Value *DepObjAddr = CGF.Builder.CreateGEP( - Addr.getElementType(), Addr.emitRawPointer(CGF), + Addr.getElementType(), Addr.getPointer(), llvm::ConstantInt::get(CGF.IntPtrTy, -1, /*isSigned=*/true)); DepObjAddr = CGF.Builder.CreatePointerBitCastOrAddrSpaceCast(DepObjAddr, CGF.VoidPtrTy); @@ -4462,8 +4460,8 @@ void CGOpenMPRuntime::emitUpdateClause(CodeGenFunction &CGF, LValue DepobjLVal, Address Begin = Base.getAddress(CGF); // Cast from pointer to array type to pointer to single element. - llvm::Value *End = CGF.Builder.CreateGEP(Begin.getElementType(), - Begin.emitRawPointer(CGF), NumDeps); + llvm::Value *End = CGF.Builder.CreateGEP( + Begin.getElementType(), Begin.getPointer(), NumDeps); // The basic structure here is a while-do loop. llvm::BasicBlock *BodyBB = CGF.createBasicBlock("omp.body"); llvm::BasicBlock *DoneBB = CGF.createBasicBlock("omp.done"); @@ -4471,7 +4469,7 @@ void CGOpenMPRuntime::emitUpdateClause(CodeGenFunction &CGF, LValue DepobjLVal, CGF.EmitBlock(BodyBB); llvm::PHINode *ElementPHI = CGF.Builder.CreatePHI(Begin.getType(), 2, "omp.elementPast"); - ElementPHI->addIncoming(Begin.emitRawPointer(CGF), EntryBB); + ElementPHI->addIncoming(Begin.getPointer(), EntryBB); Begin = Begin.withPointer(ElementPHI, KnownNonNull); Base = CGF.MakeAddrLValue(Begin, KmpDependInfoTy, Base.getBaseInfo(), Base.getTBAAInfo()); @@ -4485,12 +4483,12 @@ void CGOpenMPRuntime::emitUpdateClause(CodeGenFunction &CGF, LValue DepobjLVal, FlagsLVal); // Shift the address forward by one element. - llvm::Value *ElementNext = - CGF.Builder.CreateConstGEP(Begin, /*Index=*/1, "omp.elementNext") - .emitRawPointer(CGF); - ElementPHI->addIncoming(ElementNext, CGF.Builder.GetInsertBlock()); + Address ElementNext = + CGF.Builder.CreateConstGEP(Begin, /*Index=*/1, "omp.elementNext"); + ElementPHI->addIncoming(ElementNext.getPointer(), + CGF.Builder.GetInsertBlock()); llvm::Value *IsEmpty = - CGF.Builder.CreateICmpEQ(ElementNext, End, "omp.isempty"); + CGF.Builder.CreateICmpEQ(ElementNext.getPointer(), End, "omp.isempty"); CGF.Builder.CreateCondBr(IsEmpty, DoneBB, BodyBB); // Done. CGF.EmitBlock(DoneBB, /*IsFinished=*/true); @@ -4533,7 +4531,7 @@ void CGOpenMPRuntime::emitTaskCall(CodeGenFunction &CGF, SourceLocation Loc, DepTaskArgs[1] = ThreadID; DepTaskArgs[2] = NewTask; DepTaskArgs[3] = NumOfElements; - DepTaskArgs[4] = DependenciesArray.emitRawPointer(CGF); + DepTaskArgs[4] = DependenciesArray.getPointer(); DepTaskArgs[5] = CGF.Builder.getInt32(0); DepTaskArgs[6] = llvm::ConstantPointerNull::get(CGF.VoidPtrTy); } @@ -4565,7 +4563,7 @@ void CGOpenMPRuntime::emitTaskCall(CodeGenFunction &CGF, SourceLocation Loc, DepWaitTaskArgs[0] = UpLoc; DepWaitTaskArgs[1] = ThreadID; DepWaitTaskArgs[2] = NumOfElements; - DepWaitTaskArgs[3] = DependenciesArray.emitRawPointer(CGF); + DepWaitTaskArgs[3] = DependenciesArray.getPointer(); DepWaitTaskArgs[4] = CGF.Builder.getInt32(0); DepWaitTaskArgs[5] = llvm::ConstantPointerNull::get(CGF.VoidPtrTy); DepWaitTaskArgs[6] = @@ -4727,8 +4725,8 @@ static void EmitOMPAggregateReduction( const ArrayType *ArrayTy = Type->getAsArrayTypeUnsafe(); llvm::Value *NumElements = CGF.emitArrayLength(ArrayTy, ElementTy, LHSAddr); - llvm::Value *RHSBegin = RHSAddr.emitRawPointer(CGF); - llvm::Value *LHSBegin = LHSAddr.emitRawPointer(CGF); + llvm::Value *RHSBegin = RHSAddr.getPointer(); + llvm::Value *LHSBegin = LHSAddr.getPointer(); // Cast from pointer to array type to pointer to single element. llvm::Value *LHSEnd = CGF.Builder.CreateGEP(LHSAddr.getElementType(), LHSBegin, NumElements); @@ -4992,7 +4990,7 @@ void CGOpenMPRuntime::emitReduction(CodeGenFunction &CGF, SourceLocation Loc, QualType ReductionArrayTy = C.getConstantArrayType( C.VoidPtrTy, ArraySize, nullptr, ArraySizeModifier::Normal, /*IndexTypeQuals=*/0); - RawAddress ReductionList = + Address ReductionList = CGF.CreateMemTemp(ReductionArrayTy, ".omp.reduction.red_list"); const auto *IPriv = Privates.begin(); unsigned Idx = 0; @@ -5464,7 +5462,7 @@ llvm::Value *CGOpenMPRuntime::emitTaskReductionInit( C.getConstantArrayType(RDType, ArraySize, nullptr, ArraySizeModifier::Normal, /*IndexTypeQuals=*/0); // kmp_task_red_input_t .rd_input.[Size]; - RawAddress TaskRedInput = CGF.CreateMemTemp(ArrayRDType, ".rd_input."); + Address TaskRedInput = CGF.CreateMemTemp(ArrayRDType, ".rd_input."); ReductionCodeGen RCG(Data.ReductionVars, Data.ReductionOrigs, Data.ReductionCopies, Data.ReductionOps); for (unsigned Cnt = 0; Cnt < Size; ++Cnt) { @@ -5475,7 +5473,7 @@ llvm::Value *CGOpenMPRuntime::emitTaskReductionInit( TaskRedInput.getElementType(), TaskRedInput.getPointer(), Idxs, /*SignedIndices=*/false, /*IsSubtraction=*/false, Loc, ".rd_input.gep."); - LValue ElemLVal = CGF.MakeNaturalAlignRawAddrLValue(GEP, RDType); + LValue ElemLVal = CGF.MakeNaturalAlignAddrLValue(GEP, RDType); // ElemLVal.reduce_shar = &Shareds[Cnt]; LValue SharedLVal = CGF.EmitLValueForField(ElemLVal, SharedFD); RCG.emitSharedOrigLValue(CGF, Cnt); @@ -5631,7 +5629,7 @@ void CGOpenMPRuntime::emitTaskwaitCall(CodeGenFunction &CGF, SourceLocation Loc, DepWaitTaskArgs[0] = UpLoc; DepWaitTaskArgs[1] = ThreadID; DepWaitTaskArgs[2] = NumOfElements; - DepWaitTaskArgs[3] = DependenciesArray.emitRawPointer(CGF); + DepWaitTaskArgs[3] = DependenciesArray.getPointer(); DepWaitTaskArgs[4] = CGF.Builder.getInt32(0); DepWaitTaskArgs[5] = llvm::ConstantPointerNull::get(CGF.VoidPtrTy); DepWaitTaskArgs[6] = @@ -5854,7 +5852,7 @@ void CGOpenMPRuntime::emitUsesAllocatorsInit(CodeGenFunction &CGF, AllocatorTraitsLVal = CGF.MakeAddrLValue(Addr, CGF.getContext().VoidPtrTy, AllocatorTraitsLVal.getBaseInfo(), AllocatorTraitsLVal.getTBAAInfo()); - llvm::Value *Traits = Addr.emitRawPointer(CGF); + llvm::Value *Traits = Addr.getPointer(); llvm::Value *AllocatorVal = CGF.EmitRuntimeCall(OMPBuilder.getOrCreateRuntimeFunction( @@ -7314,19 +7312,17 @@ private: CGF.EmitOMPSharedLValue(MC.getAssociatedExpression()) .getAddress(CGF); } - llvm::Value *ComponentLBPtr = ComponentLB.emitRawPointer(CGF); - llvm::Value *LBPtr = LB.emitRawPointer(CGF); - Size = CGF.Builder.CreatePtrDiff(CGF.Int8Ty, ComponentLBPtr, - LBPtr); + Size = CGF.Builder.CreatePtrDiff( + CGF.Int8Ty, ComponentLB.getPointer(), LB.getPointer()); break; } } assert(Size && "Failed to determine structure size"); CombinedInfo.Exprs.emplace_back(MapDecl, MapExpr); - CombinedInfo.BasePointers.push_back(BP.emitRawPointer(CGF)); + CombinedInfo.BasePointers.push_back(BP.getPointer()); CombinedInfo.DevicePtrDecls.push_back(nullptr); CombinedInfo.DevicePointers.push_back(DeviceInfoTy::None); - CombinedInfo.Pointers.push_back(LB.emitRawPointer(CGF)); + CombinedInfo.Pointers.push_back(LB.getPointer()); CombinedInfo.Sizes.push_back(CGF.Builder.CreateIntCast( Size, CGF.Int64Ty, /*isSigned=*/true)); CombinedInfo.Types.push_back(Flags); @@ -7336,14 +7332,13 @@ private: LB = CGF.Builder.CreateConstGEP(ComponentLB, 1); } CombinedInfo.Exprs.emplace_back(MapDecl, MapExpr); - CombinedInfo.BasePointers.push_back(BP.emitRawPointer(CGF)); + CombinedInfo.BasePointers.push_back(BP.getPointer()); CombinedInfo.DevicePtrDecls.push_back(nullptr); CombinedInfo.DevicePointers.push_back(DeviceInfoTy::None); - CombinedInfo.Pointers.push_back(LB.emitRawPointer(CGF)); - llvm::Value *LBPtr = LB.emitRawPointer(CGF); + CombinedInfo.Pointers.push_back(LB.getPointer()); Size = CGF.Builder.CreatePtrDiff( - CGF.Int8Ty, CGF.Builder.CreateConstGEP(HB, 1).emitRawPointer(CGF), - LBPtr); + CGF.Int8Ty, CGF.Builder.CreateConstGEP(HB, 1).getPointer(), + LB.getPointer()); CombinedInfo.Sizes.push_back( CGF.Builder.CreateIntCast(Size, CGF.Int64Ty, /*isSigned=*/true)); CombinedInfo.Types.push_back(Flags); @@ -7361,21 +7356,20 @@ private: (Next == CE && MapType != OMPC_MAP_unknown)) { if (!IsMappingWholeStruct) { CombinedInfo.Exprs.emplace_back(MapDecl, MapExpr); - CombinedInfo.BasePointers.push_back(BP.emitRawPointer(CGF)); + CombinedInfo.BasePointers.push_back(BP.getPointer()); CombinedInfo.DevicePtrDecls.push_back(nullptr); CombinedInfo.DevicePointers.push_back(DeviceInfoTy::None); - CombinedInfo.Pointers.push_back(LB.emitRawPointer(CGF)); + CombinedInfo.Pointers.push_back(LB.getPointer()); CombinedInfo.Sizes.push_back(CGF.Builder.CreateIntCast( Size, CGF.Int64Ty, /*isSigned=*/true)); CombinedInfo.NonContigInfo.Dims.push_back(IsNonContiguous ? DimSize : 1); } else { StructBaseCombinedInfo.Exprs.emplace_back(MapDecl, MapExpr); - StructBaseCombinedInfo.BasePointers.push_back( - BP.emitRawPointer(CGF)); + StructBaseCombinedInfo.BasePointers.push_back(BP.getPointer()); StructBaseCombinedInfo.DevicePtrDecls.push_back(nullptr); StructBaseCombinedInfo.DevicePointers.push_back(DeviceInfoTy::None); - StructBaseCombinedInfo.Pointers.push_back(LB.emitRawPointer(CGF)); + StructBaseCombinedInfo.Pointers.push_back(LB.getPointer()); StructBaseCombinedInfo.Sizes.push_back(CGF.Builder.CreateIntCast( Size, CGF.Int64Ty, /*isSigned=*/true)); StructBaseCombinedInfo.NonContigInfo.Dims.push_back( @@ -8217,11 +8211,11 @@ public: } CombinedInfo.Exprs.push_back(VD); // Base is the base of the struct - CombinedInfo.BasePointers.push_back(PartialStruct.Base.emitRawPointer(CGF)); + CombinedInfo.BasePointers.push_back(PartialStruct.Base.getPointer()); CombinedInfo.DevicePtrDecls.push_back(nullptr); CombinedInfo.DevicePointers.push_back(DeviceInfoTy::None); // Pointer is the address of the lowest element - llvm::Value *LB = LBAddr.emitRawPointer(CGF); + llvm::Value *LB = LBAddr.getPointer(); const CXXMethodDecl *MD = CGF.CurFuncDecl ? dyn_cast(CGF.CurFuncDecl) : nullptr; const CXXRecordDecl *RD = MD ? MD->getParent() : nullptr; @@ -8235,7 +8229,7 @@ public: // if the this[:1] expression had appeared in a map clause with a map-type // of tofrom. // Emit this[:1] - CombinedInfo.Pointers.push_back(PartialStruct.Base.emitRawPointer(CGF)); + CombinedInfo.Pointers.push_back(PartialStruct.Base.getPointer()); QualType Ty = MD->getFunctionObjectParameterType(); llvm::Value *Size = CGF.Builder.CreateIntCast(CGF.getTypeSize(Ty), CGF.Int64Ty, @@ -8244,7 +8238,7 @@ public: } else { CombinedInfo.Pointers.push_back(LB); // Size is (addr of {highest+1} element) - (addr of lowest element) - llvm::Value *HB = HBAddr.emitRawPointer(CGF); + llvm::Value *HB = HBAddr.getPointer(); llvm::Value *HAddr = CGF.Builder.CreateConstGEP1_32( HBAddr.getElementType(), HB, /*Idx0=*/1); llvm::Value *CLAddr = CGF.Builder.CreatePointerCast(LB, CGF.VoidPtrTy); @@ -8753,7 +8747,7 @@ public: Address PtrAddr = CGF.EmitLoadOfReference(CGF.MakeAddrLValue( CV, ElementType, CGF.getContext().getDeclAlign(VD), AlignmentSource::Decl)); - CombinedInfo.Pointers.push_back(PtrAddr.emitRawPointer(CGF)); + CombinedInfo.Pointers.push_back(PtrAddr.getPointer()); } else { CombinedInfo.Pointers.push_back(CV); } @@ -9564,11 +9558,10 @@ static void emitTargetCallKernelLaunch( bool HasNoWait = D.hasClausesOfKind(); unsigned NumTargetItems = InputInfo.NumberOfTargetItems; - llvm::Value *BasePointersArray = - InputInfo.BasePointersArray.emitRawPointer(CGF); - llvm::Value *PointersArray = InputInfo.PointersArray.emitRawPointer(CGF); - llvm::Value *SizesArray = InputInfo.SizesArray.emitRawPointer(CGF); - llvm::Value *MappersArray = InputInfo.MappersArray.emitRawPointer(CGF); + llvm::Value *BasePointersArray = InputInfo.BasePointersArray.getPointer(); + llvm::Value *PointersArray = InputInfo.PointersArray.getPointer(); + llvm::Value *SizesArray = InputInfo.SizesArray.getPointer(); + llvm::Value *MappersArray = InputInfo.MappersArray.getPointer(); auto &&EmitTargetCallFallbackCB = [&OMPRuntime, OutlinedFn, &D, &CapturedVars, RequiresOuterTask, &CS, @@ -10316,16 +10309,15 @@ void CGOpenMPRuntime::emitTargetDataStandAloneCall( // Source location for the ident struct llvm::Value *RTLoc = emitUpdateLocation(CGF, D.getBeginLoc()); - llvm::Value *OffloadingArgs[] = { - RTLoc, - DeviceID, - PointerNum, - InputInfo.BasePointersArray.emitRawPointer(CGF), - InputInfo.PointersArray.emitRawPointer(CGF), - InputInfo.SizesArray.emitRawPointer(CGF), - MapTypesArray, - MapNamesArray, - InputInfo.MappersArray.emitRawPointer(CGF)}; + llvm::Value *OffloadingArgs[] = {RTLoc, + DeviceID, + PointerNum, + InputInfo.BasePointersArray.getPointer(), + InputInfo.PointersArray.getPointer(), + InputInfo.SizesArray.getPointer(), + MapTypesArray, + MapNamesArray, + InputInfo.MappersArray.getPointer()}; // Select the right runtime function call for each standalone // directive. @@ -11136,7 +11128,7 @@ void CGOpenMPRuntime::emitDoacrossInit(CodeGenFunction &CGF, getThreadID(CGF, D.getBeginLoc()), llvm::ConstantInt::getSigned(CGM.Int32Ty, NumIterations.size()), CGF.Builder.CreatePointerBitCastOrAddrSpaceCast( - CGF.Builder.CreateConstArrayGEP(DimsAddr, 0).emitRawPointer(CGF), + CGF.Builder.CreateConstArrayGEP(DimsAddr, 0).getPointer(), CGM.VoidPtrTy)}; llvm::FunctionCallee RTLFn = OMPBuilder.getOrCreateRuntimeFunction( @@ -11170,8 +11162,7 @@ static void EmitDoacrossOrdered(CodeGenFunction &CGF, CodeGenModule &CGM, /*Volatile=*/false, Int64Ty); } llvm::Value *Args[] = { - ULoc, ThreadID, - CGF.Builder.CreateConstArrayGEP(CntAddr, 0).emitRawPointer(CGF)}; + ULoc, ThreadID, CGF.Builder.CreateConstArrayGEP(CntAddr, 0).getPointer()}; llvm::FunctionCallee RTLFn; llvm::OpenMPIRBuilder &OMPBuilder = CGM.getOpenMPRuntime().getOMPBuilder(); OMPDoacrossKind ODK; @@ -11341,7 +11332,7 @@ Address CGOpenMPRuntime::getAddressOfLocalVariable(CodeGenFunction &CGF, Args[0] = CGF.CGM.getOpenMPRuntime().getThreadID( CGF, SourceLocation::getFromRawEncoding(LocEncoding)); Args[1] = CGF.Builder.CreatePointerBitCastOrAddrSpaceCast( - Addr.emitRawPointer(CGF), CGF.VoidPtrTy); + Addr.getPointer(), CGF.VoidPtrTy); llvm::Value *AllocVal = getAllocatorVal(CGF, AllocExpr); Args[2] = AllocVal; CGF.EmitRuntimeCall(RTLFn, Args); @@ -11699,17 +11690,15 @@ void CGOpenMPRuntime::emitLastprivateConditionalUpdate(CodeGenFunction &CGF, LLIVTy, getName({UniqueDeclName, "iv"})); cast(LastIV)->setAlignment( IVLVal.getAlignment().getAsAlign()); - LValue LastIVLVal = - CGF.MakeNaturalAlignRawAddrLValue(LastIV, IVLVal.getType()); + LValue LastIVLVal = CGF.MakeNaturalAlignAddrLValue(LastIV, IVLVal.getType()); // Last value of the lastprivate conditional. // decltype(priv_a) last_a; llvm::GlobalVariable *Last = OMPBuilder.getOrCreateInternalVariable( CGF.ConvertTypeForMem(LVal.getType()), UniqueDeclName); - cast(Last)->setAlignment( - LVal.getAlignment().getAsAlign()); - LValue LastLVal = - CGF.MakeRawAddrLValue(Last, LVal.getType(), LVal.getAlignment()); + Last->setAlignment(LVal.getAlignment().getAsAlign()); + LValue LastLVal = CGF.MakeAddrLValue( + Address(Last, Last->getValueType(), LVal.getAlignment()), LVal.getType()); // Global loop counter. Required to handle inner parallel-for regions. // iv @@ -11882,8 +11871,9 @@ void CGOpenMPRuntime::emitLastprivateConditionalFinalUpdate( // The variable was not updated in the region - exit. if (!GV) return; - LValue LPLVal = CGF.MakeRawAddrLValue( - GV, PrivLVal.getType().getNonReferenceType(), PrivLVal.getAlignment()); + LValue LPLVal = CGF.MakeAddrLValue( + Address(GV, GV->getValueType(), PrivLVal.getAlignment()), + PrivLVal.getType().getNonReferenceType()); llvm::Value *Res = CGF.EmitLoadOfScalar(LPLVal, Loc); CGF.EmitStoreOfScalar(Res, PrivLVal); } diff --git a/clang/lib/CodeGen/CGOpenMPRuntime.h b/clang/lib/CodeGen/CGOpenMPRuntime.h index 522ae3d35d22..c3206427b143 100644 --- a/clang/lib/CodeGen/CGOpenMPRuntime.h +++ b/clang/lib/CodeGen/CGOpenMPRuntime.h @@ -1068,12 +1068,13 @@ public: /// \param Loc Location of the reference to threadprivate var. /// \return Address of the threadprivate variable for the current thread. virtual Address getAddrOfThreadPrivate(CodeGenFunction &CGF, - const VarDecl *VD, Address VDAddr, + const VarDecl *VD, + Address VDAddr, SourceLocation Loc); /// Returns the address of the variable marked as declare target with link /// clause OR as declare target with to clause and unified memory. - virtual ConstantAddress getAddrOfDeclareTargetVar(const VarDecl *VD); + virtual Address getAddrOfDeclareTargetVar(const VarDecl *VD); /// Emit a code for initialization of threadprivate variable. It emits /// a call to runtime library which adds initial value to the newly created diff --git a/clang/lib/CodeGen/CGOpenMPRuntimeGPU.cpp b/clang/lib/CodeGen/CGOpenMPRuntimeGPU.cpp index 5baac8f0e3e2..299ee1460b3d 100644 --- a/clang/lib/CodeGen/CGOpenMPRuntimeGPU.cpp +++ b/clang/lib/CodeGen/CGOpenMPRuntimeGPU.cpp @@ -1096,8 +1096,7 @@ void CGOpenMPRuntimeGPU::emitGenericVarsProlog(CodeGenFunction &CGF, llvm::PointerType *VarPtrTy = CGF.ConvertTypeForMem(VarTy)->getPointerTo(); llvm::Value *CastedVoidPtr = Bld.CreatePointerBitCastOrAddrSpaceCast( VoidPtr, VarPtrTy, VD->getName() + "_on_stack"); - LValue VarAddr = - CGF.MakeNaturalAlignPointeeRawAddrLValue(CastedVoidPtr, VarTy); + LValue VarAddr = CGF.MakeNaturalAlignAddrLValue(CastedVoidPtr, VarTy); Rec.second.PrivateAddr = VarAddr.getAddress(CGF); Rec.second.GlobalizedVal = VoidPtr; @@ -1207,8 +1206,8 @@ void CGOpenMPRuntimeGPU::emitTeamsCall(CodeGenFunction &CGF, bool IsBareKernel = D.getSingleClause(); - RawAddress ZeroAddr = CGF.CreateDefaultAlignTempAlloca(CGF.Int32Ty, - /*Name=*/".zero.addr"); + Address ZeroAddr = CGF.CreateDefaultAlignTempAlloca(CGF.Int32Ty, + /*Name=*/".zero.addr"); CGF.Builder.CreateStore(CGF.Builder.getInt32(/*C*/ 0), ZeroAddr); llvm::SmallVector OutlinedFnArgs; // We don't emit any thread id function call in bare kernel, but because the @@ -1216,7 +1215,7 @@ void CGOpenMPRuntimeGPU::emitTeamsCall(CodeGenFunction &CGF, if (IsBareKernel) OutlinedFnArgs.push_back(llvm::ConstantPointerNull::get(CGM.VoidPtrTy)); else - OutlinedFnArgs.push_back(emitThreadIDAddress(CGF, Loc).emitRawPointer(CGF)); + OutlinedFnArgs.push_back(emitThreadIDAddress(CGF, Loc).getPointer()); OutlinedFnArgs.push_back(ZeroAddr.getPointer()); OutlinedFnArgs.append(CapturedVars.begin(), CapturedVars.end()); emitOutlinedFunctionCall(CGF, Loc, OutlinedFn, OutlinedFnArgs); @@ -1290,7 +1289,7 @@ void CGOpenMPRuntimeGPU::emitParallelCall(CodeGenFunction &CGF, llvm::ConstantInt::get(CGF.Int32Ty, -1), FnPtr, ID, - Bld.CreateBitOrPointerCast(CapturedVarsAddrs.emitRawPointer(CGF), + Bld.CreateBitOrPointerCast(CapturedVarsAddrs.getPointer(), CGF.VoidPtrPtrTy), llvm::ConstantInt::get(CGM.SizeTy, CapturedVars.size())}; CGF.EmitRuntimeCall(OMPBuilder.getOrCreateRuntimeFunction( @@ -1504,18 +1503,17 @@ static void shuffleAndStore(CodeGenFunction &CGF, Address SrcAddr, CGF.EmitBlock(PreCondBB); llvm::PHINode *PhiSrc = Bld.CreatePHI(Ptr.getType(), /*NumReservedValues=*/2); - PhiSrc->addIncoming(Ptr.emitRawPointer(CGF), CurrentBB); + PhiSrc->addIncoming(Ptr.getPointer(), CurrentBB); llvm::PHINode *PhiDest = Bld.CreatePHI(ElemPtr.getType(), /*NumReservedValues=*/2); - PhiDest->addIncoming(ElemPtr.emitRawPointer(CGF), CurrentBB); + PhiDest->addIncoming(ElemPtr.getPointer(), CurrentBB); Ptr = Address(PhiSrc, Ptr.getElementType(), Ptr.getAlignment()); ElemPtr = Address(PhiDest, ElemPtr.getElementType(), ElemPtr.getAlignment()); - llvm::Value *PtrEndRaw = PtrEnd.emitRawPointer(CGF); - llvm::Value *PtrRaw = Ptr.emitRawPointer(CGF); llvm::Value *PtrDiff = Bld.CreatePtrDiff( - CGF.Int8Ty, PtrEndRaw, - Bld.CreatePointerBitCastOrAddrSpaceCast(PtrRaw, CGF.VoidPtrTy)); + CGF.Int8Ty, PtrEnd.getPointer(), + Bld.CreatePointerBitCastOrAddrSpaceCast(Ptr.getPointer(), + CGF.VoidPtrTy)); Bld.CreateCondBr(Bld.CreateICmpSGT(PtrDiff, Bld.getInt64(IntSize - 1)), ThenBB, ExitBB); CGF.EmitBlock(ThenBB); @@ -1530,8 +1528,8 @@ static void shuffleAndStore(CodeGenFunction &CGF, Address SrcAddr, TBAAAccessInfo()); Address LocalPtr = Bld.CreateConstGEP(Ptr, 1); Address LocalElemPtr = Bld.CreateConstGEP(ElemPtr, 1); - PhiSrc->addIncoming(LocalPtr.emitRawPointer(CGF), ThenBB); - PhiDest->addIncoming(LocalElemPtr.emitRawPointer(CGF), ThenBB); + PhiSrc->addIncoming(LocalPtr.getPointer(), ThenBB); + PhiDest->addIncoming(LocalElemPtr.getPointer(), ThenBB); CGF.EmitBranch(PreCondBB); CGF.EmitBlock(ExitBB); } else { @@ -1678,10 +1676,10 @@ static void emitReductionListCopy( // scope and that of functions it invokes (i.e., reduce_function). // RemoteReduceData[i] = (void*)&RemoteElem if (UpdateDestListPtr) { - CGF.EmitStoreOfScalar( - Bld.CreatePointerBitCastOrAddrSpaceCast( - DestElementAddr.emitRawPointer(CGF), CGF.VoidPtrTy), - DestElementPtrAddr, /*Volatile=*/false, C.VoidPtrTy); + CGF.EmitStoreOfScalar(Bld.CreatePointerBitCastOrAddrSpaceCast( + DestElementAddr.getPointer(), CGF.VoidPtrTy), + DestElementPtrAddr, /*Volatile=*/false, + C.VoidPtrTy); } ++Idx; @@ -1832,7 +1830,7 @@ static llvm::Value *emitInterWarpCopyFunction(CodeGenModule &CGM, // elemptr = ((CopyType*)(elemptrptr)) + I Address ElemPtr(ElemPtrPtr, CopyType, Align); if (NumIters > 1) - ElemPtr = Bld.CreateGEP(CGF, ElemPtr, Cnt); + ElemPtr = Bld.CreateGEP(ElemPtr, Cnt); // Get pointer to location in transfer medium. // MediumPtr = &medium[warp_id] @@ -1896,7 +1894,7 @@ static llvm::Value *emitInterWarpCopyFunction(CodeGenModule &CGM, TargetElemPtrPtr, /*Volatile=*/false, C.VoidPtrTy, Loc); Address TargetElemPtr(TargetElemPtrVal, CopyType, Align); if (NumIters > 1) - TargetElemPtr = Bld.CreateGEP(CGF, TargetElemPtr, Cnt); + TargetElemPtr = Bld.CreateGEP(TargetElemPtr, Cnt); // *TargetElemPtr = SrcMediumVal; llvm::Value *SrcMediumValue = @@ -2107,9 +2105,9 @@ static llvm::Function *emitShuffleAndReduceFunction( CGF.EmitBlock(ThenBB); // reduce_function(LocalReduceList, RemoteReduceList) llvm::Value *LocalReduceListPtr = Bld.CreatePointerBitCastOrAddrSpaceCast( - LocalReduceList.emitRawPointer(CGF), CGF.VoidPtrTy); + LocalReduceList.getPointer(), CGF.VoidPtrTy); llvm::Value *RemoteReduceListPtr = Bld.CreatePointerBitCastOrAddrSpaceCast( - RemoteReduceList.emitRawPointer(CGF), CGF.VoidPtrTy); + RemoteReduceList.getPointer(), CGF.VoidPtrTy); CGM.getOpenMPRuntime().emitOutlinedFunctionCall( CGF, Loc, ReduceFn, {LocalReduceListPtr, RemoteReduceListPtr}); Bld.CreateBr(MergeBB); @@ -2220,9 +2218,9 @@ static llvm::Value *emitListToGlobalCopyFunction( llvm::Value *BufferPtr = Bld.CreateInBoundsGEP(LLVMReductionsBufferTy, BufferArrPtr, Idxs); LValue GlobLVal = CGF.EmitLValueForField( - CGF.MakeNaturalAlignRawAddrLValue(BufferPtr, StaticTy), FD); + CGF.MakeNaturalAlignAddrLValue(BufferPtr, StaticTy), FD); Address GlobAddr = GlobLVal.getAddress(CGF); - GlobLVal.setAddress(Address(GlobAddr.emitRawPointer(CGF), + GlobLVal.setAddress(Address(GlobAddr.getPointer(), CGF.ConvertTypeForMem(Private->getType()), GlobAddr.getAlignment())); switch (CGF.getEvaluationKind(Private->getType())) { @@ -2306,7 +2304,7 @@ static llvm::Value *emitListToGlobalReduceFunction( // 1. Build a list of reduction variables. // void *RedList[] = {[0], ..., [-1]}; - RawAddress ReductionList = + Address ReductionList = CGF.CreateMemTemp(ReductionArrayTy, ".omp.reduction.red_list"); auto IPriv = Privates.begin(); llvm::Value *Idxs[] = {CGF.EmitLoadOfScalar(CGF.GetAddrOfLocalVar(&IdxArg), @@ -2321,10 +2319,10 @@ static llvm::Value *emitListToGlobalReduceFunction( llvm::Value *BufferPtr = Bld.CreateInBoundsGEP(LLVMReductionsBufferTy, BufferArrPtr, Idxs); LValue GlobLVal = CGF.EmitLValueForField( - CGF.MakeNaturalAlignRawAddrLValue(BufferPtr, StaticTy), FD); + CGF.MakeNaturalAlignAddrLValue(BufferPtr, StaticTy), FD); Address GlobAddr = GlobLVal.getAddress(CGF); - CGF.EmitStoreOfScalar(GlobAddr.emitRawPointer(CGF), Elem, - /*Volatile=*/false, C.VoidPtrTy); + CGF.EmitStoreOfScalar(GlobAddr.getPointer(), Elem, /*Volatile=*/false, + C.VoidPtrTy); if ((*IPriv)->getType()->isVariablyModifiedType()) { // Store array size. ++Idx; @@ -2427,9 +2425,9 @@ static llvm::Value *emitGlobalToListCopyFunction( llvm::Value *BufferPtr = Bld.CreateInBoundsGEP(LLVMReductionsBufferTy, BufferArrPtr, Idxs); LValue GlobLVal = CGF.EmitLValueForField( - CGF.MakeNaturalAlignRawAddrLValue(BufferPtr, StaticTy), FD); + CGF.MakeNaturalAlignAddrLValue(BufferPtr, StaticTy), FD); Address GlobAddr = GlobLVal.getAddress(CGF); - GlobLVal.setAddress(Address(GlobAddr.emitRawPointer(CGF), + GlobLVal.setAddress(Address(GlobAddr.getPointer(), CGF.ConvertTypeForMem(Private->getType()), GlobAddr.getAlignment())); switch (CGF.getEvaluationKind(Private->getType())) { @@ -2528,10 +2526,10 @@ static llvm::Value *emitGlobalToListReduceFunction( llvm::Value *BufferPtr = Bld.CreateInBoundsGEP(LLVMReductionsBufferTy, BufferArrPtr, Idxs); LValue GlobLVal = CGF.EmitLValueForField( - CGF.MakeNaturalAlignRawAddrLValue(BufferPtr, StaticTy), FD); + CGF.MakeNaturalAlignAddrLValue(BufferPtr, StaticTy), FD); Address GlobAddr = GlobLVal.getAddress(CGF); - CGF.EmitStoreOfScalar(GlobAddr.emitRawPointer(CGF), Elem, - /*Volatile=*/false, C.VoidPtrTy); + CGF.EmitStoreOfScalar(GlobAddr.getPointer(), Elem, /*Volatile=*/false, + C.VoidPtrTy); if ((*IPriv)->getType()->isVariablyModifiedType()) { // Store array size. ++Idx; @@ -2547,7 +2545,7 @@ static llvm::Value *emitGlobalToListReduceFunction( } // Call reduce_function(ReduceList, GlobalReduceList) - llvm::Value *GlobalReduceList = ReductionList.emitRawPointer(CGF); + llvm::Value *GlobalReduceList = ReductionList.getPointer(); Address AddrReduceListArg = CGF.GetAddrOfLocalVar(&ReduceListArg); llvm::Value *ReducedPtr = CGF.EmitLoadOfScalar( AddrReduceListArg, /*Volatile=*/false, C.VoidPtrTy, Loc); @@ -2878,7 +2876,7 @@ void CGOpenMPRuntimeGPU::emitReduction( } llvm::Value *RL = CGF.Builder.CreatePointerBitCastOrAddrSpaceCast( - ReductionList.emitRawPointer(CGF), CGF.VoidPtrTy); + ReductionList.getPointer(), CGF.VoidPtrTy); llvm::Function *ReductionFn = emitReductionFunction( CGF.CurFn->getName(), Loc, CGF.ConvertTypeForMem(ReductionArrayTy), Privates, LHSExprs, RHSExprs, ReductionOps); @@ -3108,15 +3106,15 @@ llvm::Function *CGOpenMPRuntimeGPU::createParallelDataSharingWrapper( // Get the array of arguments. SmallVector Args; - Args.emplace_back(CGF.GetAddrOfLocalVar(&WrapperArg).emitRawPointer(CGF)); - Args.emplace_back(ZeroAddr.emitRawPointer(CGF)); + Args.emplace_back(CGF.GetAddrOfLocalVar(&WrapperArg).getPointer()); + Args.emplace_back(ZeroAddr.getPointer()); CGBuilderTy &Bld = CGF.Builder; auto CI = CS.capture_begin(); // Use global memory for data sharing. // Handle passing of global args to workers. - RawAddress GlobalArgs = + Address GlobalArgs = CGF.CreateDefaultAlignTempAlloca(CGF.VoidPtrPtrTy, "global_args"); llvm::Value *GlobalArgsPtr = GlobalArgs.getPointer(); llvm::Value *DataSharingArgs[] = {GlobalArgsPtr}; @@ -3402,7 +3400,7 @@ void CGOpenMPRuntimeGPU::adjustTargetSpecificDataForLambdas( VDAddr = CGF.EmitLoadOfReferenceLValue(VDAddr, VD->getType().getCanonicalType()) .getAddress(CGF); - CGF.EmitStoreOfScalar(VDAddr.emitRawPointer(CGF), VarLVal); + CGF.EmitStoreOfScalar(VDAddr.getPointer(), VarLVal); } } } diff --git a/clang/lib/CodeGen/CGStmt.cpp b/clang/lib/CodeGen/CGStmt.cpp index 576fe2f7a2d4..cb5a004e4f4a 100644 --- a/clang/lib/CodeGen/CGStmt.cpp +++ b/clang/lib/CodeGen/CGStmt.cpp @@ -2294,7 +2294,7 @@ std::pair CodeGenFunction::EmitAsmInputLValue( Address Addr = InputValue.getAddress(*this); ConstraintStr += '*'; - return {InputValue.getPointer(*this), Addr.getElementType()}; + return {Addr.getPointer(), Addr.getElementType()}; } std::pair @@ -2701,7 +2701,7 @@ void CodeGenFunction::EmitAsmStmt(const AsmStmt &S) { ArgTypes.push_back(DestAddr.getType()); ArgElemTypes.push_back(DestAddr.getElementType()); - Args.push_back(DestAddr.emitRawPointer(*this)); + Args.push_back(DestAddr.getPointer()); Constraints += "=*"; Constraints += OutputConstraint; ReadOnly = ReadNone = false; @@ -3076,8 +3076,8 @@ CodeGenFunction::GenerateCapturedStmtFunction(const CapturedStmt &S) { CapturedStmtInfo->setContextValue(Builder.CreateLoad(DeclPtr)); // Initialize variable-length arrays. - LValue Base = MakeNaturalAlignRawAddrLValue( - CapturedStmtInfo->getContextValue(), Ctx.getTagDeclType(RD)); + LValue Base = MakeNaturalAlignAddrLValue(CapturedStmtInfo->getContextValue(), + Ctx.getTagDeclType(RD)); for (auto *FD : RD->fields()) { if (FD->hasCapturedVLAType()) { auto *ExprArg = diff --git a/clang/lib/CodeGen/CGStmtOpenMP.cpp b/clang/lib/CodeGen/CGStmtOpenMP.cpp index e6d504bcdeca..f37ac549d10a 100644 --- a/clang/lib/CodeGen/CGStmtOpenMP.cpp +++ b/clang/lib/CodeGen/CGStmtOpenMP.cpp @@ -350,8 +350,7 @@ void CodeGenFunction::GenerateOpenMPCapturedVars( LValue DstLV = MakeAddrLValue(DstAddr, Ctx.getUIntPtrType()); llvm::Value *SrcAddrVal = EmitScalarConversion( - DstAddr.emitRawPointer(*this), - Ctx.getPointerType(Ctx.getUIntPtrType()), + DstAddr.getPointer(), Ctx.getPointerType(Ctx.getUIntPtrType()), Ctx.getPointerType(CurField->getType()), CurCap->getLocation()); LValue SrcLV = MakeNaturalAlignAddrLValue(SrcAddrVal, CurField->getType()); @@ -365,8 +364,7 @@ void CodeGenFunction::GenerateOpenMPCapturedVars( CapturedVars.push_back(CV); } else { assert(CurCap->capturesVariable() && "Expected capture by reference."); - CapturedVars.push_back( - EmitLValue(*I).getAddress(*this).emitRawPointer(*this)); + CapturedVars.push_back(EmitLValue(*I).getAddress(*this).getPointer()); } } } @@ -377,9 +375,8 @@ static Address castValueFromUintptr(CodeGenFunction &CGF, SourceLocation Loc, ASTContext &Ctx = CGF.getContext(); llvm::Value *CastedPtr = CGF.EmitScalarConversion( - AddrLV.getAddress(CGF).emitRawPointer(CGF), Ctx.getUIntPtrType(), + AddrLV.getAddress(CGF).getPointer(), Ctx.getUIntPtrType(), Ctx.getPointerType(DstType), Loc); - // FIXME: should the pointee type (DstType) be passed? Address TmpAddr = CGF.MakeNaturalAlignAddrLValue(CastedPtr, DstType).getAddress(CGF); return TmpAddr; @@ -705,8 +702,8 @@ void CodeGenFunction::EmitOMPAggregateAssign( llvm::Value *NumElements = emitArrayLength(ArrayTy, ElementTy, DestAddr); SrcAddr = SrcAddr.withElementType(DestAddr.getElementType()); - llvm::Value *SrcBegin = SrcAddr.emitRawPointer(*this); - llvm::Value *DestBegin = DestAddr.emitRawPointer(*this); + llvm::Value *SrcBegin = SrcAddr.getPointer(); + llvm::Value *DestBegin = DestAddr.getPointer(); // Cast from pointer to array type to pointer to single element. llvm::Value *DestEnd = Builder.CreateInBoundsGEP(DestAddr.getElementType(), DestBegin, NumElements); @@ -1010,10 +1007,10 @@ bool CodeGenFunction::EmitOMPCopyinClause(const OMPExecutableDirective &D) { CopyBegin = createBasicBlock("copyin.not.master"); CopyEnd = createBasicBlock("copyin.not.master.end"); // TODO: Avoid ptrtoint conversion. - auto *MasterAddrInt = Builder.CreatePtrToInt( - MasterAddr.emitRawPointer(*this), CGM.IntPtrTy); - auto *PrivateAddrInt = Builder.CreatePtrToInt( - PrivateAddr.emitRawPointer(*this), CGM.IntPtrTy); + auto *MasterAddrInt = + Builder.CreatePtrToInt(MasterAddr.getPointer(), CGM.IntPtrTy); + auto *PrivateAddrInt = + Builder.CreatePtrToInt(PrivateAddr.getPointer(), CGM.IntPtrTy); Builder.CreateCondBr( Builder.CreateICmpNE(MasterAddrInt, PrivateAddrInt), CopyBegin, CopyEnd); @@ -1669,7 +1666,7 @@ Address CodeGenFunction::OMPBuilderCBHelpers::getAddrOfThreadPrivate( llvm::Type *VarTy = VDAddr.getElementType(); llvm::Value *Data = - CGF.Builder.CreatePointerCast(VDAddr.emitRawPointer(CGF), CGM.Int8PtrTy); + CGF.Builder.CreatePointerCast(VDAddr.getPointer(), CGM.Int8PtrTy); llvm::ConstantInt *Size = CGM.getSize(CGM.GetTargetTypeStoreSize(VarTy)); std::string Suffix = getNameWithSeparators({"cache", ""}); llvm::Twine CacheName = Twine(CGM.getMangledName(VD)).concat(Suffix); @@ -2048,7 +2045,7 @@ void CodeGenFunction::EmitOMPCanonicalLoop(const OMPCanonicalLoop *S) { ->getParam(0) ->getType() .getNonReferenceType(); - RawAddress CountAddr = CreateMemTemp(LogicalTy, ".count.addr"); + Address CountAddr = CreateMemTemp(LogicalTy, ".count.addr"); emitCapturedStmtCall(*this, DistanceClosure, {CountAddr.getPointer()}); llvm::Value *DistVal = Builder.CreateLoad(CountAddr, ".count"); @@ -2064,7 +2061,7 @@ void CodeGenFunction::EmitOMPCanonicalLoop(const OMPCanonicalLoop *S) { LValue LCVal = EmitLValue(LoopVarRef); Address LoopVarAddress = LCVal.getAddress(*this); emitCapturedStmtCall(*this, LoopVarClosure, - {LoopVarAddress.emitRawPointer(*this), IndVar}); + {LoopVarAddress.getPointer(), IndVar}); RunCleanupsScope BodyScope(*this); EmitStmt(BodyStmt); @@ -4798,7 +4795,7 @@ void CodeGenFunction::EmitOMPTaskBasedDirective( ParamTypes.push_back(PrivatesPtr->getType()); for (const Expr *E : Data.PrivateVars) { const auto *VD = cast(cast(E)->getDecl()); - RawAddress PrivatePtr = CGF.CreateMemTemp( + Address PrivatePtr = CGF.CreateMemTemp( CGF.getContext().getPointerType(E->getType()), ".priv.ptr.addr"); PrivatePtrs.emplace_back(VD, PrivatePtr); CallArgs.push_back(PrivatePtr.getPointer()); @@ -4806,7 +4803,7 @@ void CodeGenFunction::EmitOMPTaskBasedDirective( } for (const Expr *E : Data.FirstprivateVars) { const auto *VD = cast(cast(E)->getDecl()); - RawAddress PrivatePtr = + Address PrivatePtr = CGF.CreateMemTemp(CGF.getContext().getPointerType(E->getType()), ".firstpriv.ptr.addr"); PrivatePtrs.emplace_back(VD, PrivatePtr); @@ -4816,7 +4813,7 @@ void CodeGenFunction::EmitOMPTaskBasedDirective( } for (const Expr *E : Data.LastprivateVars) { const auto *VD = cast(cast(E)->getDecl()); - RawAddress PrivatePtr = + Address PrivatePtr = CGF.CreateMemTemp(CGF.getContext().getPointerType(E->getType()), ".lastpriv.ptr.addr"); PrivatePtrs.emplace_back(VD, PrivatePtr); @@ -4829,7 +4826,7 @@ void CodeGenFunction::EmitOMPTaskBasedDirective( Ty = CGF.getContext().getPointerType(Ty); if (isAllocatableDecl(VD)) Ty = CGF.getContext().getPointerType(Ty); - RawAddress PrivatePtr = CGF.CreateMemTemp( + Address PrivatePtr = CGF.CreateMemTemp( CGF.getContext().getPointerType(Ty), ".local.ptr.addr"); auto Result = UntiedLocalVars.insert( std::make_pair(VD, std::make_pair(PrivatePtr, Address::invalid()))); @@ -4862,7 +4859,7 @@ void CodeGenFunction::EmitOMPTaskBasedDirective( if (auto *DI = CGF.getDebugInfo()) if (CGF.CGM.getCodeGenOpts().hasReducedDebugInfo()) (void)DI->EmitDeclareOfAutoVariable( - Pair.first, Pair.second.getBasePointer(), CGF.Builder, + Pair.first, Pair.second.getPointer(), CGF.Builder, /*UsePointerValue*/ true); } // Adjust mapping for internal locals by mapping actual memory instead of @@ -4915,14 +4912,14 @@ void CodeGenFunction::EmitOMPTaskBasedDirective( RedCG, Cnt); Address Replacement = CGF.CGM.getOpenMPRuntime().getTaskReductionItem( CGF, S.getBeginLoc(), ReductionsPtr, RedCG.getSharedLValue(Cnt)); - Replacement = Address( - CGF.EmitScalarConversion(Replacement.emitRawPointer(CGF), - CGF.getContext().VoidPtrTy, - CGF.getContext().getPointerType( - Data.ReductionCopies[Cnt]->getType()), - Data.ReductionCopies[Cnt]->getExprLoc()), - CGF.ConvertTypeForMem(Data.ReductionCopies[Cnt]->getType()), - Replacement.getAlignment()); + Replacement = + Address(CGF.EmitScalarConversion( + Replacement.getPointer(), CGF.getContext().VoidPtrTy, + CGF.getContext().getPointerType( + Data.ReductionCopies[Cnt]->getType()), + Data.ReductionCopies[Cnt]->getExprLoc()), + CGF.ConvertTypeForMem(Data.ReductionCopies[Cnt]->getType()), + Replacement.getAlignment()); Replacement = RedCG.adjustPrivateAddress(CGF, Cnt, Replacement); Scope.addPrivate(RedCG.getBaseDecl(Cnt), Replacement); } @@ -4973,7 +4970,7 @@ void CodeGenFunction::EmitOMPTaskBasedDirective( CGF, S.getBeginLoc(), ReductionsPtr, RedCG.getSharedLValue(Cnt)); Replacement = Address( CGF.EmitScalarConversion( - Replacement.emitRawPointer(CGF), CGF.getContext().VoidPtrTy, + Replacement.getPointer(), CGF.getContext().VoidPtrTy, CGF.getContext().getPointerType(InRedPrivs[Cnt]->getType()), InRedPrivs[Cnt]->getExprLoc()), CGF.ConvertTypeForMem(InRedPrivs[Cnt]->getType()), @@ -5092,7 +5089,7 @@ void CodeGenFunction::EmitOMPTargetTaskBasedDirective( // If there is no user-defined mapper, the mapper array will be nullptr. In // this case, we don't need to privatize it. if (!isa_and_nonnull( - InputInfo.MappersArray.emitRawPointer(*this))) { + InputInfo.MappersArray.getPointer())) { MVD = createImplicitFirstprivateForType( getContext(), Data, BaseAndPointerAndMapperType, CD, S.getBeginLoc()); TargetScope.addPrivate(MVD, InputInfo.MappersArray); @@ -5118,7 +5115,7 @@ void CodeGenFunction::EmitOMPTargetTaskBasedDirective( ParamTypes.push_back(PrivatesPtr->getType()); for (const Expr *E : Data.FirstprivateVars) { const auto *VD = cast(cast(E)->getDecl()); - RawAddress PrivatePtr = + Address PrivatePtr = CGF.CreateMemTemp(CGF.getContext().getPointerType(E->getType()), ".firstpriv.ptr.addr"); PrivatePtrs.emplace_back(VD, PrivatePtr); @@ -5197,14 +5194,14 @@ void CodeGenFunction::processInReduction(const OMPExecutableDirective &S, RedCG, Cnt); Address Replacement = CGF.CGM.getOpenMPRuntime().getTaskReductionItem( CGF, S.getBeginLoc(), ReductionsPtr, RedCG.getSharedLValue(Cnt)); - Replacement = Address( - CGF.EmitScalarConversion(Replacement.emitRawPointer(CGF), - CGF.getContext().VoidPtrTy, - CGF.getContext().getPointerType( - Data.ReductionCopies[Cnt]->getType()), - Data.ReductionCopies[Cnt]->getExprLoc()), - CGF.ConvertTypeForMem(Data.ReductionCopies[Cnt]->getType()), - Replacement.getAlignment()); + Replacement = + Address(CGF.EmitScalarConversion( + Replacement.getPointer(), CGF.getContext().VoidPtrTy, + CGF.getContext().getPointerType( + Data.ReductionCopies[Cnt]->getType()), + Data.ReductionCopies[Cnt]->getExprLoc()), + CGF.ConvertTypeForMem(Data.ReductionCopies[Cnt]->getType()), + Replacement.getAlignment()); Replacement = RedCG.adjustPrivateAddress(CGF, Cnt, Replacement); Scope.addPrivate(RedCG.getBaseDecl(Cnt), Replacement); } @@ -5250,7 +5247,7 @@ void CodeGenFunction::processInReduction(const OMPExecutableDirective &S, CGF, S.getBeginLoc(), ReductionsPtr, RedCG.getSharedLValue(Cnt)); Replacement = Address( CGF.EmitScalarConversion( - Replacement.emitRawPointer(CGF), CGF.getContext().VoidPtrTy, + Replacement.getPointer(), CGF.getContext().VoidPtrTy, CGF.getContext().getPointerType(InRedPrivs[Cnt]->getType()), InRedPrivs[Cnt]->getExprLoc()), CGF.ConvertTypeForMem(InRedPrivs[Cnt]->getType()), @@ -5397,7 +5394,7 @@ void CodeGenFunction::EmitOMPDepobjDirective(const OMPDepobjDirective &S) { Dependencies.DepExprs.append(DC->varlist_begin(), DC->varlist_end()); Address DepAddr = CGM.getOpenMPRuntime().emitDepobjDependClause( *this, Dependencies, DC->getBeginLoc()); - EmitStoreOfScalar(DepAddr.emitRawPointer(*this), DOLVal); + EmitStoreOfScalar(DepAddr.getPointer(), DOLVal); return; } if (const auto *DC = S.getSingleClause()) { @@ -6474,21 +6471,21 @@ static void emitOMPAtomicCompareExpr( D->getType()->hasSignedIntegerRepresentation()); llvm::OpenMPIRBuilder::AtomicOpValue XOpVal{ - XAddr.emitRawPointer(CGF), XAddr.getElementType(), + XAddr.getPointer(), XAddr.getElementType(), X->getType()->hasSignedIntegerRepresentation(), X->getType().isVolatileQualified()}; llvm::OpenMPIRBuilder::AtomicOpValue VOpVal, ROpVal; if (V) { LValue LV = CGF.EmitLValue(V); Address Addr = LV.getAddress(CGF); - VOpVal = {Addr.emitRawPointer(CGF), Addr.getElementType(), + VOpVal = {Addr.getPointer(), Addr.getElementType(), V->getType()->hasSignedIntegerRepresentation(), V->getType().isVolatileQualified()}; } if (R) { LValue LV = CGF.EmitLValue(R); Address Addr = LV.getAddress(CGF); - ROpVal = {Addr.emitRawPointer(CGF), Addr.getElementType(), + ROpVal = {Addr.getPointer(), Addr.getElementType(), R->getType()->hasSignedIntegerRepresentation(), R->getType().isVolatileQualified()}; } @@ -7032,7 +7029,7 @@ void CodeGenFunction::EmitOMPInteropDirective(const OMPInteropDirective &S) { std::tie(NumDependences, DependenciesArray) = CGM.getOpenMPRuntime().emitDependClause(*this, Data.Dependences, S.getBeginLoc()); - DependenceList = DependenciesArray.emitRawPointer(*this); + DependenceList = DependenciesArray.getPointer(); } Data.HasNowaitClause = S.hasClausesOfKind(); diff --git a/clang/lib/CodeGen/CGVTables.cpp b/clang/lib/CodeGen/CGVTables.cpp index 862369ae009f..8dee3f74b44b 100644 --- a/clang/lib/CodeGen/CGVTables.cpp +++ b/clang/lib/CodeGen/CGVTables.cpp @@ -201,13 +201,14 @@ CodeGenFunction::GenerateVarArgsThunk(llvm::Function *Fn, // Find the first store of "this", which will be to the alloca associated // with "this". - Address ThisPtr = makeNaturalAddressForPointer( - &*AI, MD->getFunctionObjectParameterType(), - CGM.getClassPointerAlignment(MD->getParent())); + Address ThisPtr = + Address(&*AI, ConvertTypeForMem(MD->getFunctionObjectParameterType()), + CGM.getClassPointerAlignment(MD->getParent())); llvm::BasicBlock *EntryBB = &Fn->front(); llvm::BasicBlock::iterator ThisStore = llvm::find_if(*EntryBB, [&](llvm::Instruction &I) { - return isa(I) && I.getOperand(0) == &*AI; + return isa(I) && + I.getOperand(0) == ThisPtr.getPointer(); }); assert(ThisStore != EntryBB->end() && "Store of this should be in entry block?"); diff --git a/clang/lib/CodeGen/CGValue.h b/clang/lib/CodeGen/CGValue.h index cc9ad10ae596..1e6f67250583 100644 --- a/clang/lib/CodeGen/CGValue.h +++ b/clang/lib/CodeGen/CGValue.h @@ -14,13 +14,12 @@ #ifndef LLVM_CLANG_LIB_CODEGEN_CGVALUE_H #define LLVM_CLANG_LIB_CODEGEN_CGVALUE_H -#include "Address.h" -#include "CodeGenTBAA.h" -#include "EHScopeStack.h" #include "clang/AST/ASTContext.h" #include "clang/AST/Type.h" -#include "llvm/IR/Type.h" #include "llvm/IR/Value.h" +#include "llvm/IR/Type.h" +#include "Address.h" +#include "CodeGenTBAA.h" namespace llvm { class Constant; @@ -29,64 +28,57 @@ namespace llvm { namespace clang { namespace CodeGen { -class AggValueSlot; -class CGBuilderTy; -class CodeGenFunction; -struct CGBitFieldInfo; + class AggValueSlot; + class CodeGenFunction; + struct CGBitFieldInfo; /// RValue - This trivial value class is used to represent the result of an /// expression that is evaluated. It can be one of three things: either a /// simple LLVM SSA value, a pair of SSA values for complex numbers, or the /// address of an aggregate value in memory. class RValue { - friend struct DominatingValue; + enum Flavor { Scalar, Complex, Aggregate }; - enum FlavorEnum { Scalar, Complex, Aggregate }; + // The shift to make to an aggregate's alignment to make it look + // like a pointer. + enum { AggAlignShift = 4 }; - union { - // Stores first and second value. - struct { - llvm::Value *first; - llvm::Value *second; - } Vals; - - // Stores aggregate address. - Address AggregateAddr; - }; - - unsigned IsVolatile : 1; - unsigned Flavor : 2; + // Stores first value and flavor. + llvm::PointerIntPair V1; + // Stores second value and volatility. + llvm::PointerIntPair V2; + // Stores element type for aggregate values. + llvm::Type *ElementType; public: - RValue() : Vals{nullptr, nullptr}, Flavor(Scalar) {} - - bool isScalar() const { return Flavor == Scalar; } - bool isComplex() const { return Flavor == Complex; } - bool isAggregate() const { return Flavor == Aggregate; } + bool isScalar() const { return V1.getInt() == Scalar; } + bool isComplex() const { return V1.getInt() == Complex; } + bool isAggregate() const { return V1.getInt() == Aggregate; } - bool isVolatileQualified() const { return IsVolatile; } + bool isVolatileQualified() const { return V2.getInt(); } /// getScalarVal() - Return the Value* of this scalar value. llvm::Value *getScalarVal() const { assert(isScalar() && "Not a scalar!"); - return Vals.first; + return V1.getPointer(); } /// getComplexVal - Return the real/imag components of this complex value. /// std::pair getComplexVal() const { - return std::make_pair(Vals.first, Vals.second); + return std::make_pair(V1.getPointer(), V2.getPointer()); } /// getAggregateAddr() - Return the Value* of the address of the aggregate. Address getAggregateAddress() const { assert(isAggregate() && "Not an aggregate!"); - return AggregateAddr; + auto align = reinterpret_cast(V2.getPointer()) >> AggAlignShift; + return Address( + V1.getPointer(), ElementType, CharUnits::fromQuantity(align)); } - - llvm::Value *getAggregatePointer(QualType PointeeType, - CodeGenFunction &CGF) const { - return getAggregateAddress().getBasePointer(); + llvm::Value *getAggregatePointer() const { + assert(isAggregate() && "Not an aggregate!"); + return V1.getPointer(); } static RValue getIgnored() { @@ -96,19 +88,17 @@ public: static RValue get(llvm::Value *V) { RValue ER; - ER.Vals.first = V; - ER.Flavor = Scalar; - ER.IsVolatile = false; + ER.V1.setPointer(V); + ER.V1.setInt(Scalar); + ER.V2.setInt(false); return ER; } - static RValue get(Address Addr, CodeGenFunction &CGF) { - return RValue::get(Addr.emitRawPointer(CGF)); - } static RValue getComplex(llvm::Value *V1, llvm::Value *V2) { RValue ER; - ER.Vals = {V1, V2}; - ER.Flavor = Complex; - ER.IsVolatile = false; + ER.V1.setPointer(V1); + ER.V2.setPointer(V2); + ER.V1.setInt(Complex); + ER.V2.setInt(false); return ER; } static RValue getComplex(const std::pair &C) { @@ -117,15 +107,15 @@ public: // FIXME: Aggregate rvalues need to retain information about whether they are // volatile or not. Remove default to find all places that probably get this // wrong. - - /// Convert an Address to an RValue. If the Address is not - /// signed, create an RValue using the unsigned address. Otherwise, resign the - /// address using the provided type. static RValue getAggregate(Address addr, bool isVolatile = false) { RValue ER; - ER.AggregateAddr = addr; - ER.Flavor = Aggregate; - ER.IsVolatile = isVolatile; + ER.V1.setPointer(addr.getPointer()); + ER.V1.setInt(Aggregate); + ER.ElementType = addr.getElementType(); + + auto align = static_cast(addr.getAlignment().getQuantity()); + ER.V2.setPointer(reinterpret_cast(align << AggAlignShift)); + ER.V2.setInt(isVolatile); return ER; } }; @@ -188,10 +178,8 @@ class LValue { MatrixElt // This is a matrix element, use getVector* } LVType; - union { - Address Addr = Address::invalid(); - llvm::Value *V; - }; + llvm::Value *V; + llvm::Type *ElementType; union { // Index into a vector subscript: V[i] @@ -209,6 +197,10 @@ class LValue { // 'const' is unused here Qualifiers Quals; + // The alignment to use when accessing this lvalue. (For vector elements, + // this is the alignment of the whole vector.) + unsigned Alignment; + // objective-c's ivar bool Ivar:1; @@ -242,19 +234,23 @@ class LValue { Expr *BaseIvarExp; private: - void Initialize(QualType Type, Qualifiers Quals, Address Addr, + void Initialize(QualType Type, Qualifiers Quals, CharUnits Alignment, LValueBaseInfo BaseInfo, TBAAAccessInfo TBAAInfo) { + assert((!Alignment.isZero() || Type->isIncompleteType()) && + "initializing l-value with zero alignment!"); + if (isGlobalReg()) + assert(ElementType == nullptr && "Global reg does not store elem type"); + else + assert(ElementType != nullptr && "Must have elem type"); + this->Type = Type; this->Quals = Quals; const unsigned MaxAlign = 1U << 31; - CharUnits Alignment = Addr.getAlignment(); - assert((isGlobalReg() || !Alignment.isZero() || Type->isIncompleteType()) && - "initializing l-value with zero alignment!"); - if (Alignment.getQuantity() > MaxAlign) { - assert(false && "Alignment exceeds allowed max!"); - Alignment = CharUnits::fromQuantity(MaxAlign); - } - this->Addr = Addr; + this->Alignment = Alignment.getQuantity() <= MaxAlign + ? Alignment.getQuantity() + : MaxAlign; + assert(this->Alignment == Alignment.getQuantity() && + "Alignment exceeds allowed max!"); this->BaseInfo = BaseInfo; this->TBAAInfo = TBAAInfo; @@ -263,20 +259,9 @@ private: this->ImpreciseLifetime = false; this->Nontemporal = false; this->ThreadLocalRef = false; - this->IsKnownNonNull = false; this->BaseIvarExp = nullptr; } - void initializeSimpleLValue(Address Addr, QualType Type, - LValueBaseInfo BaseInfo, TBAAAccessInfo TBAAInfo, - ASTContext &Context) { - Qualifiers QS = Type.getQualifiers(); - QS.setObjCGCAttr(Context.getObjCGCAttrKind(Type)); - LVType = Simple; - Initialize(Type, QS, Addr, BaseInfo, TBAAInfo); - assert(Addr.getBasePointer()->getType()->isPointerTy()); - } - public: bool isSimple() const { return LVType == Simple; } bool isVectorElt() const { return LVType == VectorElt; } @@ -343,8 +328,8 @@ public: LangAS getAddressSpace() const { return Quals.getAddressSpace(); } - CharUnits getAlignment() const { return Addr.getAlignment(); } - void setAlignment(CharUnits A) { Addr.setAlignment(A); } + CharUnits getAlignment() const { return CharUnits::fromQuantity(Alignment); } + void setAlignment(CharUnits A) { Alignment = A.getQuantity(); } LValueBaseInfo getBaseInfo() const { return BaseInfo; } void setBaseInfo(LValueBaseInfo Info) { BaseInfo = Info; } @@ -360,32 +345,28 @@ public: // simple lvalue llvm::Value *getPointer(CodeGenFunction &CGF) const { assert(isSimple()); - return Addr.getBasePointer(); + return V; } - llvm::Value *emitRawPointer(CodeGenFunction &CGF) const { - assert(isSimple()); - return Addr.isValid() ? Addr.emitRawPointer(CGF) : nullptr; - } - Address getAddress(CodeGenFunction &CGF) const { - // FIXME: remove parameter. - return Addr; + return Address(getPointer(CGF), ElementType, getAlignment(), + isKnownNonNull()); + } + void setAddress(Address address) { + assert(isSimple()); + V = address.getPointer(); + ElementType = address.getElementType(); + Alignment = address.getAlignment().getQuantity(); + IsKnownNonNull = address.isKnownNonNull(); } - - void setAddress(Address address) { Addr = address; } // vector elt lvalue Address getVectorAddress() const { - assert(isVectorElt()); - return Addr; - } - llvm::Value *getRawVectorPointer(CodeGenFunction &CGF) const { - assert(isVectorElt()); - return Addr.emitRawPointer(CGF); + return Address(getVectorPointer(), ElementType, getAlignment(), + (KnownNonNull_t)isKnownNonNull()); } llvm::Value *getVectorPointer() const { assert(isVectorElt()); - return Addr.getBasePointer(); + return V; } llvm::Value *getVectorIdx() const { assert(isVectorElt()); @@ -393,12 +374,12 @@ public: } Address getMatrixAddress() const { - assert(isMatrixElt()); - return Addr; + return Address(getMatrixPointer(), ElementType, getAlignment(), + (KnownNonNull_t)isKnownNonNull()); } llvm::Value *getMatrixPointer() const { assert(isMatrixElt()); - return Addr.getBasePointer(); + return V; } llvm::Value *getMatrixIdx() const { assert(isMatrixElt()); @@ -407,12 +388,12 @@ public: // extended vector elements. Address getExtVectorAddress() const { - assert(isExtVectorElt()); - return Addr; + return Address(getExtVectorPointer(), ElementType, getAlignment(), + (KnownNonNull_t)isKnownNonNull()); } - llvm::Value *getRawExtVectorPointer(CodeGenFunction &CGF) const { + llvm::Value *getExtVectorPointer() const { assert(isExtVectorElt()); - return Addr.emitRawPointer(CGF); + return V; } llvm::Constant *getExtVectorElts() const { assert(isExtVectorElt()); @@ -421,14 +402,10 @@ public: // bitfield lvalue Address getBitFieldAddress() const { - assert(isBitField()); - return Addr; - } - llvm::Value *getRawBitFieldPointer(CodeGenFunction &CGF) const { - assert(isBitField()); - return Addr.emitRawPointer(CGF); + return Address(getBitFieldPointer(), ElementType, getAlignment(), + (KnownNonNull_t)isKnownNonNull()); } - + llvm::Value *getBitFieldPointer() const { assert(isBitField()); return V; } const CGBitFieldInfo &getBitFieldInfo() const { assert(isBitField()); return *BitFieldInfo; @@ -437,13 +414,18 @@ public: // global register lvalue llvm::Value *getGlobalReg() const { assert(isGlobalReg()); return V; } - static LValue MakeAddr(Address Addr, QualType type, ASTContext &Context, + static LValue MakeAddr(Address address, QualType type, ASTContext &Context, LValueBaseInfo BaseInfo, TBAAAccessInfo TBAAInfo) { + Qualifiers qs = type.getQualifiers(); + qs.setObjCGCAttr(Context.getObjCGCAttrKind(type)); + LValue R; R.LVType = Simple; - R.initializeSimpleLValue(Addr, type, BaseInfo, TBAAInfo, Context); - R.Addr = Addr; - assert(Addr.getType()->isPointerTy()); + assert(address.getPointer()->getType()->isPointerTy()); + R.V = address.getPointer(); + R.ElementType = address.getElementType(); + R.IsKnownNonNull = address.isKnownNonNull(); + R.Initialize(type, qs, address.getAlignment(), BaseInfo, TBAAInfo); return R; } @@ -452,18 +434,26 @@ public: TBAAAccessInfo TBAAInfo) { LValue R; R.LVType = VectorElt; + R.V = vecAddress.getPointer(); + R.ElementType = vecAddress.getElementType(); R.VectorIdx = Idx; - R.Initialize(type, type.getQualifiers(), vecAddress, BaseInfo, TBAAInfo); + R.IsKnownNonNull = vecAddress.isKnownNonNull(); + R.Initialize(type, type.getQualifiers(), vecAddress.getAlignment(), + BaseInfo, TBAAInfo); return R; } - static LValue MakeExtVectorElt(Address Addr, llvm::Constant *Elts, + static LValue MakeExtVectorElt(Address vecAddress, llvm::Constant *Elts, QualType type, LValueBaseInfo BaseInfo, TBAAAccessInfo TBAAInfo) { LValue R; R.LVType = ExtVectorElt; + R.V = vecAddress.getPointer(); + R.ElementType = vecAddress.getElementType(); R.VectorElts = Elts; - R.Initialize(type, type.getQualifiers(), Addr, BaseInfo, TBAAInfo); + R.IsKnownNonNull = vecAddress.isKnownNonNull(); + R.Initialize(type, type.getQualifiers(), vecAddress.getAlignment(), + BaseInfo, TBAAInfo); return R; } @@ -478,8 +468,12 @@ public: TBAAAccessInfo TBAAInfo) { LValue R; R.LVType = BitField; + R.V = Addr.getPointer(); + R.ElementType = Addr.getElementType(); R.BitFieldInfo = &Info; - R.Initialize(type, type.getQualifiers(), Addr, BaseInfo, TBAAInfo); + R.IsKnownNonNull = Addr.isKnownNonNull(); + R.Initialize(type, type.getQualifiers(), Addr.getAlignment(), BaseInfo, + TBAAInfo); return R; } @@ -487,9 +481,11 @@ public: QualType type) { LValue R; R.LVType = GlobalReg; - R.Initialize(type, type.getQualifiers(), Address::invalid(), - LValueBaseInfo(AlignmentSource::Decl), TBAAAccessInfo()); R.V = V; + R.ElementType = nullptr; + R.IsKnownNonNull = true; + R.Initialize(type, type.getQualifiers(), alignment, + LValueBaseInfo(AlignmentSource::Decl), TBAAAccessInfo()); return R; } @@ -498,8 +494,12 @@ public: TBAAAccessInfo TBAAInfo) { LValue R; R.LVType = MatrixElt; + R.V = matAddress.getPointer(); + R.ElementType = matAddress.getElementType(); R.VectorIdx = Idx; - R.Initialize(type, type.getQualifiers(), matAddress, BaseInfo, TBAAInfo); + R.IsKnownNonNull = matAddress.isKnownNonNull(); + R.Initialize(type, type.getQualifiers(), matAddress.getAlignment(), + BaseInfo, TBAAInfo); return R; } @@ -643,17 +643,17 @@ public: return NeedsGCBarriers_t(ObjCGCFlag); } - llvm::Value *getPointer(QualType PointeeTy, CodeGenFunction &CGF) const; - - llvm::Value *emitRawPointer(CodeGenFunction &CGF) const { - return Addr.isValid() ? Addr.emitRawPointer(CGF) : nullptr; + llvm::Value *getPointer() const { + return Addr.getPointer(); } Address getAddress() const { return Addr; } - bool isIgnored() const { return !Addr.isValid(); } + bool isIgnored() const { + return !Addr.isValid(); + } CharUnits getAlignment() const { return Addr.getAlignment(); diff --git a/clang/lib/CodeGen/CodeGenFunction.cpp b/clang/lib/CodeGen/CodeGenFunction.cpp index 44103884940f..f2ebaf767452 100644 --- a/clang/lib/CodeGen/CodeGenFunction.cpp +++ b/clang/lib/CodeGen/CodeGenFunction.cpp @@ -193,35 +193,26 @@ CodeGenFunction::CGFPOptionsRAII::~CGFPOptionsRAII() { CGF.Builder.setDefaultConstrainedRounding(OldRounding); } -static LValue MakeNaturalAlignAddrLValue(llvm::Value *V, QualType T, - bool ForPointeeType, - CodeGenFunction &CGF) { +LValue CodeGenFunction::MakeNaturalAlignAddrLValue(llvm::Value *V, QualType T) { LValueBaseInfo BaseInfo; TBAAAccessInfo TBAAInfo; - CharUnits Alignment = - CGF.CGM.getNaturalTypeAlignment(T, &BaseInfo, &TBAAInfo, ForPointeeType); - Address Addr = Address(V, CGF.ConvertTypeForMem(T), Alignment); - return CGF.MakeAddrLValue(Addr, T, BaseInfo, TBAAInfo); -} - -LValue CodeGenFunction::MakeNaturalAlignAddrLValue(llvm::Value *V, QualType T) { - return ::MakeNaturalAlignAddrLValue(V, T, /*ForPointeeType*/ false, *this); + CharUnits Alignment = CGM.getNaturalTypeAlignment(T, &BaseInfo, &TBAAInfo); + Address Addr(V, ConvertTypeForMem(T), Alignment); + return LValue::MakeAddr(Addr, T, getContext(), BaseInfo, TBAAInfo); } +/// Given a value of type T* that may not be to a complete object, +/// construct an l-value with the natural pointee alignment of T. LValue CodeGenFunction::MakeNaturalAlignPointeeAddrLValue(llvm::Value *V, QualType T) { - return ::MakeNaturalAlignAddrLValue(V, T, /*ForPointeeType*/ true, *this); -} - -LValue CodeGenFunction::MakeNaturalAlignRawAddrLValue(llvm::Value *V, - QualType T) { - return ::MakeNaturalAlignAddrLValue(V, T, /*ForPointeeType*/ false, *this); + LValueBaseInfo BaseInfo; + TBAAAccessInfo TBAAInfo; + CharUnits Align = CGM.getNaturalTypeAlignment(T, &BaseInfo, &TBAAInfo, + /* forPointeeType= */ true); + Address Addr(V, ConvertTypeForMem(T), Align); + return MakeAddrLValue(Addr, T, BaseInfo, TBAAInfo); } -LValue CodeGenFunction::MakeNaturalAlignPointeeRawAddrLValue(llvm::Value *V, - QualType T) { - return ::MakeNaturalAlignAddrLValue(V, T, /*ForPointeeType*/ true, *this); -} llvm::Type *CodeGenFunction::ConvertTypeForMem(QualType T) { return CGM.getTypes().ConvertTypeForMem(T); @@ -534,8 +525,7 @@ void CodeGenFunction::FinishFunction(SourceLocation EndLoc) { ReturnBlock.getBlock()->eraseFromParent(); } if (ReturnValue.isValid()) { - auto *RetAlloca = - dyn_cast(ReturnValue.emitRawPointer(*this)); + auto *RetAlloca = dyn_cast(ReturnValue.getPointer()); if (RetAlloca && RetAlloca->use_empty()) { RetAlloca->eraseFromParent(); ReturnValue = Address::invalid(); @@ -1132,14 +1122,13 @@ void CodeGenFunction::StartFunction(GlobalDecl GD, QualType RetTy, auto AI = CurFn->arg_begin(); if (CurFnInfo->getReturnInfo().isSRetAfterThis()) ++AI; - ReturnValue = makeNaturalAddressForPointer( - &*AI, RetTy, CurFnInfo->getReturnInfo().getIndirectAlign(), false, - nullptr, nullptr, KnownNonNull); + ReturnValue = + Address(&*AI, ConvertType(RetTy), + CurFnInfo->getReturnInfo().getIndirectAlign(), KnownNonNull); if (!CurFnInfo->getReturnInfo().getIndirectByVal()) { - ReturnValuePointer = - CreateDefaultAlignTempAlloca(ReturnValue.getType(), "result.ptr"); - Builder.CreateStore(ReturnValue.emitRawPointer(*this), - ReturnValuePointer); + ReturnValuePointer = CreateDefaultAlignTempAlloca( + ReturnValue.getPointer()->getType(), "result.ptr"); + Builder.CreateStore(ReturnValue.getPointer(), ReturnValuePointer); } } else if (CurFnInfo->getReturnInfo().getKind() == ABIArgInfo::InAlloca && !hasScalarEvaluationKind(CurFnInfo->getReturnType())) { @@ -1200,9 +1189,8 @@ void CodeGenFunction::StartFunction(GlobalDecl GD, QualType RetTy, // or contains the address of the enclosing object). LValue ThisFieldLValue = EmitLValueForLambdaField(LambdaThisCaptureField); if (!LambdaThisCaptureField->getType()->isPointerType()) { - // If the enclosing object was captured by value, just use its - // address. Sign this pointer. - CXXThisValue = ThisFieldLValue.getPointer(*this); + // If the enclosing object was captured by value, just use its address. + CXXThisValue = ThisFieldLValue.getAddress(*this).getPointer(); } else { // Load the lvalue pointed to by the field, since '*this' was captured // by reference. @@ -2024,9 +2012,8 @@ static void emitNonZeroVLAInit(CodeGenFunction &CGF, QualType baseType, = llvm::ConstantInt::get(CGF.IntPtrTy, baseSize.getQuantity()); Address begin = dest.withElementType(CGF.Int8Ty); - llvm::Value *end = Builder.CreateInBoundsGEP(begin.getElementType(), - begin.emitRawPointer(CGF), - sizeInChars, "vla.end"); + llvm::Value *end = Builder.CreateInBoundsGEP( + begin.getElementType(), begin.getPointer(), sizeInChars, "vla.end"); llvm::BasicBlock *originBB = CGF.Builder.GetInsertBlock(); llvm::BasicBlock *loopBB = CGF.createBasicBlock("vla-init.loop"); @@ -2037,7 +2024,7 @@ static void emitNonZeroVLAInit(CodeGenFunction &CGF, QualType baseType, CGF.EmitBlock(loopBB); llvm::PHINode *cur = Builder.CreatePHI(begin.getType(), 2, "vla.cur"); - cur->addIncoming(begin.emitRawPointer(CGF), originBB); + cur->addIncoming(begin.getPointer(), originBB); CharUnits curAlign = dest.getAlignment().alignmentOfArrayElement(baseSize); @@ -2230,10 +2217,10 @@ llvm::Value *CodeGenFunction::emitArrayLength(const ArrayType *origArrayType, addr = addr.withElementType(baseType); } else { // Create the actual GEP. - addr = Address(Builder.CreateInBoundsGEP(addr.getElementType(), - addr.emitRawPointer(*this), - gepIndices, "array.begin"), - ConvertTypeForMem(eltType), addr.getAlignment()); + addr = Address(Builder.CreateInBoundsGEP( + addr.getElementType(), addr.getPointer(), gepIndices, "array.begin"), + ConvertTypeForMem(eltType), + addr.getAlignment()); } baseType = eltType; @@ -2574,7 +2561,7 @@ void CodeGenFunction::EmitVarAnnotations(const VarDecl *D, llvm::Value *V) { Address CodeGenFunction::EmitFieldAnnotations(const FieldDecl *D, Address Addr) { assert(D->hasAttr() && "no annotate attribute"); - llvm::Value *V = Addr.emitRawPointer(*this); + llvm::Value *V = Addr.getPointer(); llvm::Type *VTy = V->getType(); auto *PTy = dyn_cast(VTy); unsigned AS = PTy ? PTy->getAddressSpace() : 0; diff --git a/clang/lib/CodeGen/CodeGenFunction.h b/clang/lib/CodeGen/CodeGenFunction.h index 8dd6da5f85f1..e8f8aa601ed0 100644 --- a/clang/lib/CodeGen/CodeGenFunction.h +++ b/clang/lib/CodeGen/CodeGenFunction.h @@ -151,9 +151,6 @@ struct DominatingLLVMValue { /// Answer whether the given value needs extra work to be saved. static bool needsSaving(llvm::Value *value) { - if (!value) - return false; - // If it's not an instruction, we don't need to save. if (!isa(value)) return false; @@ -180,28 +177,21 @@ template <> struct DominatingValue
{ typedef Address type; struct saved_type { - DominatingLLVMValue::saved_type BasePtr; + DominatingLLVMValue::saved_type SavedValue; llvm::Type *ElementType; CharUnits Alignment; - DominatingLLVMValue::saved_type Offset; - llvm::PointerType *EffectiveType; }; static bool needsSaving(type value) { - if (DominatingLLVMValue::needsSaving(value.getBasePointer()) || - DominatingLLVMValue::needsSaving(value.getOffset())) - return true; - return false; + return DominatingLLVMValue::needsSaving(value.getPointer()); } static saved_type save(CodeGenFunction &CGF, type value) { - return {DominatingLLVMValue::save(CGF, value.getBasePointer()), - value.getElementType(), value.getAlignment(), - DominatingLLVMValue::save(CGF, value.getOffset()), value.getType()}; + return { DominatingLLVMValue::save(CGF, value.getPointer()), + value.getElementType(), value.getAlignment() }; } static type restore(CodeGenFunction &CGF, saved_type value) { - return Address(DominatingLLVMValue::restore(CGF, value.BasePtr), - value.ElementType, value.Alignment, - DominatingLLVMValue::restore(CGF, value.Offset)); + return Address(DominatingLLVMValue::restore(CGF, value.SavedValue), + value.ElementType, value.Alignment); } }; @@ -211,26 +201,14 @@ template <> struct DominatingValue { class saved_type { enum Kind { ScalarLiteral, ScalarAddress, AggregateLiteral, AggregateAddress, ComplexAddress }; - union { - struct { - DominatingLLVMValue::saved_type first, second; - } Vals; - DominatingValue
::saved_type AggregateAddr; - }; + + llvm::Value *Value; + llvm::Type *ElementType; LLVM_PREFERRED_TYPE(Kind) unsigned K : 3; - unsigned IsVolatile : 1; - - saved_type(DominatingLLVMValue::saved_type Val1, unsigned K) - : Vals{Val1, DominatingLLVMValue::saved_type()}, K(K) {} - - saved_type(DominatingLLVMValue::saved_type Val1, - DominatingLLVMValue::saved_type Val2) - : Vals{Val1, Val2}, K(ComplexAddress) {} - - saved_type(DominatingValue
::saved_type AggregateAddr, - bool IsVolatile, unsigned K) - : AggregateAddr(AggregateAddr), K(K) {} + unsigned Align : 29; + saved_type(llvm::Value *v, llvm::Type *e, Kind k, unsigned a = 0) + : Value(v), ElementType(e), K(k), Align(a) {} public: static bool needsSaving(RValue value); @@ -681,7 +659,7 @@ public: llvm::Value *Size; public: - CallLifetimeEnd(RawAddress addr, llvm::Value *size) + CallLifetimeEnd(Address addr, llvm::Value *size) : Addr(addr.getPointer()), Size(size) {} void Emit(CodeGenFunction &CGF, Flags flags) override { @@ -706,7 +684,7 @@ public: }; /// i32s containing the indexes of the cleanup destinations. - RawAddress NormalCleanupDest = RawAddress::invalid(); + Address NormalCleanupDest = Address::invalid(); unsigned NextCleanupDestIndex = 1; @@ -841,10 +819,10 @@ public: template void pushCleanupAfterFullExpr(CleanupKind Kind, As... A) { if (!isInConditionalBranch()) - return pushCleanupAfterFullExprWithActiveFlag( - Kind, RawAddress::invalid(), A...); + return pushCleanupAfterFullExprWithActiveFlag(Kind, Address::invalid(), + A...); - RawAddress ActiveFlag = createCleanupActiveFlag(); + Address ActiveFlag = createCleanupActiveFlag(); assert(!DominatingValue
::needsSaving(ActiveFlag) && "cleanup active flag should never need saving"); @@ -857,7 +835,7 @@ public: template void pushCleanupAfterFullExprWithActiveFlag(CleanupKind Kind, - RawAddress ActiveFlag, As... A) { + Address ActiveFlag, As... A) { LifetimeExtendedCleanupHeader Header = {sizeof(T), Kind, ActiveFlag.isValid()}; @@ -872,7 +850,7 @@ public: new (Buffer) LifetimeExtendedCleanupHeader(Header); new (Buffer + sizeof(Header)) T(A...); if (Header.IsConditional) - new (Buffer + sizeof(Header) + sizeof(T)) RawAddress(ActiveFlag); + new (Buffer + sizeof(Header) + sizeof(T)) Address(ActiveFlag); } /// Set up the last cleanup that was pushed as a conditional @@ -881,8 +859,8 @@ public: initFullExprCleanupWithFlag(createCleanupActiveFlag()); } - void initFullExprCleanupWithFlag(RawAddress ActiveFlag); - RawAddress createCleanupActiveFlag(); + void initFullExprCleanupWithFlag(Address ActiveFlag); + Address createCleanupActiveFlag(); /// PushDestructorCleanup - Push a cleanup to call the /// complete-object destructor of an object of the given type at the @@ -1070,7 +1048,7 @@ public: QualType VarTy = LocalVD->getType(); if (VarTy->isReferenceType()) { Address Temp = CGF.CreateMemTemp(VarTy); - CGF.Builder.CreateStore(TempAddr.emitRawPointer(CGF), Temp); + CGF.Builder.CreateStore(TempAddr.getPointer(), Temp); TempAddr = Temp; } SavedTempAddresses.try_emplace(LocalVD, TempAddr); @@ -1265,12 +1243,10 @@ public: /// one branch or the other of a conditional expression. bool isInConditionalBranch() const { return OutermostConditional != nullptr; } - void setBeforeOutermostConditional(llvm::Value *value, Address addr, - CodeGenFunction &CGF) { + void setBeforeOutermostConditional(llvm::Value *value, Address addr) { assert(isInConditionalBranch()); llvm::BasicBlock *block = OutermostConditional->getStartingBlock(); - auto store = - new llvm::StoreInst(value, addr.emitRawPointer(CGF), &block->back()); + auto store = new llvm::StoreInst(value, addr.getPointer(), &block->back()); store->setAlignment(addr.getAlignment().getAsAlign()); } @@ -1625,7 +1601,7 @@ public: /// If \p StepV is null, the default increment is 1. void maybeUpdateMCDCTestVectorBitmap(const Expr *E) { if (isMCDCCoverageEnabled() && isBinaryLogicalOp(E)) { - PGO.emitMCDCTestVectorBitmapUpdate(Builder, E, MCDCCondBitmapAddr, *this); + PGO.emitMCDCTestVectorBitmapUpdate(Builder, E, MCDCCondBitmapAddr); PGO.setCurrentStmt(E); } } @@ -1633,7 +1609,7 @@ public: /// Update the MCDC temp value with the condition's evaluated result. void maybeUpdateMCDCCondBitmap(const Expr *E, llvm::Value *Val) { if (isMCDCCoverageEnabled()) { - PGO.emitMCDCCondBitmapUpdate(Builder, E, MCDCCondBitmapAddr, Val, *this); + PGO.emitMCDCCondBitmapUpdate(Builder, E, MCDCCondBitmapAddr, Val); PGO.setCurrentStmt(E); } } @@ -1728,7 +1704,7 @@ public: : CGF(CGF), OldCXXThisValue(CGF.CXXThisValue), OldCXXThisAlignment(CGF.CXXThisAlignment), SourceLocScope(E, CGF.CurSourceLocExprScope) { - CGF.CXXThisValue = CGF.CXXDefaultInitExprThis.getBasePointer(); + CGF.CXXThisValue = CGF.CXXDefaultInitExprThis.getPointer(); CGF.CXXThisAlignment = CGF.CXXDefaultInitExprThis.getAlignment(); } ~CXXDefaultInitExprScope() { @@ -2114,7 +2090,7 @@ public: llvm::Value *getExceptionFromSlot(); llvm::Value *getSelectorFromSlot(); - RawAddress getNormalCleanupDestSlot(); + Address getNormalCleanupDestSlot(); llvm::BasicBlock *getUnreachableBlock() { if (!UnreachableBlock) { @@ -2603,40 +2579,10 @@ public: // Helpers //===--------------------------------------------------------------------===// - Address mergeAddressesInConditionalExpr(Address LHS, Address RHS, - llvm::BasicBlock *LHSBlock, - llvm::BasicBlock *RHSBlock, - llvm::BasicBlock *MergeBlock, - QualType MergedType) { - Builder.SetInsertPoint(MergeBlock); - llvm::PHINode *PtrPhi = Builder.CreatePHI(LHS.getType(), 2, "cond"); - PtrPhi->addIncoming(LHS.getBasePointer(), LHSBlock); - PtrPhi->addIncoming(RHS.getBasePointer(), RHSBlock); - LHS.replaceBasePointer(PtrPhi); - LHS.setAlignment(std::min(LHS.getAlignment(), RHS.getAlignment())); - return LHS; - } - - /// Construct an address with the natural alignment of T. If a pointer to T - /// is expected to be signed, the pointer passed to this function must have - /// been signed, and the returned Address will have the pointer authentication - /// information needed to authenticate the signed pointer. - Address makeNaturalAddressForPointer( - llvm::Value *Ptr, QualType T, CharUnits Alignment = CharUnits::Zero(), - bool ForPointeeType = false, LValueBaseInfo *BaseInfo = nullptr, - TBAAAccessInfo *TBAAInfo = nullptr, - KnownNonNull_t IsKnownNonNull = NotKnownNonNull) { - if (Alignment.isZero()) - Alignment = - CGM.getNaturalTypeAlignment(T, BaseInfo, TBAAInfo, ForPointeeType); - return Address(Ptr, ConvertTypeForMem(T), Alignment, nullptr, - IsKnownNonNull); - } - LValue MakeAddrLValue(Address Addr, QualType T, AlignmentSource Source = AlignmentSource::Type) { - return MakeAddrLValue(Addr, T, LValueBaseInfo(Source), - CGM.getTBAAAccessInfo(T)); + return LValue::MakeAddr(Addr, T, getContext(), LValueBaseInfo(Source), + CGM.getTBAAAccessInfo(T)); } LValue MakeAddrLValue(Address Addr, QualType T, LValueBaseInfo BaseInfo, @@ -2646,14 +2592,6 @@ public: LValue MakeAddrLValue(llvm::Value *V, QualType T, CharUnits Alignment, AlignmentSource Source = AlignmentSource::Type) { - return MakeAddrLValue(makeNaturalAddressForPointer(V, T, Alignment), T, - LValueBaseInfo(Source), CGM.getTBAAAccessInfo(T)); - } - - /// Same as MakeAddrLValue above except that the pointer is known to be - /// unsigned. - LValue MakeRawAddrLValue(llvm::Value *V, QualType T, CharUnits Alignment, - AlignmentSource Source = AlignmentSource::Type) { Address Addr(V, ConvertTypeForMem(T), Alignment); return LValue::MakeAddr(Addr, T, getContext(), LValueBaseInfo(Source), CGM.getTBAAAccessInfo(T)); @@ -2666,18 +2604,9 @@ public: TBAAAccessInfo()); } - /// Given a value of type T* that may not be to a complete object, construct - /// an l-value with the natural pointee alignment of T. LValue MakeNaturalAlignPointeeAddrLValue(llvm::Value *V, QualType T); - LValue MakeNaturalAlignAddrLValue(llvm::Value *V, QualType T); - /// Same as MakeNaturalAlignPointeeAddrLValue except that the pointer is known - /// to be unsigned. - LValue MakeNaturalAlignPointeeRawAddrLValue(llvm::Value *V, QualType T); - - LValue MakeNaturalAlignRawAddrLValue(llvm::Value *V, QualType T); - Address EmitLoadOfReference(LValue RefLVal, LValueBaseInfo *PointeeBaseInfo = nullptr, TBAAAccessInfo *PointeeTBAAInfo = nullptr); @@ -2726,13 +2655,13 @@ public: /// more efficient if the caller knows that the address will not be exposed. llvm::AllocaInst *CreateTempAlloca(llvm::Type *Ty, const Twine &Name = "tmp", llvm::Value *ArraySize = nullptr); - RawAddress CreateTempAlloca(llvm::Type *Ty, CharUnits align, - const Twine &Name = "tmp", - llvm::Value *ArraySize = nullptr, - RawAddress *Alloca = nullptr); - RawAddress CreateTempAllocaWithoutCast(llvm::Type *Ty, CharUnits align, - const Twine &Name = "tmp", - llvm::Value *ArraySize = nullptr); + Address CreateTempAlloca(llvm::Type *Ty, CharUnits align, + const Twine &Name = "tmp", + llvm::Value *ArraySize = nullptr, + Address *Alloca = nullptr); + Address CreateTempAllocaWithoutCast(llvm::Type *Ty, CharUnits align, + const Twine &Name = "tmp", + llvm::Value *ArraySize = nullptr); /// CreateDefaultAlignedTempAlloca - This creates an alloca with the /// default ABI alignment of the given LLVM type. @@ -2744,8 +2673,8 @@ public: /// not hand this address off to arbitrary IRGen routines, and especially /// do not pass it as an argument to a function that might expect a /// properly ABI-aligned value. - RawAddress CreateDefaultAlignTempAlloca(llvm::Type *Ty, - const Twine &Name = "tmp"); + Address CreateDefaultAlignTempAlloca(llvm::Type *Ty, + const Twine &Name = "tmp"); /// CreateIRTemp - Create a temporary IR object of the given type, with /// appropriate alignment. This routine should only be used when an temporary @@ -2755,31 +2684,32 @@ public: /// /// That is, this is exactly equivalent to CreateMemTemp, but calling /// ConvertType instead of ConvertTypeForMem. - RawAddress CreateIRTemp(QualType T, const Twine &Name = "tmp"); + Address CreateIRTemp(QualType T, const Twine &Name = "tmp"); /// CreateMemTemp - Create a temporary memory object of the given type, with /// appropriate alignmen and cast it to the default address space. Returns /// the original alloca instruction by \p Alloca if it is not nullptr. - RawAddress CreateMemTemp(QualType T, const Twine &Name = "tmp", - RawAddress *Alloca = nullptr); - RawAddress CreateMemTemp(QualType T, CharUnits Align, - const Twine &Name = "tmp", - RawAddress *Alloca = nullptr); + Address CreateMemTemp(QualType T, const Twine &Name = "tmp", + Address *Alloca = nullptr); + Address CreateMemTemp(QualType T, CharUnits Align, const Twine &Name = "tmp", + Address *Alloca = nullptr); /// CreateMemTemp - Create a temporary memory object of the given type, with /// appropriate alignmen without casting it to the default address space. - RawAddress CreateMemTempWithoutCast(QualType T, const Twine &Name = "tmp"); - RawAddress CreateMemTempWithoutCast(QualType T, CharUnits Align, - const Twine &Name = "tmp"); + Address CreateMemTempWithoutCast(QualType T, const Twine &Name = "tmp"); + Address CreateMemTempWithoutCast(QualType T, CharUnits Align, + const Twine &Name = "tmp"); /// CreateAggTemp - Create a temporary memory object for the given /// aggregate type. AggValueSlot CreateAggTemp(QualType T, const Twine &Name = "tmp", - RawAddress *Alloca = nullptr) { - return AggValueSlot::forAddr( - CreateMemTemp(T, Name, Alloca), T.getQualifiers(), - AggValueSlot::IsNotDestructed, AggValueSlot::DoesNotNeedGCBarriers, - AggValueSlot::IsNotAliased, AggValueSlot::DoesNotOverlap); + Address *Alloca = nullptr) { + return AggValueSlot::forAddr(CreateMemTemp(T, Name, Alloca), + T.getQualifiers(), + AggValueSlot::IsNotDestructed, + AggValueSlot::DoesNotNeedGCBarriers, + AggValueSlot::IsNotAliased, + AggValueSlot::DoesNotOverlap); } /// EvaluateExprAsBool - Perform the usual unary conversions on the specified @@ -3153,25 +3083,6 @@ public: /// calls to EmitTypeCheck can be skipped. bool sanitizePerformTypeCheck() const; - void EmitTypeCheck(TypeCheckKind TCK, SourceLocation Loc, LValue LV, - QualType Type, SanitizerSet SkippedChecks = SanitizerSet(), - llvm::Value *ArraySize = nullptr) { - if (!sanitizePerformTypeCheck()) - return; - EmitTypeCheck(TCK, Loc, LV.emitRawPointer(*this), Type, LV.getAlignment(), - SkippedChecks, ArraySize); - } - - void EmitTypeCheck(TypeCheckKind TCK, SourceLocation Loc, Address Addr, - QualType Type, CharUnits Alignment = CharUnits::Zero(), - SanitizerSet SkippedChecks = SanitizerSet(), - llvm::Value *ArraySize = nullptr) { - if (!sanitizePerformTypeCheck()) - return; - EmitTypeCheck(TCK, Loc, Addr.emitRawPointer(*this), Type, Alignment, - SkippedChecks, ArraySize); - } - /// Emit a check that \p V is the address of storage of the /// appropriate size and alignment for an object of type \p Type /// (or if ArraySize is provided, for an array of that bound). @@ -3272,17 +3183,17 @@ public: /// Address with original alloca instruction. Invalid if the variable was /// emitted as a global constant. - RawAddress AllocaAddr; + Address AllocaAddr; struct Invalid {}; AutoVarEmission(Invalid) : Variable(nullptr), Addr(Address::invalid()), - AllocaAddr(RawAddress::invalid()) {} + AllocaAddr(Address::invalid()) {} AutoVarEmission(const VarDecl &variable) : Variable(&variable), Addr(Address::invalid()), NRVOFlag(nullptr), IsEscapingByRef(false), IsConstantAggregate(false), - SizeForLifetimeMarkers(nullptr), AllocaAddr(RawAddress::invalid()) {} + SizeForLifetimeMarkers(nullptr), AllocaAddr(Address::invalid()) {} bool wasEmittedAsGlobal() const { return !Addr.isValid(); } @@ -3305,7 +3216,7 @@ public: } /// Returns the address for the original alloca instruction. - RawAddress getOriginalAllocatedAddress() const { return AllocaAddr; } + Address getOriginalAllocatedAddress() const { return AllocaAddr; } /// Returns the address of the object within this declaration. /// Note that this does not chase the forwarding pointer for @@ -3335,32 +3246,23 @@ public: llvm::GlobalValue::LinkageTypes Linkage); class ParamValue { - union { - Address Addr; - llvm::Value *Value; - }; - - bool IsIndirect; - - ParamValue(llvm::Value *V) : Value(V), IsIndirect(false) {} - ParamValue(Address A) : Addr(A), IsIndirect(true) {} - + llvm::Value *Value; + llvm::Type *ElementType; + unsigned Alignment; + ParamValue(llvm::Value *V, llvm::Type *T, unsigned A) + : Value(V), ElementType(T), Alignment(A) {} public: static ParamValue forDirect(llvm::Value *value) { - return ParamValue(value); + return ParamValue(value, nullptr, 0); } static ParamValue forIndirect(Address addr) { assert(!addr.getAlignment().isZero()); - return ParamValue(addr); + return ParamValue(addr.getPointer(), addr.getElementType(), + addr.getAlignment().getQuantity()); } - bool isIndirect() const { return IsIndirect; } - llvm::Value *getAnyValue() const { - if (!isIndirect()) - return Value; - assert(!Addr.hasOffset() && "unexpected offset"); - return Addr.getBasePointer(); - } + bool isIndirect() const { return Alignment != 0; } + llvm::Value *getAnyValue() const { return Value; } llvm::Value *getDirectValue() const { assert(!isIndirect()); @@ -3369,7 +3271,8 @@ public: Address getIndirectAddress() const { assert(isIndirect()); - return Addr; + return Address(Value, ElementType, CharUnits::fromQuantity(Alignment), + KnownNonNull); } }; @@ -4279,9 +4182,6 @@ public: const Twine &name = ""); llvm::CallInst *EmitNounwindRuntimeCall(llvm::FunctionCallee callee, const Twine &name = ""); - llvm::CallInst *EmitNounwindRuntimeCall(llvm::FunctionCallee callee, - ArrayRef
args, - const Twine &name = ""); llvm::CallInst *EmitNounwindRuntimeCall(llvm::FunctionCallee callee, ArrayRef args, const Twine &name = ""); @@ -4308,12 +4208,6 @@ public: CXXDtorType Type, const CXXRecordDecl *RD); - llvm::Value *getAsNaturalPointerTo(Address Addr, QualType PointeeType) { - return Addr.getBasePointer(); - } - - bool isPointerKnownNonNull(const Expr *E); - // Return the copy constructor name with the prefix "__copy_constructor_" // removed. static std::string getNonTrivialCopyConstructorStr(QualType QT, @@ -4886,11 +4780,6 @@ public: SourceLocation Loc, const Twine &Name = ""); - Address EmitCheckedInBoundsGEP(Address Addr, ArrayRef IdxList, - llvm::Type *elementType, bool SignedIndices, - bool IsSubtraction, SourceLocation Loc, - CharUnits Align, const Twine &Name = ""); - /// Specifies which type of sanitizer check to apply when handling a /// particular builtin. enum BuiltinCheckKind { @@ -4953,10 +4842,6 @@ public: void EmitNonNullArgCheck(RValue RV, QualType ArgType, SourceLocation ArgLoc, AbstractCallee AC, unsigned ParmNum); - void EmitNonNullArgCheck(Address Addr, QualType ArgType, - SourceLocation ArgLoc, AbstractCallee AC, - unsigned ParmNum); - /// EmitCallArg - Emit a single call argument. void EmitCallArg(CallArgList &args, const Expr *E, QualType ArgType); @@ -5165,7 +5050,7 @@ DominatingLLVMValue::save(CodeGenFunction &CGF, llvm::Value *value) { CGF.CreateTempAlloca(value->getType(), align, "cond-cleanup.save"); CGF.Builder.CreateStore(value, alloca); - return saved_type(alloca.emitRawPointer(CGF), true); + return saved_type(alloca.getPointer(), true); } inline llvm::Value *DominatingLLVMValue::restore(CodeGenFunction &CGF, diff --git a/clang/lib/CodeGen/CodeGenModule.cpp b/clang/lib/CodeGen/CodeGenModule.cpp index 00b3bfcaa0bc..e3ed5e90f2d3 100644 --- a/clang/lib/CodeGen/CodeGenModule.cpp +++ b/clang/lib/CodeGen/CodeGenModule.cpp @@ -7267,7 +7267,7 @@ void CodeGenFunction::EmitDeclMetadata() { for (auto &I : LocalDeclMap) { const Decl *D = I.first; - llvm::Value *Addr = I.second.emitRawPointer(*this); + llvm::Value *Addr = I.second.getPointer(); if (auto *Alloca = dyn_cast(Addr)) { llvm::Value *DAddr = GetPointerConstant(getLLVMContext(), D); Alloca->setMetadata( diff --git a/clang/lib/CodeGen/CodeGenPGO.cpp b/clang/lib/CodeGen/CodeGenPGO.cpp index 76704c4d7be4..2619edfeb7dc 100644 --- a/clang/lib/CodeGen/CodeGenPGO.cpp +++ b/clang/lib/CodeGen/CodeGenPGO.cpp @@ -1239,8 +1239,7 @@ void CodeGenPGO::emitMCDCParameters(CGBuilderTy &Builder) { void CodeGenPGO::emitMCDCTestVectorBitmapUpdate(CGBuilderTy &Builder, const Expr *S, - Address MCDCCondBitmapAddr, - CodeGenFunction &CGF) { + Address MCDCCondBitmapAddr) { if (!canEmitMCDCCoverage(Builder) || !RegionMCDCState) return; @@ -1263,7 +1262,7 @@ void CodeGenPGO::emitMCDCTestVectorBitmapUpdate(CGBuilderTy &Builder, Builder.getInt64(FunctionHash), Builder.getInt32(RegionMCDCState->BitmapBytes), Builder.getInt32(MCDCTestVectorBitmapOffset), - MCDCCondBitmapAddr.emitRawPointer(CGF)}; + MCDCCondBitmapAddr.getPointer()}; Builder.CreateCall( CGM.getIntrinsic(llvm::Intrinsic::instrprof_mcdc_tvbitmap_update), Args); } @@ -1284,8 +1283,7 @@ void CodeGenPGO::emitMCDCCondBitmapReset(CGBuilderTy &Builder, const Expr *S, void CodeGenPGO::emitMCDCCondBitmapUpdate(CGBuilderTy &Builder, const Expr *S, Address MCDCCondBitmapAddr, - llvm::Value *Val, - CodeGenFunction &CGF) { + llvm::Value *Val) { if (!canEmitMCDCCoverage(Builder) || !RegionMCDCState) return; @@ -1314,7 +1312,7 @@ void CodeGenPGO::emitMCDCCondBitmapUpdate(CGBuilderTy &Builder, const Expr *S, llvm::Value *Args[5] = {llvm::ConstantExpr::getBitCast(FuncNameVar, I8PtrTy), Builder.getInt64(FunctionHash), Builder.getInt32(Branch.ID), - MCDCCondBitmapAddr.emitRawPointer(CGF), Val}; + MCDCCondBitmapAddr.getPointer(), Val}; Builder.CreateCall( CGM.getIntrinsic(llvm::Intrinsic::instrprof_mcdc_condbitmap_update), Args); diff --git a/clang/lib/CodeGen/CodeGenPGO.h b/clang/lib/CodeGen/CodeGenPGO.h index 9d66ffad6f43..036fbf6815a4 100644 --- a/clang/lib/CodeGen/CodeGenPGO.h +++ b/clang/lib/CodeGen/CodeGenPGO.h @@ -113,14 +113,12 @@ public: void emitCounterSetOrIncrement(CGBuilderTy &Builder, const Stmt *S, llvm::Value *StepV); void emitMCDCTestVectorBitmapUpdate(CGBuilderTy &Builder, const Expr *S, - Address MCDCCondBitmapAddr, - CodeGenFunction &CGF); + Address MCDCCondBitmapAddr); void emitMCDCParameters(CGBuilderTy &Builder); void emitMCDCCondBitmapReset(CGBuilderTy &Builder, const Expr *S, Address MCDCCondBitmapAddr); void emitMCDCCondBitmapUpdate(CGBuilderTy &Builder, const Expr *S, - Address MCDCCondBitmapAddr, llvm::Value *Val, - CodeGenFunction &CGF); + Address MCDCCondBitmapAddr, llvm::Value *Val); /// Return the region count for the counter at the given index. uint64_t getRegionCount(const Stmt *S) { diff --git a/clang/lib/CodeGen/ItaniumCXXABI.cpp b/clang/lib/CodeGen/ItaniumCXXABI.cpp index fd71317572f0..bdd53a192f82 100644 --- a/clang/lib/CodeGen/ItaniumCXXABI.cpp +++ b/clang/lib/CodeGen/ItaniumCXXABI.cpp @@ -307,6 +307,10 @@ public: CodeGenFunction &CGF, const CXXRecordDecl *VTableClass, BaseSubobject Base, const CXXRecordDecl *NearestVBase); + llvm::Constant * + getVTableAddressPointForConstExpr(BaseSubobject Base, + const CXXRecordDecl *VTableClass) override; + llvm::GlobalVariable *getAddrOfVTable(const CXXRecordDecl *RD, CharUnits VPtrOffset) override; @@ -642,7 +646,7 @@ CGCallee ItaniumCXXABI::EmitLoadOfMemberFunctionPointer( // Apply the adjustment and cast back to the original struct type // for consistency. - llvm::Value *This = ThisAddr.emitRawPointer(CGF); + llvm::Value *This = ThisAddr.getPointer(); This = Builder.CreateInBoundsGEP(Builder.getInt8Ty(), This, Adj); ThisPtrForCall = This; @@ -846,7 +850,7 @@ llvm::Value *ItaniumCXXABI::EmitMemberDataPointerAddress( CGBuilderTy &Builder = CGF.Builder; // Apply the offset, which we assume is non-null. - return Builder.CreateInBoundsGEP(CGF.Int8Ty, Base.emitRawPointer(CGF), MemPtr, + return Builder.CreateInBoundsGEP(CGF.Int8Ty, Base.getPointer(), MemPtr, "memptr.offset"); } @@ -1241,7 +1245,7 @@ void ItaniumCXXABI::emitVirtualObjectDelete(CodeGenFunction &CGF, CGF.getPointerAlign()); // Apply the offset. - llvm::Value *CompletePtr = Ptr.emitRawPointer(CGF); + llvm::Value *CompletePtr = Ptr.getPointer(); CompletePtr = CGF.Builder.CreateInBoundsGEP(CGF.Int8Ty, CompletePtr, Offset); @@ -1478,8 +1482,7 @@ llvm::Value *ItaniumCXXABI::emitDynamicCastCall( computeOffsetHint(CGF.getContext(), SrcDecl, DestDecl).getQuantity()); // Emit the call to __dynamic_cast. - llvm::Value *Args[] = {ThisAddr.emitRawPointer(CGF), SrcRTTI, DestRTTI, - OffsetHint}; + llvm::Value *Args[] = {ThisAddr.getPointer(), SrcRTTI, DestRTTI, OffsetHint}; llvm::Value *Value = CGF.EmitNounwindRuntimeCall(getItaniumDynamicCastFn(CGF), Args); @@ -1568,7 +1571,7 @@ llvm::Value *ItaniumCXXABI::emitExactDynamicCast( VPtr, CGM.getTBAAVTablePtrAccessInfo(CGF.VoidPtrPtrTy)); llvm::Value *Success = CGF.Builder.CreateICmpEQ( VPtr, getVTableAddressPoint(BaseSubobject(SrcDecl, *Offset), DestDecl)); - llvm::Value *Result = ThisAddr.emitRawPointer(CGF); + llvm::Value *Result = ThisAddr.getPointer(); if (!Offset->isZero()) Result = CGF.Builder.CreateInBoundsGEP( CGF.CharTy, Result, @@ -1608,7 +1611,7 @@ llvm::Value *ItaniumCXXABI::emitDynamicCastToVoid(CodeGenFunction &CGF, PtrDiffLTy, OffsetToTop, CGF.getPointerAlign(), "offset.to.top"); } // Finally, add the offset to the pointer. - return CGF.Builder.CreateInBoundsGEP(CGF.Int8Ty, ThisAddr.emitRawPointer(CGF), + return CGF.Builder.CreateInBoundsGEP(CGF.Int8Ty, ThisAddr.getPointer(), OffsetToTop); } @@ -1789,8 +1792,8 @@ void ItaniumCXXABI::EmitDestructorCall(CodeGenFunction &CGF, else Callee = CGCallee::forDirect(CGM.getAddrOfCXXStructor(GD), GD); - CGF.EmitCXXDestructorCall(GD, Callee, CGF.getAsNaturalPointerTo(This, ThisTy), - ThisTy, VTT, VTTTy, nullptr); + CGF.EmitCXXDestructorCall(GD, Callee, This.getPointer(), ThisTy, VTT, VTTTy, + nullptr); } void ItaniumCXXABI::emitVTableDefinitions(CodeGenVTables &CGVT, @@ -1949,6 +1952,11 @@ llvm::Value *ItaniumCXXABI::getVTableAddressPointInStructorWithVTT( CGF.getPointerAlign()); } +llvm::Constant *ItaniumCXXABI::getVTableAddressPointForConstExpr( + BaseSubobject Base, const CXXRecordDecl *VTableClass) { + return getVTableAddressPoint(Base, VTableClass); +} + llvm::GlobalVariable *ItaniumCXXABI::getAddrOfVTable(const CXXRecordDecl *RD, CharUnits VPtrOffset) { assert(VPtrOffset.isZero() && "Itanium ABI only supports zero vptr offsets"); @@ -2080,8 +2088,8 @@ llvm::Value *ItaniumCXXABI::EmitVirtualDestructorCall( ThisTy = D->getDestroyedType(); } - CGF.EmitCXXDestructorCall(GD, Callee, This.emitRawPointer(CGF), ThisTy, - nullptr, QualType(), nullptr); + CGF.EmitCXXDestructorCall(GD, Callee, This.getPointer(), ThisTy, nullptr, + QualType(), nullptr); return nullptr; } @@ -2154,7 +2162,7 @@ static llvm::Value *performTypeAdjustment(CodeGenFunction &CGF, int64_t VirtualAdjustment, bool IsReturnAdjustment) { if (!NonVirtualAdjustment && !VirtualAdjustment) - return InitialPtr.emitRawPointer(CGF); + return InitialPtr.getPointer(); Address V = InitialPtr.withElementType(CGF.Int8Ty); @@ -2187,10 +2195,10 @@ static llvm::Value *performTypeAdjustment(CodeGenFunction &CGF, CGF.getPointerAlign()); } // Adjust our pointer. - ResultPtr = CGF.Builder.CreateInBoundsGEP(V.getElementType(), - V.emitRawPointer(CGF), Offset); + ResultPtr = CGF.Builder.CreateInBoundsGEP( + V.getElementType(), V.getPointer(), Offset); } else { - ResultPtr = V.emitRawPointer(CGF); + ResultPtr = V.getPointer(); } // In a derived-to-base conversion, the non-virtual adjustment is @@ -2276,7 +2284,7 @@ Address ItaniumCXXABI::InitializeArrayCookie(CodeGenFunction &CGF, llvm::FunctionType::get(CGM.VoidTy, NumElementsPtr.getType(), false); llvm::FunctionCallee F = CGM.CreateRuntimeFunction(FTy, "__asan_poison_cxx_array_cookie"); - CGF.Builder.CreateCall(F, NumElementsPtr.emitRawPointer(CGF)); + CGF.Builder.CreateCall(F, NumElementsPtr.getPointer()); } // Finally, compute a pointer to the actual data buffer by skipping @@ -2307,7 +2315,7 @@ llvm::Value *ItaniumCXXABI::readArrayCookieImpl(CodeGenFunction &CGF, llvm::FunctionType::get(CGF.SizeTy, CGF.UnqualPtrTy, false); llvm::FunctionCallee F = CGM.CreateRuntimeFunction(FTy, "__asan_load_cxx_array_cookie"); - return CGF.Builder.CreateCall(F, numElementsPtr.emitRawPointer(CGF)); + return CGF.Builder.CreateCall(F, numElementsPtr.getPointer()); } CharUnits ARMCXXABI::getArrayCookieSizeImpl(QualType elementType) { @@ -2619,7 +2627,7 @@ void ItaniumCXXABI::EmitGuardedInit(CodeGenFunction &CGF, // Call __cxa_guard_release. This cannot throw. CGF.EmitNounwindRuntimeCall(getGuardReleaseFn(CGM, guardPtrTy), - guardAddr.emitRawPointer(CGF)); + guardAddr.getPointer()); } else if (D.isLocalVarDecl()) { // For local variables, store 1 into the first byte of the guard variable // after the object initialization completes so that initialization is @@ -3112,10 +3120,10 @@ LValue ItaniumCXXABI::EmitThreadLocalVarDeclLValue(CodeGenFunction &CGF, LValue LV; if (VD->getType()->isReferenceType()) - LV = CGF.MakeNaturalAlignRawAddrLValue(CallVal, LValType); + LV = CGF.MakeNaturalAlignAddrLValue(CallVal, LValType); else - LV = CGF.MakeRawAddrLValue(CallVal, LValType, - CGF.getContext().getDeclAlign(VD)); + LV = CGF.MakeAddrLValue(CallVal, LValType, + CGF.getContext().getDeclAlign(VD)); // FIXME: need setObjCGCLValueClass? return LV; } @@ -4596,7 +4604,7 @@ static void InitCatchParam(CodeGenFunction &CGF, CGF.Builder.CreateStore(Casted, ExnPtrTmp); // Bind the reference to the temporary. - AdjustedExn = ExnPtrTmp.emitRawPointer(CGF); + AdjustedExn = ExnPtrTmp.getPointer(); } } diff --git a/clang/lib/CodeGen/MicrosoftCXXABI.cpp b/clang/lib/CodeGen/MicrosoftCXXABI.cpp index d38a26940a3c..172c4c937b97 100644 --- a/clang/lib/CodeGen/MicrosoftCXXABI.cpp +++ b/clang/lib/CodeGen/MicrosoftCXXABI.cpp @@ -327,6 +327,10 @@ public: CodeGenFunction &CGF, const CXXRecordDecl *VTableClass, BaseSubobject Base, const CXXRecordDecl *NearestVBase) override; + llvm::Constant * + getVTableAddressPointForConstExpr(BaseSubobject Base, + const CXXRecordDecl *VTableClass) override; + llvm::GlobalVariable *getAddrOfVTable(const CXXRecordDecl *RD, CharUnits VPtrOffset) override; @@ -933,7 +937,7 @@ void MicrosoftCXXABI::emitBeginCatch(CodeGenFunction &CGF, } CodeGenFunction::AutoVarEmission var = CGF.EmitAutoVarAlloca(*CatchParam); - CPI->setArgOperand(2, var.getObjectAddress(CGF).emitRawPointer(CGF)); + CPI->setArgOperand(2, var.getObjectAddress(CGF).getPointer()); CGF.EHStack.pushCleanup(NormalCleanup, CPI); CGF.EmitAutoVarCleanups(var); } @@ -970,7 +974,7 @@ MicrosoftCXXABI::performBaseAdjustment(CodeGenFunction &CGF, Address Value, llvm::Value *Offset = GetVirtualBaseClassOffset(CGF, Value, SrcDecl, PolymorphicBase); llvm::Value *Ptr = CGF.Builder.CreateInBoundsGEP( - Value.getElementType(), Value.emitRawPointer(CGF), Offset); + Value.getElementType(), Value.getPointer(), Offset); CharUnits VBaseAlign = CGF.CGM.getVBaseAlignment(Value.getAlignment(), SrcDecl, PolymorphicBase); return std::make_tuple(Address(Ptr, CGF.Int8Ty, VBaseAlign), Offset, @@ -1007,7 +1011,7 @@ llvm::Value *MicrosoftCXXABI::EmitTypeid(CodeGenFunction &CGF, llvm::Type *StdTypeInfoPtrTy) { std::tie(ThisPtr, std::ignore, std::ignore) = performBaseAdjustment(CGF, ThisPtr, SrcRecordTy); - llvm::CallBase *Typeid = emitRTtypeidCall(CGF, ThisPtr.emitRawPointer(CGF)); + llvm::CallBase *Typeid = emitRTtypeidCall(CGF, ThisPtr.getPointer()); return CGF.Builder.CreateBitCast(Typeid, StdTypeInfoPtrTy); } @@ -1029,7 +1033,7 @@ llvm::Value *MicrosoftCXXABI::emitDynamicCastCall( llvm::Value *Offset; std::tie(This, Offset, std::ignore) = performBaseAdjustment(CGF, This, SrcRecordTy); - llvm::Value *ThisPtr = This.emitRawPointer(CGF); + llvm::Value *ThisPtr = This.getPointer(); Offset = CGF.Builder.CreateTrunc(Offset, CGF.Int32Ty); // PVOID __RTDynamicCast( @@ -1061,7 +1065,7 @@ llvm::Value *MicrosoftCXXABI::emitDynamicCastToVoid(CodeGenFunction &CGF, llvm::FunctionCallee Function = CGF.CGM.CreateRuntimeFunction( llvm::FunctionType::get(CGF.Int8PtrTy, ArgTypes, false), "__RTCastToVoid"); - llvm::Value *Args[] = {Value.emitRawPointer(CGF)}; + llvm::Value *Args[] = {Value.getPointer()}; return CGF.EmitRuntimeCall(Function, Args); } @@ -1489,7 +1493,7 @@ Address MicrosoftCXXABI::adjustThisArgumentForVirtualFunctionCall( llvm::Value *VBaseOffset = GetVirtualBaseClassOffset(CGF, Result, Derived, VBase); llvm::Value *VBasePtr = CGF.Builder.CreateInBoundsGEP( - Result.getElementType(), Result.emitRawPointer(CGF), VBaseOffset); + Result.getElementType(), Result.getPointer(), VBaseOffset); CharUnits VBaseAlign = CGF.CGM.getVBaseAlignment(Result.getAlignment(), Derived, VBase); Result = Address(VBasePtr, CGF.Int8Ty, VBaseAlign); @@ -1656,8 +1660,7 @@ void MicrosoftCXXABI::EmitDestructorCall(CodeGenFunction &CGF, llvm::Value *Implicit = getCXXDestructorImplicitParam(CGF, DD, Type, ForVirtualBase, Delegating); // = nullptr - CGF.EmitCXXDestructorCall(GD, Callee, CGF.getAsNaturalPointerTo(This, ThisTy), - ThisTy, + CGF.EmitCXXDestructorCall(GD, Callee, This.getPointer(), ThisTy, /*ImplicitParam=*/Implicit, /*ImplicitParamTy=*/QualType(), nullptr); if (BaseDtorEndBB) { @@ -1788,6 +1791,13 @@ MicrosoftCXXABI::getVTableAddressPoint(BaseSubobject Base, return VFTablesMap[ID]; } +llvm::Constant *MicrosoftCXXABI::getVTableAddressPointForConstExpr( + BaseSubobject Base, const CXXRecordDecl *VTableClass) { + llvm::Constant *VFTable = getVTableAddressPoint(Base, VTableClass); + assert(VFTable && "Couldn't find a vftable for the given base?"); + return VFTable; +} + llvm::GlobalVariable *MicrosoftCXXABI::getAddrOfVTable(const CXXRecordDecl *RD, CharUnits VPtrOffset) { // getAddrOfVTable may return 0 if asked to get an address of a vtable which @@ -2003,9 +2013,8 @@ llvm::Value *MicrosoftCXXABI::EmitVirtualDestructorCall( } This = adjustThisArgumentForVirtualFunctionCall(CGF, GD, This, true); - RValue RV = - CGF.EmitCXXDestructorCall(GD, Callee, This.emitRawPointer(CGF), ThisTy, - ImplicitParam, Context.IntTy, CE); + RValue RV = CGF.EmitCXXDestructorCall(GD, Callee, This.getPointer(), ThisTy, + ImplicitParam, Context.IntTy, CE); return RV.getScalarVal(); } @@ -2203,13 +2212,13 @@ llvm::Value *MicrosoftCXXABI::performThisAdjustment(CodeGenFunction &CGF, Address This, const ThisAdjustment &TA) { if (TA.isEmpty()) - return This.emitRawPointer(CGF); + return This.getPointer(); This = This.withElementType(CGF.Int8Ty); llvm::Value *V; if (TA.Virtual.isEmpty()) { - V = This.emitRawPointer(CGF); + V = This.getPointer(); } else { assert(TA.Virtual.Microsoft.VtordispOffset < 0); // Adjust the this argument based on the vtordisp value. @@ -2218,7 +2227,7 @@ llvm::Value *MicrosoftCXXABI::performThisAdjustment(CodeGenFunction &CGF, CharUnits::fromQuantity(TA.Virtual.Microsoft.VtordispOffset)); VtorDispPtr = VtorDispPtr.withElementType(CGF.Int32Ty); llvm::Value *VtorDisp = CGF.Builder.CreateLoad(VtorDispPtr, "vtordisp"); - V = CGF.Builder.CreateGEP(This.getElementType(), This.emitRawPointer(CGF), + V = CGF.Builder.CreateGEP(This.getElementType(), This.getPointer(), CGF.Builder.CreateNeg(VtorDisp)); // Unfortunately, having applied the vtordisp means that we no @@ -2255,11 +2264,11 @@ llvm::Value * MicrosoftCXXABI::performReturnAdjustment(CodeGenFunction &CGF, Address Ret, const ReturnAdjustment &RA) { if (RA.isEmpty()) - return Ret.emitRawPointer(CGF); + return Ret.getPointer(); Ret = Ret.withElementType(CGF.Int8Ty); - llvm::Value *V = Ret.emitRawPointer(CGF); + llvm::Value *V = Ret.getPointer(); if (RA.Virtual.Microsoft.VBIndex) { assert(RA.Virtual.Microsoft.VBIndex > 0); int32_t IntSize = CGF.getIntSize().getQuantity(); @@ -2574,7 +2583,7 @@ struct ResetGuardBit final : EHScopeStack::Cleanup { struct CallInitThreadAbort final : EHScopeStack::Cleanup { llvm::Value *Guard; - CallInitThreadAbort(RawAddress Guard) : Guard(Guard.getPointer()) {} + CallInitThreadAbort(Address Guard) : Guard(Guard.getPointer()) {} void Emit(CodeGenFunction &CGF, Flags flags) override { // Calling _Init_thread_abort will reset the guard's state. @@ -3114,8 +3123,8 @@ MicrosoftCXXABI::GetVBaseOffsetFromVBPtr(CodeGenFunction &CGF, llvm::Value **VBPtrOut) { CGBuilderTy &Builder = CGF.Builder; // Load the vbtable pointer from the vbptr in the instance. - llvm::Value *VBPtr = Builder.CreateInBoundsGEP( - CGM.Int8Ty, This.emitRawPointer(CGF), VBPtrOffset, "vbptr"); + llvm::Value *VBPtr = Builder.CreateInBoundsGEP(CGM.Int8Ty, This.getPointer(), + VBPtrOffset, "vbptr"); if (VBPtrOut) *VBPtrOut = VBPtr; @@ -3194,7 +3203,7 @@ llvm::Value *MicrosoftCXXABI::AdjustVirtualBase( Builder.CreateBr(SkipAdjustBB); CGF.EmitBlock(SkipAdjustBB); llvm::PHINode *Phi = Builder.CreatePHI(CGM.Int8PtrTy, 2, "memptr.base"); - Phi->addIncoming(Base.emitRawPointer(CGF), OriginalBB); + Phi->addIncoming(Base.getPointer(), OriginalBB); Phi->addIncoming(AdjustedBase, VBaseAdjustBB); return Phi; } @@ -3229,7 +3238,7 @@ llvm::Value *MicrosoftCXXABI::EmitMemberDataPointerAddress( Addr = AdjustVirtualBase(CGF, E, RD, Base, VirtualBaseAdjustmentOffset, VBPtrOffset); } else { - Addr = Base.emitRawPointer(CGF); + Addr = Base.getPointer(); } // Apply the offset, which we assume is non-null. @@ -3517,7 +3526,7 @@ CGCallee MicrosoftCXXABI::EmitLoadOfMemberFunctionPointer( ThisPtrForCall = AdjustVirtualBase(CGF, E, RD, This, VirtualBaseAdjustmentOffset, VBPtrOffset); } else { - ThisPtrForCall = This.emitRawPointer(CGF); + ThisPtrForCall = This.getPointer(); } if (NonVirtualBaseAdjustment) @@ -4436,7 +4445,10 @@ void MicrosoftCXXABI::emitThrow(CodeGenFunction &CGF, const CXXThrowExpr *E) { llvm::GlobalVariable *TI = getThrowInfo(ThrowType); // Call into the runtime to throw the exception. - llvm::Value *Args[] = {AI.emitRawPointer(CGF), TI}; + llvm::Value *Args[] = { + AI.getPointer(), + TI + }; CGF.EmitNoreturnRuntimeCallOrInvoke(getThrowFn(), Args); } diff --git a/clang/lib/CodeGen/TargetInfo.h b/clang/lib/CodeGen/TargetInfo.h index b1dfe5bf8f27..6893b50a3cfe 100644 --- a/clang/lib/CodeGen/TargetInfo.h +++ b/clang/lib/CodeGen/TargetInfo.h @@ -295,11 +295,6 @@ public: /// Get the AST address space for alloca. virtual LangAS getASTAllocaAddressSpace() const { return LangAS::Default; } - Address performAddrSpaceCast(CodeGen::CodeGenFunction &CGF, Address Addr, - LangAS SrcAddr, LangAS DestAddr, - llvm::Type *DestTy, - bool IsNonNull = false) const; - /// Perform address space cast of an expression of pointer type. /// \param V is the LLVM value to be casted to another address space. /// \param SrcAddr is the language address space of \p V. diff --git a/clang/lib/CodeGen/Targets/NVPTX.cpp b/clang/lib/CodeGen/Targets/NVPTX.cpp index 7dce5042c3dc..8718f1ecf3a7 100644 --- a/clang/lib/CodeGen/Targets/NVPTX.cpp +++ b/clang/lib/CodeGen/Targets/NVPTX.cpp @@ -85,7 +85,7 @@ private: LValue Src) { llvm::Value *Handle = nullptr; llvm::Constant *C = - llvm::dyn_cast(Src.getAddress(CGF).emitRawPointer(CGF)); + llvm::dyn_cast(Src.getAddress(CGF).getPointer()); // Lookup `addrspacecast` through the constant pointer if any. if (auto *ASC = llvm::dyn_cast_or_null(C)) C = llvm::cast(ASC->getPointerOperand()); diff --git a/clang/lib/CodeGen/Targets/PPC.cpp b/clang/lib/CodeGen/Targets/PPC.cpp index 362add30b435..00b04723f17d 100644 --- a/clang/lib/CodeGen/Targets/PPC.cpp +++ b/clang/lib/CodeGen/Targets/PPC.cpp @@ -513,10 +513,9 @@ Address PPC32_SVR4_ABIInfo::EmitVAArg(CodeGenFunction &CGF, Address VAList, CharUnits RegSize = CharUnits::fromQuantity((isInt || IsSoftFloatABI) ? 4 : 8); llvm::Value *RegOffset = Builder.CreateMul(NumRegs, Builder.getInt8(RegSize.getQuantity())); - RegAddr = Address(Builder.CreateInBoundsGEP( - CGF.Int8Ty, RegAddr.emitRawPointer(CGF), RegOffset), - DirectTy, - RegAddr.getAlignment().alignmentOfArrayElement(RegSize)); + RegAddr = Address( + Builder.CreateInBoundsGEP(CGF.Int8Ty, RegAddr.getPointer(), RegOffset), + DirectTy, RegAddr.getAlignment().alignmentOfArrayElement(RegSize)); // Increase the used-register count. NumRegs = @@ -552,7 +551,7 @@ Address PPC32_SVR4_ABIInfo::EmitVAArg(CodeGenFunction &CGF, Address VAList, // Round up address of argument to alignment CharUnits Align = CGF.getContext().getTypeAlignInChars(Ty); if (Align > OverflowAreaAlign) { - llvm::Value *Ptr = OverflowArea.emitRawPointer(CGF); + llvm::Value *Ptr = OverflowArea.getPointer(); OverflowArea = Address(emitRoundPointerUpToAlignment(CGF, Ptr, Align), OverflowArea.getElementType(), Align); } @@ -561,7 +560,7 @@ Address PPC32_SVR4_ABIInfo::EmitVAArg(CodeGenFunction &CGF, Address VAList, // Increase the overflow area. OverflowArea = Builder.CreateConstInBoundsByteGEP(OverflowArea, Size); - Builder.CreateStore(OverflowArea.emitRawPointer(CGF), OverflowAreaAddr); + Builder.CreateStore(OverflowArea.getPointer(), OverflowAreaAddr); CGF.EmitBranch(Cont); } diff --git a/clang/lib/CodeGen/Targets/Sparc.cpp b/clang/lib/CodeGen/Targets/Sparc.cpp index 9025a633f328..a337a52a94ec 100644 --- a/clang/lib/CodeGen/Targets/Sparc.cpp +++ b/clang/lib/CodeGen/Targets/Sparc.cpp @@ -326,7 +326,7 @@ Address SparcV9ABIInfo::EmitVAArg(CodeGenFunction &CGF, Address VAListAddr, // Update VAList. Address NextPtr = Builder.CreateConstInBoundsByteGEP(Addr, Stride, "ap.next"); - Builder.CreateStore(NextPtr.emitRawPointer(CGF), VAListAddr); + Builder.CreateStore(NextPtr.getPointer(), VAListAddr); return ArgAddr.withElementType(ArgTy); } diff --git a/clang/lib/CodeGen/Targets/SystemZ.cpp b/clang/lib/CodeGen/Targets/SystemZ.cpp index deaafc85a315..6eb0c6ef2f7d 100644 --- a/clang/lib/CodeGen/Targets/SystemZ.cpp +++ b/clang/lib/CodeGen/Targets/SystemZ.cpp @@ -306,7 +306,7 @@ Address SystemZABIInfo::EmitVAArg(CodeGenFunction &CGF, Address VAListAddr, // Update overflow_arg_area_ptr pointer llvm::Value *NewOverflowArgArea = CGF.Builder.CreateGEP( - OverflowArgArea.getElementType(), OverflowArgArea.emitRawPointer(CGF), + OverflowArgArea.getElementType(), OverflowArgArea.getPointer(), PaddedSizeV, "overflow_arg_area"); CGF.Builder.CreateStore(NewOverflowArgArea, OverflowArgAreaPtr); @@ -382,9 +382,10 @@ Address SystemZABIInfo::EmitVAArg(CodeGenFunction &CGF, Address VAListAddr, Address MemAddr = RawMemAddr.withElementType(DirectTy); // Update overflow_arg_area_ptr pointer - llvm::Value *NewOverflowArgArea = CGF.Builder.CreateGEP( - OverflowArgArea.getElementType(), OverflowArgArea.emitRawPointer(CGF), - PaddedSizeV, "overflow_arg_area"); + llvm::Value *NewOverflowArgArea = + CGF.Builder.CreateGEP(OverflowArgArea.getElementType(), + OverflowArgArea.getPointer(), PaddedSizeV, + "overflow_arg_area"); CGF.Builder.CreateStore(NewOverflowArgArea, OverflowArgAreaPtr); CGF.EmitBranch(ContBlock); diff --git a/clang/lib/CodeGen/Targets/XCore.cpp b/clang/lib/CodeGen/Targets/XCore.cpp index 88edb781a947..aeb48f851e16 100644 --- a/clang/lib/CodeGen/Targets/XCore.cpp +++ b/clang/lib/CodeGen/Targets/XCore.cpp @@ -180,7 +180,7 @@ Address XCoreABIInfo::EmitVAArg(CodeGenFunction &CGF, Address VAListAddr, // Increment the VAList. if (!ArgSize.isZero()) { Address APN = Builder.CreateConstInBoundsByteGEP(AP, ArgSize); - Builder.CreateStore(APN.emitRawPointer(CGF), VAListAddr); + Builder.CreateStore(APN.getPointer(), VAListAddr); } return Val; diff --git a/clang/utils/TableGen/MveEmitter.cpp b/clang/utils/TableGen/MveEmitter.cpp index aa20c758d84a..3a90eee5f1c9 100644 --- a/clang/utils/TableGen/MveEmitter.cpp +++ b/clang/utils/TableGen/MveEmitter.cpp @@ -575,7 +575,7 @@ public: // Emit code to generate this result as a Value *. std::string asValue() override { if (AddressType) - return "(" + varname() + ".emitRawPointer(*this))"; + return "(" + varname() + ".getPointer())"; return Result::asValue(); } bool hasIntegerValue() const override { return Immediate; } diff --git a/llvm/include/llvm/IR/IRBuilder.h b/llvm/include/llvm/IR/IRBuilder.h index 2e2ec9a1c830..2a0c1e9e8c44 100644 --- a/llvm/include/llvm/IR/IRBuilder.h +++ b/llvm/include/llvm/IR/IRBuilder.h @@ -2708,7 +2708,6 @@ public: IRBuilder(const IRBuilder &) = delete; InserterTy &getInserter() { return Inserter; } - const InserterTy &getInserter() const { return Inserter; } }; template -- GitLab From 1095f71bdfe25778c169954f249819bc5b553c91 Mon Sep 17 00:00:00 2001 From: smanna12 Date: Wed, 27 Mar 2024 20:20:22 -0500 Subject: [PATCH 011/788] [NFC][Clang] Fix potential dereferencing of nullptr (#86759) This patch replaces dyn_cast<> with cast<> to resolve potential static analyzer bugs for 1. Dereferencing a pointer issue with nullptr GVar when calling addAttribute() in AIXTargetCodeGenInfo::setTargetAttributes(clang::Decl const *, llvm::GlobalValue *, clang::CodeGen::CodeGenModule &). 2. Dereferencing a pointer issue with nullptr GG when calling getCorrespondingConstructor() in DeclareImplicitDeductionGuidesForTypeAlias(clang::Sema &, clang::TypeAliasTemplateDecl *, clang::SourceLocation). 3. Dereferencing a pointer issue with nullptr CurrentBT when calling getKind() in ComplexExprEmitter::GetHigherPrecisionFPType(clang::QualType). --- clang/lib/CodeGen/CGExprComplex.cpp | 2 +- clang/lib/CodeGen/Targets/PPC.cpp | 2 +- clang/lib/Sema/SemaTemplate.cpp | 2 +- 3 files changed, 3 insertions(+), 3 deletions(-) diff --git a/clang/lib/CodeGen/CGExprComplex.cpp b/clang/lib/CodeGen/CGExprComplex.cpp index b873bc6737bb..c3774d0cb75e 100644 --- a/clang/lib/CodeGen/CGExprComplex.cpp +++ b/clang/lib/CodeGen/CGExprComplex.cpp @@ -289,7 +289,7 @@ public: const BinOpInfo &Op); QualType GetHigherPrecisionFPType(QualType ElementType) { - const auto *CurrentBT = dyn_cast(ElementType); + const auto *CurrentBT = cast(ElementType); switch (CurrentBT->getKind()) { case BuiltinType::Kind::Float16: return CGF.getContext().FloatTy; diff --git a/clang/lib/CodeGen/Targets/PPC.cpp b/clang/lib/CodeGen/Targets/PPC.cpp index 00b04723f17d..3eadb19bd205 100644 --- a/clang/lib/CodeGen/Targets/PPC.cpp +++ b/clang/lib/CodeGen/Targets/PPC.cpp @@ -274,7 +274,7 @@ void AIXTargetCodeGenInfo::setTargetAttributes( if (!isa(GV)) return; - auto *GVar = dyn_cast(GV); + auto *GVar = cast(GV); auto GVId = GV->getName(); // Is this a global variable specified by the user as toc-data? diff --git a/clang/lib/Sema/SemaTemplate.cpp b/clang/lib/Sema/SemaTemplate.cpp index 005529a53270..aab72dbaf48c 100644 --- a/clang/lib/Sema/SemaTemplate.cpp +++ b/clang/lib/Sema/SemaTemplate.cpp @@ -2974,7 +2974,7 @@ void DeclareImplicitDeductionGuidesForTypeAlias( if (auto *FPrime = SemaRef.InstantiateFunctionDeclaration( F, TemplateArgListForBuildingFPrime, AliasTemplate->getLocation(), Sema::CodeSynthesisContext::BuildingDeductionGuides)) { - auto *GG = dyn_cast(FPrime); + auto *GG = cast(FPrime); buildDeductionGuide(SemaRef, AliasTemplate, FPrimeTemplateParamList, GG->getCorrespondingConstructor(), GG->getExplicitSpecifier(), GG->getTypeSourceInfo(), -- GitLab From 0c1c0d53931636331b59a03ed08f70936835399c Mon Sep 17 00:00:00 2001 From: Jerry Wu Date: Thu, 28 Mar 2024 01:32:27 +0000 Subject: [PATCH 012/788] [MLIR] Add patterns to bubble-up pack and push-down unpack through collapse/expand shape ops (#85297) Add DataLayoutPropagation patterns to bubble-up pack and push-down unpack through collapse/expand shape ops. --------- Co-authored-by: Quinn Dawkins --- .../Transforms/DataLayoutPropagation.cpp | 303 +++++++++++++++++- .../Linalg/data-layout-propagation.mlir | 160 +++++++++ 2 files changed, 462 insertions(+), 1 deletion(-) diff --git a/mlir/lib/Dialect/Linalg/Transforms/DataLayoutPropagation.cpp b/mlir/lib/Dialect/Linalg/Transforms/DataLayoutPropagation.cpp index 5ceb85e7d990..7fd88dec71d4 100644 --- a/mlir/lib/Dialect/Linalg/Transforms/DataLayoutPropagation.cpp +++ b/mlir/lib/Dialect/Linalg/Transforms/DataLayoutPropagation.cpp @@ -17,6 +17,7 @@ #include "mlir/Dialect/Utils/IndexingUtils.h" #include "mlir/IR/Dominance.h" #include "mlir/Transforms/GreedyPatternRewriteDriver.h" +#include "llvm/ADT/TypeSwitch.h" #include "llvm/Support/Debug.h" #include @@ -552,6 +553,305 @@ private: ControlPropagationFn controlFn; }; +/// Project dimsPos to the inner-most non-unit dim pos with reassocIndices. +/// +/// For example, given dimsPos [0, 2], reassocIndices [[0, 1], [2, 3]], and +/// targetShape [16, 16, 32, 1], it returns [1, 2]. Because for pos 0, the +/// inner-most projected dim in pos [0, 1] is 1. And for pos 2, the inner-most +/// non-unit projected dims in pos [2, 3] is 2. +/// +/// If all candidates in a reassociation are unit dims, it chooses the +/// inner-most dim pos. +static SmallVector +projectToInnerMostNonUnitDimsPos(ArrayRef dimsPos, + ArrayRef reassocIndices, + ArrayRef targetShape) { + SmallVector projectedDimsPos; + for (auto pos : dimsPos) { + // In the case all dims are unit, this will return the inner-most one. + int64_t projectedPos = reassocIndices[pos].back(); + for (auto i : llvm::reverse(reassocIndices[pos])) { + int64_t dim = targetShape[i]; + if (dim > 1 || ShapedType::isDynamic(dim)) { + projectedPos = i; + break; + } + } + projectedDimsPos.push_back(projectedPos); + } + return projectedDimsPos; +} + +/// Check if all dims in dimsPos are divisible by the corresponding tile sizes. +static bool isDimsDivisibleByTileSizes(ArrayRef dimsPos, + ArrayRef shape, + ArrayRef tileSizes) { + for (auto [pos, tileSize] : llvm::zip_equal(dimsPos, tileSizes)) { + int64_t dim = shape[pos]; + if (ShapedType::isDynamic(dim) || (dim % tileSize) != 0) + return false; + } + return true; +} + +/// Permutate the reassociation indices and reindex them in the sequence order. +/// Returns the next dim pos in the sequence. +/// +/// For example, given reassocIndices [[0, 1], [2]] and permutation [1, 0], it +/// applies the permutation to get [[2], [0, 1]] and reindexes the indices into +/// [[0], [1, 2]]. +static int64_t applyPermutationAndReindexReassoc( + SmallVector &reassocIndices, + ArrayRef permutation) { + applyPermutationToVector(reassocIndices, permutation); + int64_t nextPos = 0; + for (ReassociationIndices &indices : reassocIndices) { + for (auto &index : indices) { + index = nextPos; + nextPos += 1; + } + } + return nextPos; +} + +/// Bubble up pack op through collapse shape op when the packed dims can be +/// projected to the dims before collapsing. This is possible when the inner +/// tile sizes can divide the projected dims. +/// +/// For example: +/// +/// %collapsed = tensor.collapse_shape %in [[0, 1], 2] +/// : tensor into tensor +/// %pack = tensor.pack %collapsed outer_dims_perm = [0, 1] +/// inner_dims_pos = [0, 1] inner_tiles = [8, 1] into %empty +/// : tensor -> tensor +/// +/// can be transformed into: +/// +/// %pack = tensor.pack %in outer_dims_perm = [1, 2] +/// inner_dims_pos = [1, 2] inner_tiles = [8, 1] into %empty +/// : tensor -> tensor +/// %collapsed = tensor.collapse_shape %pack [[0, 1], 2, 3, 4] +/// : tensor into tensor +static LogicalResult +bubbleUpPackOpThroughCollapseShape(tensor::CollapseShapeOp collapseOp, + tensor::PackOp packOp, + PatternRewriter &rewriter) { + SmallVector innerTileSizes = packOp.getStaticTiles(); + ArrayRef innerDimsPos = packOp.getInnerDimsPos(); + ArrayRef outerDimsPerm = packOp.getOuterDimsPerm(); + + ArrayRef srcShape = collapseOp.getSrcType().getShape(); + SmallVector reassocIndices = + collapseOp.getReassociationIndices(); + // Project inner tile pos to the dim pos before collapsing. For example, if + // dims [x, y] is collapsed into [z], packing on dim z can be projected back + // to pack on dim y. + // + // Project to inner-most non-unit dims to increase the chance that they can be + // divided by the inner tile sizes. This is correct because for [..., x, 1], + // packing on dim 1 is equivalent to packing on dim x. + SmallVector projectedInnerDimsPos = + projectToInnerMostNonUnitDimsPos(innerDimsPos, reassocIndices, srcShape); + + if (!isDimsDivisibleByTileSizes(projectedInnerDimsPos, srcShape, + innerTileSizes)) { + return failure(); + } + // Expand the outer dims permutation with the associated source dims for the + // new permutation after bubbling. This is because moving a collapsed dim is + // equivalent to moving the associated source dims together. + SmallVector newOuterDimsPerm; + for (auto outerPos : outerDimsPerm) { + newOuterDimsPerm.insert(newOuterDimsPerm.end(), + reassocIndices[outerPos].begin(), + reassocIndices[outerPos].end()); + } + + auto emptyOp = tensor::PackOp::createDestinationTensor( + rewriter, packOp.getLoc(), collapseOp.getSrc(), packOp.getMixedTiles(), + projectedInnerDimsPos, newOuterDimsPerm); + auto newPackOp = rewriter.create( + packOp.getLoc(), collapseOp.getSrc(), emptyOp, projectedInnerDimsPos, + packOp.getMixedTiles(), packOp.getPaddingValue(), newOuterDimsPerm); + + SmallVector newReassocIndices = reassocIndices; + // First apply the permutation on the reassociations of the outer dims. + // For example given the permutation [1, 0], the reassociations [[0, 1], [2]] + // -> [[0], [1, 2]] + int64_t nextPos = + applyPermutationAndReindexReassoc(newReassocIndices, outerDimsPerm); + // Then add direct mapping for the inner tile dims. + for (size_t i = 0; i < innerDimsPos.size(); ++i) { + newReassocIndices.push_back({nextPos}); + nextPos += 1; + } + + auto newCollapseOp = rewriter.create( + collapseOp.getLoc(), packOp.getType(), newPackOp, newReassocIndices); + rewriter.replaceOp(packOp, newCollapseOp); + + return success(); +} + +class BubbleUpPackOpThroughReshapeOp final + : public OpRewritePattern { +public: + BubbleUpPackOpThroughReshapeOp(MLIRContext *context, ControlPropagationFn fun) + : OpRewritePattern(context), controlFn(std::move(fun)) {} + + LogicalResult matchAndRewrite(tensor::PackOp packOp, + PatternRewriter &rewriter) const override { + Operation *srcOp = packOp.getSource().getDefiningOp(); + // Currently only support when the pack op is the only user. + if (!srcOp || !(srcOp->getNumResults() == 1) || + !srcOp->getResult(0).hasOneUse()) { + return failure(); + } + // Currently only support static inner tile sizes. + if (llvm::any_of(packOp.getStaticTiles(), [](int64_t size) { + return ShapedType::isDynamic(size); + })) { + return failure(); + } + + // User controlled propagation function. + if (!controlFn(srcOp)) + return failure(); + + return TypeSwitch(srcOp) + .Case([&](tensor::CollapseShapeOp op) { + return bubbleUpPackOpThroughCollapseShape(op, packOp, rewriter); + }) + .Default([](Operation *) { return failure(); }); + } + +private: + ControlPropagationFn controlFn; +}; + +/// Push down unpack op through expand shape op when the packed dims can be +/// projected to the dims after expanding. This is possible when the inner tile +/// sizes can divide the projected dims. +/// +/// For example: +/// +/// %unpack = tensor.unpack %in outer_dims_perm = [0, 1] +/// inner_dims_pos = [0, 1] inner_tiles = [8, 8] into %empty +/// : tensor -> tensor +/// %expanded = tensor.expand_shape %unpack [[0, 1], [2]] +/// : tensor into tensor +/// +/// can be transformed into: +/// +/// %expanded = tensor.expand_shape %ain [[0, 1], [2], [3], [4]] +/// : tensor into tensor +/// %unpack = tensor.unpack %expanded outer_dims_perm = [0, 1, 2] +/// inner_dims_pos = [1, 2] inner_tiles = [8, 8] into %empty +/// : tensor -> tensor +static LogicalResult +pushDownUnPackOpThroughExpandShape(tensor::UnPackOp unPackOp, + tensor::ExpandShapeOp expandOp, + PatternRewriter &rewriter) { + SmallVector innerTileSizes = unPackOp.getStaticTiles(); + ArrayRef innerDimsPos = unPackOp.getInnerDimsPos(); + ArrayRef outerDimsPerm = unPackOp.getOuterDimsPerm(); + + ArrayRef dstShape = expandOp.getType().getShape(); + SmallVector reassocIndices = + expandOp.getReassociationIndices(); + // Project inner tile pos to the dim pos after expanding. For example, if dims + // [z] is expanded into [x, y], unpacking on dim z can be projected to unpack + // on dim y. + // + // Project to inner-most non-unit dims to increase the chance that they can be + // divided by the inner tile sizes. This is correct because for [..., x, 1], + // unpacking on dim 1 is equivalent to unpacking on dim x. + SmallVector projectedInnerDimsPos = + projectToInnerMostNonUnitDimsPos(innerDimsPos, reassocIndices, dstShape); + + if (!isDimsDivisibleByTileSizes(projectedInnerDimsPos, dstShape, + innerTileSizes)) { + return failure(); + } + // Expand the outer dims permutation with the associated expanded dims for the + // new permutation after pushing. This is because moving a source dim is + // equivalent to moving the associated expanded dims together. + SmallVector newOuterDimsPerm; + for (auto outerPos : outerDimsPerm) { + newOuterDimsPerm.insert(newOuterDimsPerm.end(), + reassocIndices[outerPos].begin(), + reassocIndices[outerPos].end()); + } + + SmallVector newReassocIndices = reassocIndices; + // First apply the permutation on the reassociations of the outer dims. + // For example given the permutation [1, 0], the reassociations [[0, 1], [2]] + // -> [[0], [1, 2]] + int64_t nextPos = + applyPermutationAndReindexReassoc(newReassocIndices, outerDimsPerm); + // Then add direct mapping for the inner tile dims. + for (size_t i = 0; i < innerDimsPos.size(); ++i) { + newReassocIndices.push_back({nextPos}); + nextPos += 1; + } + + RankedTensorType newExpandType = + tensor::PackOp::inferPackedType(expandOp.getType(), innerTileSizes, + projectedInnerDimsPos, newOuterDimsPerm); + auto newExpandOp = rewriter.create( + expandOp.getLoc(), newExpandType, unPackOp.getSource(), + newReassocIndices); + + auto emptyOp = tensor::UnPackOp::createDestinationTensor( + rewriter, unPackOp.getLoc(), newExpandOp, unPackOp.getMixedTiles(), + projectedInnerDimsPos, newOuterDimsPerm); + auto newUnPackOp = rewriter.create( + unPackOp.getLoc(), newExpandOp.getResult(), emptyOp, + projectedInnerDimsPos, unPackOp.getMixedTiles(), newOuterDimsPerm); + rewriter.replaceOp(expandOp, newUnPackOp); + + return success(); +} + +class PushDownUnPackOpThroughReshapeOp final + : public OpRewritePattern { +public: + PushDownUnPackOpThroughReshapeOp(MLIRContext *context, + ControlPropagationFn fun) + : OpRewritePattern(context), controlFn(std::move(fun)) { + } + + LogicalResult matchAndRewrite(tensor::UnPackOp unPackOp, + PatternRewriter &rewriter) const override { + Value result = unPackOp.getResult(); + // Currently only support unpack op with the single user. + if (!result.hasOneUse()) { + return failure(); + } + // Currently only support static inner tile sizes. + if (llvm::any_of(unPackOp.getStaticTiles(), [](int64_t size) { + return ShapedType::isDynamic(size); + })) { + return failure(); + } + + Operation *consumerOp = *result.user_begin(); + // User controlled propagation function. + if (!controlFn(consumerOp)) + return failure(); + + return TypeSwitch(consumerOp) + .Case([&](tensor::ExpandShapeOp op) { + return pushDownUnPackOpThroughExpandShape(unPackOp, op, rewriter); + }) + .Default([](Operation *) { return failure(); }); + } + +private: + ControlPropagationFn controlFn; +}; + // TODO: Relax this restriction. We should unpack a generic op also // in the presence of multiple unpack ops as producers. /// Return the unpacked operand, if present, for the current generic op. @@ -774,6 +1074,7 @@ void mlir::linalg::populateDataLayoutPropagationPatterns( const ControlPropagationFn &controlPackUnPackPropagation) { patterns .insert( + BubbleUpPackOpThroughReshapeOp, PushDownUnPackOpThroughGenericOp, + PushDownUnPackThroughPadOp, PushDownUnPackOpThroughReshapeOp>( patterns.getContext(), controlPackUnPackPropagation); } diff --git a/mlir/test/Dialect/Linalg/data-layout-propagation.mlir b/mlir/test/Dialect/Linalg/data-layout-propagation.mlir index e036695a2ac9..79d61ab757e3 100644 --- a/mlir/test/Dialect/Linalg/data-layout-propagation.mlir +++ b/mlir/test/Dialect/Linalg/data-layout-propagation.mlir @@ -905,3 +905,163 @@ func.func @unpack_different_destination_shape(%arg0: tensor<1x1x1080x1920x16xi32 // CHECK-SAME: inner_dims_pos = [0] inner_tiles = [16] // CHECK-SAME: into %[[UNPACK_NEW_DEST]] // CHECK: return %[[UNPACK]] : tensor<16x540x960xi32> + +// ----- + +func.func @bubble_up_pack_through_collapse(%1: tensor, %dim : index) -> tensor { + %collapsed = tensor.collapse_shape %1 [[0, 1], [2]] : tensor into tensor + %2 = tensor.empty(%dim) : tensor + %pack = tensor.pack %collapsed outer_dims_perm = [0, 1] inner_dims_pos = [0, 1] inner_tiles = [8, 1] into %2 : tensor -> tensor + func.return %pack : tensor +} +// CHECK-LABEL: func.func @bubble_up_pack_through_collapse +// CHECK-SAME: %[[ARG0:[a-zA-Z0-9]+]] +// CHECK-SAME: %[[ARG1:[a-zA-Z0-9]+]] +// CHECK: %[[C0:.+]] = arith.constant 0 : index +// CHECK: %[[DIM:.+]] = tensor.dim %[[ARG0]], %[[C0]] : tensor +// CHECK: %[[EMPTY:.+]] = tensor.empty(%[[DIM]]) : tensor +// CHECK: %[[PACK:.+]] = tensor.pack %[[ARG0]] outer_dims_perm = [0, 1, 2] inner_dims_pos = [1, 2] inner_tiles = [8, 1] into %[[EMPTY]] : tensor -> tensor +// CHECK: %[[COLLAPSED:.+]] = tensor.collapse_shape %[[PACK]] {{\[}}[0, 1], [2], [3], [4]] : tensor into tensor +// CHECK: return %[[COLLAPSED]] : tensor + +// ----- + +func.func @bubble_up_permuted_pack_through_collapse(%1: tensor<4x192x16x256xf32>) -> tensor<4x32x3072x8x1xf32> { + %collapsed = tensor.collapse_shape %1 [[0], [1, 2], [3]] : tensor<4x192x16x256xf32> into tensor<4x3072x256xf32> + %2 = tensor.empty() : tensor<4x32x3072x8x1xf32> + %pack = tensor.pack %collapsed outer_dims_perm = [0, 2, 1] inner_dims_pos = [2, 1] inner_tiles = [8, 1] into %2 : tensor<4x3072x256xf32> -> tensor<4x32x3072x8x1xf32> + func.return %pack : tensor<4x32x3072x8x1xf32> +} +// CHECK-LABEL: func.func @bubble_up_permuted_pack_through_collapse +// CHECK-SAME: %[[ARG0:[a-zA-Z0-9]+]] +// CHECK: %[[EMPTY:.+]] = tensor.empty() : tensor<4x32x192x16x8x1xf32> +// CHECK: %[[PACK:.+]] = tensor.pack %[[ARG0]] outer_dims_perm = [0, 3, 1, 2] inner_dims_pos = [3, 2] inner_tiles = [8, 1] into %[[EMPTY]] : tensor<4x192x16x256xf32> -> tensor<4x32x192x16x8x1xf32> +// CHECK: %[[COLLAPSED:.+]] = tensor.collapse_shape %pack {{\[}}[0], [1], [2, 3], [4], [5]] : tensor<4x32x192x16x8x1xf32> into tensor<4x32x3072x8x1xf32> +// CHECK: return %[[COLLAPSED]] : tensor<4x32x3072x8x1xf32> + +// ----- + +func.func @bubble_up_pack_through_unit_collapse(%1: tensor<1x64x1x4xf32>) -> tensor<8x4x8x1xf32> { + %collapsed = tensor.collapse_shape %1 [[0, 1, 2], [3]] : tensor<1x64x1x4xf32> into tensor<64x4xf32> + %2 = tensor.empty() : tensor<8x4x8x1xf32> + %pack = tensor.pack %collapsed outer_dims_perm = [0, 1] inner_dims_pos = [0, 1] inner_tiles = [8, 1] into %2 : tensor<64x4xf32> -> tensor<8x4x8x1xf32> + func.return %pack : tensor<8x4x8x1xf32> +} +// CHECK-LABEL: func.func @bubble_up_pack_through_unit_collapse +// CHECK-SAME: %[[ARG0:[a-zA-Z0-9]+]] +// CHECK: %[[EMPTY:.+]] = tensor.empty() : tensor<1x8x1x4x8x1xf32> +// CHECK: %[[PACK:.+]] = tensor.pack %[[ARG0]] outer_dims_perm = [0, 1, 2, 3] inner_dims_pos = [1, 3] inner_tiles = [8, 1] into %[[EMPTY]] : tensor<1x64x1x4xf32> -> tensor<1x8x1x4x8x1xf32> +// CHECK: %[[COLLAPSED:.+]] = tensor.collapse_shape %[[PACK]] {{\[}}[0, 1, 2], [3], [4], [5]] : tensor<1x8x1x4x8x1xf32> into tensor<8x4x8x1xf32> +// CHECK: return %[[COLLAPSED]] : tensor<8x4x8x1xf32> + +// ----- + +func.func @bubble_up_pack_through_collapse_on_outer_dims(%1: tensor, %dim : index) -> tensor { + %collapsed = tensor.collapse_shape %1 [[0, 1], [2]] : tensor into tensor + %2 = tensor.empty(%dim) : tensor + %pack = tensor.pack %collapsed outer_dims_perm = [0, 1] inner_dims_pos = [1] inner_tiles = [4] into %2 : tensor -> tensor + func.return %pack : tensor +} +// CHECK-LABEL: func.func @bubble_up_pack_through_collapse_on_outer_dims +// CHECK-SAME: %[[ARG0:[a-zA-Z0-9]+]] +// CHECK-SAME: %[[ARG1:[a-zA-Z0-9]+]] +// CHECK: %[[C0:.+]] = arith.constant 0 : index +// CHECK: %[[DIM:.+]] = tensor.dim %[[ARG0]], %[[C0]] : tensor +// CHECK: %[[EMPTY:.+]] = tensor.empty(%[[DIM]]) : tensor +// CHECK: %[[PACK:.+]] = tensor.pack %[[ARG0]] outer_dims_perm = [0, 1, 2] inner_dims_pos = [2] inner_tiles = [4] into %[[EMPTY]] : tensor -> tensor +// CHECK: %[[COLLAPSED:.+]] = tensor.collapse_shape %[[PACK]] {{\[}}[0, 1], [2], [3]] : tensor into tensor +// CHECK: return %[[COLLAPSED]] : tensor + +// ----- + +func.func @no_bubble_up_pack_through_non_divisible_collapse(%1: tensor<3072x64x4xf32>) -> tensor<384x32x8x8xf32> { + %collapsed = tensor.collapse_shape %1 [[0], [1, 2]] : tensor<3072x64x4xf32> into tensor<3072x256xf32> + %2 = tensor.empty() : tensor<384x32x8x8xf32> + %pack = tensor.pack %collapsed outer_dims_perm = [0, 1] inner_dims_pos = [0, 1] inner_tiles = [8, 8] into %2 : tensor<3072x256xf32> -> tensor<384x32x8x8xf32> + func.return %pack : tensor<384x32x8x8xf32> +} +// CHECK-LABEL: func.func @no_bubble_up_pack_through_non_divisible_collapse +// CHECK-SAME: %[[ARG0:[a-zA-Z0-9]+]] +// CHECK: %[[COLLAPSED:.+]] = tensor.collapse_shape %[[ARG0]] {{\[}}[0], [1, 2]] : tensor<3072x64x4xf32> into tensor<3072x256xf32> +// CHECK: %[[PACK:.+]] = tensor.pack %[[COLLAPSED]] +// CHECK: return %[[PACK]] : tensor<384x32x8x8xf32> + +// ----- + +func.func @push_down_unpack_through_expand(%5: tensor, %dim: index) -> tensor { + %6 = tensor.empty(%dim) : tensor + %unpack = tensor.unpack %5 outer_dims_perm = [0, 1] inner_dims_pos = [0, 1] inner_tiles = [8, 8] into %6 : tensor -> tensor + %expanded = tensor.expand_shape %unpack [[0, 1], [2]] : tensor into tensor + func.return %expanded : tensor +} +// CHECK-LABEL: func.func @push_down_unpack_through_expand +// CHECK-SAME: %[[ARG0:[a-zA-Z0-9]+]] +// CHECK-SAME: %[[ARG1:[a-zA-Z0-9]+]] +// CHECK: %[[C0:.+]] = arith.constant 0 : index +// CHECK: %[[EXPANDED:.+]] = tensor.expand_shape %[[ARG0]] {{\[}}[0, 1], [2], [3], [4]] : tensor into tensor +// CHECK: %[[DIM:.+]] = tensor.dim %[[EXPANDED]], %[[C0]] : tensor +// CHECK: %[[EMPTY:.+]] = tensor.empty(%[[DIM]]) : tensor +// CHECK: %[[UNPACK:.+]] = tensor.unpack %[[EXPANDED:.+]] outer_dims_perm = [0, 1, 2] inner_dims_pos = [1, 2] inner_tiles = [8, 8] into %[[EMPTY]] : tensor -> tensor +// CHECK: return %[[UNPACK]] : tensor + +// ----- + +func.func @push_down_permuted_unpack_through_expand(%5: tensor<4x32x384x8x8xf32>) -> tensor<4x12x256x256xf32> { + %6 = tensor.empty() : tensor<4x3072x256xf32> + %unpack = tensor.unpack %5 outer_dims_perm = [0, 2, 1] inner_dims_pos = [2, 1] inner_tiles = [8, 8] into %6 : tensor<4x32x384x8x8xf32> -> tensor<4x3072x256xf32> + %expanded = tensor.expand_shape %unpack [[0], [1, 2], [3]] : tensor<4x3072x256xf32> into tensor<4x12x256x256xf32> + func.return %expanded : tensor<4x12x256x256xf32> +} +// CHECK-LABEL: @push_down_permuted_unpack_through_expand +// CHECK-SAME: %[[ARG0:[a-zA-Z0-9]+]] +// CHECK: %[[EXPANDED:.+]] = tensor.expand_shape %[[ARG0]] {{\[}}[0], [1], [2, 3], [4], [5]] : tensor<4x32x384x8x8xf32> into tensor<4x32x12x32x8x8xf32> +// CHECK: %[[EMPTY:.+]] = tensor.empty() : tensor<4x12x256x256xf32> +// CHECK: %[[UNPACK:.+]] = tensor.unpack %[[EXPANDED]] outer_dims_perm = [0, 3, 1, 2] inner_dims_pos = [3, 2] inner_tiles = [8, 8] into %[[EMPTY]] : tensor<4x32x12x32x8x8xf32> -> tensor<4x12x256x256xf32> +// CHECK: return %[[UNPACK]] : tensor<4x12x256x256xf32> + +// ----- + +func.func @push_down_unpack_through_unit_expand(%5: tensor<6x32x8x8xf32>) -> tensor<3x16x1x256xf32> { + %6 = tensor.empty() : tensor<48x256xf32> + %unpack = tensor.unpack %5 outer_dims_perm = [0, 1] inner_dims_pos = [0, 1] inner_tiles = [8, 8] into %6 : tensor<6x32x8x8xf32> -> tensor<48x256xf32> + %expanded = tensor.expand_shape %unpack [[0, 1, 2], [3]] : tensor<48x256xf32> into tensor<3x16x1x256xf32> + func.return %expanded : tensor<3x16x1x256xf32> +} +// CHECK-LABEL: func.func @push_down_unpack_through_unit_expand +// CHECK-SAME: %[[ARG0:[a-zA-Z0-9]+]] +// CHECK: %[[EXPANDED:.+]] = tensor.expand_shape %[[ARG0]] {{\[}}[0, 1, 2], [3], [4], [5]] : tensor<6x32x8x8xf32> into tensor<3x2x1x32x8x8xf32> +// CHECK: %[[EMPTY:.+]] = tensor.empty() : tensor<3x16x1x256xf32> +// CHECK: %[[UNPACK:.+]] = tensor.unpack %[[EXPANDED]] outer_dims_perm = [0, 1, 2, 3] inner_dims_pos = [1, 3] inner_tiles = [8, 8] into %[[EMPTY]] : tensor<3x2x1x32x8x8xf32> -> tensor<3x16x1x256xf32> +// CHECK: return %[[UNPACK]] : tensor<3x16x1x256xf32> + +// ----- + +func.func @push_down_unpack_through_expand_on_outer_dims(%5: tensor, %dim: index) -> tensor { + %6 = tensor.empty(%dim) : tensor + %unpack = tensor.unpack %5 outer_dims_perm = [0, 1] inner_dims_pos = [1] inner_tiles = [8] into %6 : tensor -> tensor + %expanded = tensor.expand_shape %unpack [[0, 1], [2]] : tensor into tensor + func.return %expanded : tensor +} +// CHECK-LABEL: func.func @push_down_unpack_through_expand_on_outer_dims +// CHECK-SAME: %[[ARG0:[a-zA-Z0-9]+]] +// CHECK-SAME: %[[ARG1:[a-zA-Z0-9]+]] +// CHECK: %[[C0:.+]] = arith.constant 0 : index +// CHECK: %[[EXPANDED:.+]] = tensor.expand_shape %[[ARG0]] {{\[}}[0, 1], [2], [3]] : tensor into tensor +// CHECK: %[[DIM:.+]] = tensor.dim %[[EXPANDED]], %[[C0]] : tensor +// CHECK: %[[EMPTY:.+]] = tensor.empty(%[[DIM]]) : tensor +// CHECK: %[[UNPACK:.+]] = tensor.unpack %[[EXPANDED:.+]] outer_dims_perm = [0, 1, 2] inner_dims_pos = [2] inner_tiles = [8] into %[[EMPTY]] : tensor -> tensor +// CHECK: return %[[UNPACK]] : tensor + +// ----- + +func.func @no_push_down_unpack_through_non_divisible_expand(%5: tensor<384x32x8x8xf32>) -> tensor<256x12x256xf32> { + %6 = tensor.empty() : tensor<3072x256xf32> + %unpack = tensor.unpack %5 outer_dims_perm = [0, 1] inner_dims_pos = [0, 1] inner_tiles = [8, 8] into %6 : tensor<384x32x8x8xf32> -> tensor<3072x256xf32> + %expanded = tensor.expand_shape %unpack [[0, 1], [2]] : tensor<3072x256xf32> into tensor<256x12x256xf32> + func.return %expanded : tensor<256x12x256xf32> +} +// CHECK-LABEL: func.func @no_push_down_unpack_through_non_divisible_expand +// CHECK-SAME: %[[ARG0:[a-zA-Z0-9]+]] +// CHECK: %[[UNPACK:.+]] = tensor.unpack %[[ARG0]] +// CHECK: %[[EXPANDED:.+]] = tensor.expand_shape %[[UNPACK]] {{\[}}[0, 1], [2]] : tensor<3072x256xf32> into tensor<256x12x256xf32> +// CHECK: return %[[EXPANDED]] : tensor<256x12x256xf32> -- GitLab From 443baed56c770aca050d27581d5d6f0c5c168285 Mon Sep 17 00:00:00 2001 From: Fangrui Song Date: Wed, 27 Mar 2024 20:01:30 -0700 Subject: [PATCH 013/788] [ELF,test] Update tests that depend on --export-dynamic creating dynamic sections The CloudABI change from https://reviews.llvm.org/D30175 does not make sense. Update tests not to rely on the --export-dynamic behavior. --- lld/test/ELF/common-gc2.s | 8 +++++--- lld/test/ELF/executable-undefined-ignoreall.s | 2 -- .../ELF/relro-non-contiguous-script-data.s | 6 ++++-- lld/test/ELF/riscv-undefined-weak.s | 18 ++++++++---------- lld/test/ELF/x86-64-dyn-rel-error.s | 2 +- 5 files changed, 18 insertions(+), 18 deletions(-) diff --git a/lld/test/ELF/common-gc2.s b/lld/test/ELF/common-gc2.s index fec1c4be86b5..1ecaef7d9af5 100644 --- a/lld/test/ELF/common-gc2.s +++ b/lld/test/ELF/common-gc2.s @@ -1,7 +1,9 @@ # REQUIRES: x86 -# RUN: llvm-mc -filetype=obj -triple=x86_64-pc-linux %s -o %t -# RUN: ld.lld -gc-sections -export-dynamic %t -o %t1 -# RUN: llvm-readobj --dyn-symbols %t1 | FileCheck %s +# RUN: llvm-mc -filetype=obj -triple=x86_64 %s -o %t.o +# RUN: llvm-mc -filetype=obj -triple=x86_64 /dev/null -o %t2.o +# RUN: ld.lld -shared -soname=t2 %t2.o -o %t2.so +# RUN: ld.lld -gc-sections -export-dynamic %t.o %t2.so -o %t +# RUN: llvm-readobj --dyn-symbols %t | FileCheck %s # CHECK: Name: bar # CHECK: Name: foo diff --git a/lld/test/ELF/executable-undefined-ignoreall.s b/lld/test/ELF/executable-undefined-ignoreall.s index cc38e17cdf61..073b22bd8454 100644 --- a/lld/test/ELF/executable-undefined-ignoreall.s +++ b/lld/test/ELF/executable-undefined-ignoreall.s @@ -7,8 +7,6 @@ # RUN: llvm-mc -filetype=obj -triple=x86_64-unknown-linux %s -o %t.o # RUN: ld.lld %t.o -o %t --unresolved-symbols=ignore-all -pie # RUN: llvm-readobj -r %t | FileCheck %s -# RUN: ld.lld %t.o -o %t --unresolved-symbols=ignore-all --export-dynamic -# RUN: llvm-readobj -r %t | FileCheck %s # CHECK: Relocations [ # CHECK-NEXT: Section ({{.*}}) .rela.plt { diff --git a/lld/test/ELF/relro-non-contiguous-script-data.s b/lld/test/ELF/relro-non-contiguous-script-data.s index fd485e89167f..530fc7c84eb9 100644 --- a/lld/test/ELF/relro-non-contiguous-script-data.s +++ b/lld/test/ELF/relro-non-contiguous-script-data.s @@ -1,19 +1,21 @@ // REQUIRES: x86 +// RUN: llvm-mc -filetype=obj -triple=x86_64 /dev/null -o %t2.o +// RUN: ld.lld -shared -soname=t2 %t2.o -o %t2.so // RUN: echo "SECTIONS { \ // RUN: .dynamic : { *(.dynamic) } \ // RUN: .non_ro : { . += 1; } \ // RUN: .jcr : { *(.jcr) } \ // RUN: } " > %t.script // RUN: llvm-mc -filetype=obj -triple=x86_64-pc-linux %s -o %t.o -// RUN: not ld.lld --export-dynamic %t.o -o /dev/null --script=%t.script 2>&1 | FileCheck %s +// RUN: not ld.lld %t.o %t2.so -o /dev/null --script=%t.script 2>&1 | FileCheck %s // RUN: echo "SECTIONS { \ // RUN: .dynamic : { *(.dynamic) } \ // RUN: .non_ro : { BYTE(1); } \ // RUN: .jcr : { *(.jcr) } \ // RUN: } " > %t2.script -// RUN: not ld.lld --export-dynamic %t.o -o /dev/null --script=%t2.script 2>&1 | FileCheck %s +// RUN: not ld.lld %t.o %t2.so -o /dev/null --script=%t2.script 2>&1 | FileCheck %s // CHECK: error: section: .jcr is not contiguous with other relro sections diff --git a/lld/test/ELF/riscv-undefined-weak.s b/lld/test/ELF/riscv-undefined-weak.s index 303a27f920c5..8a78e1f83833 100644 --- a/lld/test/ELF/riscv-undefined-weak.s +++ b/lld/test/ELF/riscv-undefined-weak.s @@ -1,4 +1,6 @@ # REQUIRES: riscv +# RUN: llvm-mc -filetype=obj -triple=riscv64 /dev/null -o %t2.o +# RUN: ld.lld -shared -soname=t2 %t2.o -o %t2.so # RUN: llvm-mc -filetype=obj -triple=riscv64 -riscv-asm-relax-branches=0 %s -o %t.o # RUN: llvm-readobj -r %t.o | FileCheck --check-prefix=RELOC %s @@ -6,7 +8,7 @@ # RUN: llvm-objdump -d --no-show-raw-insn %t | FileCheck --check-prefixes=CHECK,PC %s # RUN: llvm-readelf -x .data %t | FileCheck --check-prefixes=HEX,HEX-WITHOUT-PLT %s -# RUN: ld.lld -e absolute %t.o -o %t --export-dynamic +# RUN: ld.lld -e absolute %t.o -o %t %t2.so # RUN: llvm-objdump -d --no-show-raw-insn %t | FileCheck --check-prefixes=CHECK,PLT %s # RUN: llvm-readelf -x .data %t | FileCheck --check-prefixes=HEX,HEX-WITH-PLT %s @@ -34,11 +36,11 @@ absolute: # CHECK-LABEL: : # CHECK-NEXT: 11{{...}}: auipc a1, 0xfffef # PC-NEXT: addi a1, a1, -0x160 -# PLT-NEXT: addi a1, a1, -0x318 +# PLT-NEXT: addi a1, a1, -0x290 # CHECK-LABEL: <.Lpcrel_hi1>: # CHECK-NEXT: 11{{...}}: auipc t1, 0xfffef # PC-NEXT: sd a2, -0x166(t1) -# PLT-NEXT: sd a2, -0x31e(t1) +# PLT-NEXT: sd a2, -0x296(t1) relative: la a1, target sd a2, target+2, t1 @@ -62,7 +64,7 @@ relative: ## We create a PLT entry and redirect the reference to it. # PLT-LABEL: : # PLT-NEXT: auipc ra, 0x0 -# PLT-NEXT: jalr 0x38(ra) +# PLT-NEXT: jalr 0x30(ra) # PLT-NEXT: [[#%x,ADDR:]]: # PLT-SAME: j 0x[[#ADDR]] # PLT-NEXT: [[#%x,ADDR:]]: @@ -84,12 +86,8 @@ branch: ## A plt entry is created for target, so this is the offset between the ## plt entry and this address. ## -## S = 0x11360 (the address of the plt entry for target) -## A = 0 -## P = 0x1343c (the address of `.`) -## -## S - A + P = -0x0x20dc = 0xffffdf24 -# HEX-WITH-PLT-SAME: 24dfffff +## S - A + P = -0x0x20ec = 0xffffdf14 +# HEX-WITH-PLT-SAME: 14dfffff .data .p2align 3 diff --git a/lld/test/ELF/x86-64-dyn-rel-error.s b/lld/test/ELF/x86-64-dyn-rel-error.s index a03adf89072f..1590045312d4 100644 --- a/lld/test/ELF/x86-64-dyn-rel-error.s +++ b/lld/test/ELF/x86-64-dyn-rel-error.s @@ -19,7 +19,7 @@ # CHECK-NOT: error: # RUN: ld.lld --noinhibit-exec %t.o %t2.so -o /dev/null 2>&1 | FileCheck --check-prefix=WARN %s -# RUN: not ld.lld --export-dynamic --unresolved-symbols=ignore-all %t.o -o /dev/null 2>&1 | FileCheck --check-prefix=WARN %s +# RUN: not ld.lld --export-dynamic --unresolved-symbols=ignore-all %t.o %t2.so -o /dev/null 2>&1 | FileCheck --check-prefix=WARN %s # WARN: relocation R_X86_64_32 cannot be used against symbol 'zed'; recompile with -fPIC # WARN: relocation R_X86_64_PC32 cannot be used against symbol 'zed'; recompile with -fPIC -- GitLab From 070d7af0c56b993806fa47f77b607b1849a2172f Mon Sep 17 00:00:00 2001 From: Fangrui Song Date: Wed, 27 Mar 2024 20:04:59 -0700 Subject: [PATCH 014/788] [ELF] --export-dynamic: don't create dynamic sections for non-PIC static links The CloudABI (removed from Clang Driver) change from https://reviews.llvm.org/D29982 does not make sense. GNU ld and gold don't create dynamic sections for a non-PIC static link when --export-dynamic is specified. Creating dynamic sections is harmful in this scenario because we would consider undefined weak symbols preemptible and generate GLOB_DAT relocations, breaking the expectation that non-PIC static links only contain IRELATIVE relocations. In addition, there are other options that export symbols (--export-dynamic-symbol, --dynamic-list, etc). It does not make sense to special case --export-dynamic. --- lld/ELF/Driver.cpp | 10 ++----- lld/test/ELF/static-with-export-dynamic.s | 32 ----------------------- lld/test/ELF/weak-undef.s | 9 ++++--- 3 files changed, 7 insertions(+), 44 deletions(-) delete mode 100644 lld/test/ELF/static-with-export-dynamic.s diff --git a/lld/ELF/Driver.cpp b/lld/ELF/Driver.cpp index f14a2376601b..b43da7727e22 100644 --- a/lld/ELF/Driver.cpp +++ b/lld/ELF/Driver.cpp @@ -2724,14 +2724,8 @@ template void LinkerDriver::link(opt::InputArgList &args) { parseFiles(files, armCmseImpLib); - // Now that we have every file, we can decide if we will need a - // dynamic symbol table. - // We need one if we were asked to export dynamic symbols or if we are - // producing a shared library. - // We also need one if any shared libraries are used and for pie executables - // (probably because the dynamic linker needs it). - config->hasDynSymTab = - !ctx.sharedFiles.empty() || config->isPic || config->exportDynamic; + // Create dynamic sections for dynamic linking and static PIE. + config->hasDynSymTab = !ctx.sharedFiles.empty() || config->isPic; script->addScriptReferencedSymbolsToSymTable(); diff --git a/lld/test/ELF/static-with-export-dynamic.s b/lld/test/ELF/static-with-export-dynamic.s deleted file mode 100644 index b0349b85e303..000000000000 --- a/lld/test/ELF/static-with-export-dynamic.s +++ /dev/null @@ -1,32 +0,0 @@ -// REQUIRES: x86 -// RUN: llvm-mc -filetype=obj -triple=i686-unknown-cloudabi %s -o %t.o -// RUN: ld.lld --export-dynamic %t.o -o %t -// RUN: llvm-readobj --dyn-syms %t | FileCheck %s - -// Ensure that a dynamic symbol table is present when --export-dynamic -// is passed in, even when creating statically linked executables. -// -// CHECK: DynamicSymbols [ -// CHECK-NEXT: Symbol { -// CHECK-NEXT: Name: -// CHECK-NEXT: Value: 0x0 -// CHECK-NEXT: Size: 0 -// CHECK-NEXT: Binding: Local -// CHECK-NEXT: Type: None -// CHECK-NEXT: Other: 0 -// CHECK-NEXT: Section: Undefined -// CHECK-NEXT: } -// CHECK-NEXT: Symbol { -// CHECK-NEXT: Name: _start -// CHECK-NEXT: Value: -// CHECK-NEXT: Size: 0 -// CHECK-NEXT: Binding: Global -// CHECK-NEXT: Type: None -// CHECK-NEXT: Other: 0 -// CHECK-NEXT: Section: .text -// CHECK-NEXT: } -// CHECK-NEXT: ] - -.global _start -_start: - ret diff --git a/lld/test/ELF/weak-undef.s b/lld/test/ELF/weak-undef.s index 3a9d5f462c21..21488023a79e 100644 --- a/lld/test/ELF/weak-undef.s +++ b/lld/test/ELF/weak-undef.s @@ -16,10 +16,11 @@ # RELOC-NEXT: Offset Info Type Symbol's Value Symbol's Name + Addend # RELOC-NEXT: {{.*}} 0000000100000001 R_X86_64_64 0000000000000000 foo + 0 -# COMMON: Symbol table '.dynsym' contains 2 entries: -# COMMON-NEXT: Num: Value Size Type Bind Vis Ndx Name -# COMMON-NEXT: 0: 0000000000000000 0 NOTYPE LOCAL DEFAULT UND -# COMMON-NEXT: 1: 0000000000000000 0 NOTYPE WEAK DEFAULT UND foo +# NORELOC-NOT: Symbol table '.dynsym' +# RELOC: Symbol table '.dynsym' contains 2 entries: +# RELOC-NEXT: Num: Value Size Type Bind Vis Ndx Name +# RELOC-NEXT: 0: 0000000000000000 0 NOTYPE LOCAL DEFAULT UND +# RELOC-NEXT: 1: 0000000000000000 0 NOTYPE WEAK DEFAULT UND foo # COMMON: Hex dump of section '.data': # COMMON-NEXT: {{.*}} 00000000 00000000 # COMMON-EMPTY: -- GitLab From 2c7610cc43cd70192a0ed5eac58471c50045c6de Mon Sep 17 00:00:00 2001 From: Mingming Liu Date: Wed, 27 Mar 2024 20:40:01 -0700 Subject: [PATCH 015/788] [nfc]Make InstrProfSymtab non-copyable and non-movable (#86882) - The direct use case (in [1]) is to add `llvm::IntervalMap` [2] and the allocator required by IntervalMap ctor [3] to class `InstrProfSymtab` as owned members. The allocator class doesn't have a move-assignment operator; and it's going to take much effort to implement move-assignment operator for the allocator class such that the enclosing class is movable. - There is only one use of compiler-generated move-assignment operator in the repo, which is in CoverageMappingReader.cpp. Luckily it's possible to use std::unique_ptr instead, so did the change. [1] https://github.com/llvm/llvm-project/pull/66825 [2] https://github.com/llvm/llvm-project/blob/4c2f68840e984b0f111779c46845ac00e3a7547d/llvm/include/llvm/ADT/IntervalMap.h#L936 [3] https://github.com/llvm/llvm-project/blob/4c2f68840e984b0f111779c46845ac00e3a7547d/llvm/include/llvm/ADT/IntervalMap.h#L1041 --- .../Coverage/CoverageMappingReader.h | 17 +++++---- llvm/include/llvm/ProfileData/InstrProf.h | 7 ++++ .../Coverage/CoverageMappingReader.cpp | 35 ++++++++++--------- 3 files changed, 34 insertions(+), 25 deletions(-) diff --git a/llvm/include/llvm/ProfileData/Coverage/CoverageMappingReader.h b/llvm/include/llvm/ProfileData/Coverage/CoverageMappingReader.h index 346ca4ad2eb3..f05b90114d75 100644 --- a/llvm/include/llvm/ProfileData/Coverage/CoverageMappingReader.h +++ b/llvm/include/llvm/ProfileData/Coverage/CoverageMappingReader.h @@ -184,7 +184,7 @@ public: private: std::vector Filenames; std::vector MappingRecords; - InstrProfSymtab ProfileNames; + std::unique_ptr ProfileNames; size_t CurrentRecord = 0; std::vector FunctionsFilenames; std::vector Expressions; @@ -195,8 +195,9 @@ private: // D69471, which can split up function records into multiple sections on ELF. FuncRecordsStorage FuncRecords; - BinaryCoverageReader(FuncRecordsStorage &&FuncRecords) - : FuncRecords(std::move(FuncRecords)) {} + BinaryCoverageReader(std::unique_ptr Symtab, + FuncRecordsStorage &&FuncRecords) + : ProfileNames(std::move(Symtab)), FuncRecords(std::move(FuncRecords)) {} public: BinaryCoverageReader(const BinaryCoverageReader &) = delete; @@ -209,12 +210,10 @@ public: SmallVectorImpl *BinaryIDs = nullptr); static Expected> - createCoverageReaderFromBuffer(StringRef Coverage, - FuncRecordsStorage &&FuncRecords, - InstrProfSymtab &&ProfileNames, - uint8_t BytesInAddress, - llvm::endianness Endian, - StringRef CompilationDir = ""); + createCoverageReaderFromBuffer( + StringRef Coverage, FuncRecordsStorage &&FuncRecords, + std::unique_ptr ProfileNamesPtr, uint8_t BytesInAddress, + llvm::endianness Endian, StringRef CompilationDir = ""); Error readNextRecord(CoverageMappingRecord &Record) override; }; diff --git a/llvm/include/llvm/ProfileData/InstrProf.h b/llvm/include/llvm/ProfileData/InstrProf.h index 25ec06a73920..612c444faec6 100644 --- a/llvm/include/llvm/ProfileData/InstrProf.h +++ b/llvm/include/llvm/ProfileData/InstrProf.h @@ -471,6 +471,13 @@ private: public: InstrProfSymtab() = default; + // Not copyable or movable. + // Consider std::unique_ptr for move. + InstrProfSymtab(const InstrProfSymtab &) = delete; + InstrProfSymtab &operator=(const InstrProfSymtab &) = delete; + InstrProfSymtab(InstrProfSymtab &&) = delete; + InstrProfSymtab &operator=(InstrProfSymtab &&) = delete; + /// Create InstrProfSymtab from an object file section which /// contains function PGO names. When section may contain raw /// string data or string data in compressed form. This method diff --git a/llvm/lib/ProfileData/Coverage/CoverageMappingReader.cpp b/llvm/lib/ProfileData/Coverage/CoverageMappingReader.cpp index d32846051083..445b48067a97 100644 --- a/llvm/lib/ProfileData/Coverage/CoverageMappingReader.cpp +++ b/llvm/lib/ProfileData/Coverage/CoverageMappingReader.cpp @@ -894,31 +894,34 @@ static Error readCoverageMappingData( Expected> BinaryCoverageReader::createCoverageReaderFromBuffer( StringRef Coverage, FuncRecordsStorage &&FuncRecords, - InstrProfSymtab &&ProfileNames, uint8_t BytesInAddress, + std::unique_ptr ProfileNamesPtr, uint8_t BytesInAddress, llvm::endianness Endian, StringRef CompilationDir) { - std::unique_ptr Reader( - new BinaryCoverageReader(std::move(FuncRecords))); - Reader->ProfileNames = std::move(ProfileNames); + if (ProfileNamesPtr == nullptr) + return make_error(coveragemap_error::malformed, + "Caller must provide ProfileNames"); + std::unique_ptr Reader(new BinaryCoverageReader( + std::move(ProfileNamesPtr), std::move(FuncRecords))); + InstrProfSymtab &ProfileNames = *Reader->ProfileNames; StringRef FuncRecordsRef = Reader->FuncRecords->getBuffer(); if (BytesInAddress == 4 && Endian == llvm::endianness::little) { if (Error E = readCoverageMappingData( - Reader->ProfileNames, Coverage, FuncRecordsRef, - Reader->MappingRecords, CompilationDir, Reader->Filenames)) + ProfileNames, Coverage, FuncRecordsRef, Reader->MappingRecords, + CompilationDir, Reader->Filenames)) return std::move(E); } else if (BytesInAddress == 4 && Endian == llvm::endianness::big) { if (Error E = readCoverageMappingData( - Reader->ProfileNames, Coverage, FuncRecordsRef, - Reader->MappingRecords, CompilationDir, Reader->Filenames)) + ProfileNames, Coverage, FuncRecordsRef, Reader->MappingRecords, + CompilationDir, Reader->Filenames)) return std::move(E); } else if (BytesInAddress == 8 && Endian == llvm::endianness::little) { if (Error E = readCoverageMappingData( - Reader->ProfileNames, Coverage, FuncRecordsRef, - Reader->MappingRecords, CompilationDir, Reader->Filenames)) + ProfileNames, Coverage, FuncRecordsRef, Reader->MappingRecords, + CompilationDir, Reader->Filenames)) return std::move(E); } else if (BytesInAddress == 8 && Endian == llvm::endianness::big) { if (Error E = readCoverageMappingData( - Reader->ProfileNames, Coverage, FuncRecordsRef, - Reader->MappingRecords, CompilationDir, Reader->Filenames)) + ProfileNames, Coverage, FuncRecordsRef, Reader->MappingRecords, + CompilationDir, Reader->Filenames)) return std::move(E); } else return make_error( @@ -963,8 +966,8 @@ loadTestingFormat(StringRef Data, StringRef CompilationDir) { if (Data.size() < ProfileNamesSize) return make_error(coveragemap_error::malformed, "the size of ProfileNames is too big"); - InstrProfSymtab ProfileNames; - if (Error E = ProfileNames.create(Data.substr(0, ProfileNamesSize), Address)) + auto ProfileNames = std::make_unique(); + if (Error E = ProfileNames->create(Data.substr(0, ProfileNamesSize), Address)) return std::move(E); Data = Data.substr(ProfileNamesSize); @@ -1099,7 +1102,7 @@ loadBinaryFormat(std::unique_ptr Bin, StringRef Arch, OF->isLittleEndian() ? llvm::endianness::little : llvm::endianness::big; // Look for the sections that we are interested in. - InstrProfSymtab ProfileNames; + auto ProfileNames = std::make_unique(); std::vector NamesSectionRefs; // If IPSK_name is not found, fallback to search for IPK_covname, which is // used when binary correlation is enabled. @@ -1116,7 +1119,7 @@ loadBinaryFormat(std::unique_ptr Bin, StringRef Arch, return make_error( coveragemap_error::malformed, "the size of coverage mapping section is not one"); - if (Error E = ProfileNames.create(NamesSectionRefs.back())) + if (Error E = ProfileNames->create(NamesSectionRefs.back())) return std::move(E); auto CoverageSection = lookupSections(*OF, IPSK_covmap); -- GitLab From 056b4043543cbc9e4ecad183db185bd26324b5b1 Mon Sep 17 00:00:00 2001 From: Job Henandez Lara Date: Wed, 27 Mar 2024 20:55:12 -0700 Subject: [PATCH 016/788] [libc][NFC] refactor fmin and fmax (#86718) Hello, So, I worked on the fmaximum and fminimum functions recently and the reviewers suggested the structure: ``` if (bitsx ...) return ...; if (bitsy ..) return ... return ...; ``` So I went ahead and did the same for fmin and fmax. I hope this isnt an issue for you all. thanks. --------- Co-authored-by: Job Hernandez --- libc/src/__support/FPUtil/BasicOperations.h | 24 +++++++++------------ 1 file changed, 10 insertions(+), 14 deletions(-) diff --git a/libc/src/__support/FPUtil/BasicOperations.h b/libc/src/__support/FPUtil/BasicOperations.h index f746d7ac6ad4..a47931bb3390 100644 --- a/libc/src/__support/FPUtil/BasicOperations.h +++ b/libc/src/__support/FPUtil/BasicOperations.h @@ -30,36 +30,32 @@ template , int> = 0> LIBC_INLINE T fmin(T x, T y) { const FPBits bitx(x), bity(y); - if (bitx.is_nan()) { + if (bitx.is_nan()) return y; - } else if (bity.is_nan()) { + if (bity.is_nan()) return x; - } else if (bitx.sign() != bity.sign()) { + if (bitx.sign() != bity.sign()) // To make sure that fmin(+0, -0) == -0 == fmin(-0, +0), whenever x and // y has different signs and both are not NaNs, we return the number // with negative sign. - return (bitx.is_neg()) ? x : y; - } else { - return (x < y ? x : y); - } + return bitx.is_neg() ? x : y; + return x < y ? x : y; } template , int> = 0> LIBC_INLINE T fmax(T x, T y) { FPBits bitx(x), bity(y); - if (bitx.is_nan()) { + if (bitx.is_nan()) return y; - } else if (bity.is_nan()) { + if (bity.is_nan()) return x; - } else if (bitx.sign() != bity.sign()) { + if (bitx.sign() != bity.sign()) // To make sure that fmax(+0, -0) == +0 == fmax(-0, +0), whenever x and // y has different signs and both are not NaNs, we return the number // with positive sign. - return (bitx.is_neg() ? y : x); - } else { - return (x > y ? x : y); - } + return bitx.is_neg() ? y : x; + return x > y ? x : y; } template , int> = 0> -- GitLab From e766f87b922933d6b1aefcfd24e5111162369e2e Mon Sep 17 00:00:00 2001 From: Owen Pan Date: Wed, 27 Mar 2024 21:22:57 -0700 Subject: [PATCH 017/788] [clang-format] Handle C++ Core Guidelines suppression tags (#86458) Fixes #86451. --- clang/lib/Format/TokenAnnotator.cpp | 4 ++++ clang/unittests/Format/FormatTest.cpp | 1 + 2 files changed, 5 insertions(+) diff --git a/clang/lib/Format/TokenAnnotator.cpp b/clang/lib/Format/TokenAnnotator.cpp index 4c83a7a3a323..b9144cf55452 100644 --- a/clang/lib/Format/TokenAnnotator.cpp +++ b/clang/lib/Format/TokenAnnotator.cpp @@ -4827,6 +4827,10 @@ bool TokenAnnotator::spaceRequiredBefore(const AnnotatedLine &Line, Right.is(TT_TemplateOpener)) { return true; } + if (Left.is(tok::identifier) && Right.is(tok::numeric_constant) && + Right.TokenText[0] == '.') { + return false; + } } else if (Style.isProto()) { if (Right.is(tok::period) && Left.isOneOf(Keywords.kw_optional, Keywords.kw_required, diff --git a/clang/unittests/Format/FormatTest.cpp b/clang/unittests/Format/FormatTest.cpp index d1e977dfa66a..33dec7dae319 100644 --- a/clang/unittests/Format/FormatTest.cpp +++ b/clang/unittests/Format/FormatTest.cpp @@ -12075,6 +12075,7 @@ TEST_F(FormatTest, UnderstandsSquareAttributes) { verifyFormat("SomeType s [[gnu::unused]] (InitValue);"); verifyFormat("SomeType s [[using gnu: unused]] (InitValue);"); verifyFormat("[[gsl::suppress(\"clang-tidy-check-name\")]] void f() {}"); + verifyFormat("[[suppress(type.5)]] int uninitialized_on_purpose;"); verifyFormat("void f() [[deprecated(\"so sorry\")]];"); verifyFormat("aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa\n" " [[unused]] aaaaaaaaaaaaaaaaaaaaaaa(int i);"); -- GitLab From d9e3e11ae57612ec61f6fcab4afc27d8d0ff5841 Mon Sep 17 00:00:00 2001 From: Owen Pan Date: Wed, 27 Mar 2024 21:23:37 -0700 Subject: [PATCH 018/788] [clang-format] Exit clang-format-diff only after all diffs are printed (#86776) See https://github.com/llvm/llvm-project/pull/70883#issuecomment-2020811077. --- clang/tools/clang-format/clang-format-diff.py | 10 +++++++--- 1 file changed, 7 insertions(+), 3 deletions(-) diff --git a/clang/tools/clang-format/clang-format-diff.py b/clang/tools/clang-format/clang-format-diff.py index 0a2c24743678..3a74b90e7315 100755 --- a/clang/tools/clang-format/clang-format-diff.py +++ b/clang/tools/clang-format/clang-format-diff.py @@ -138,6 +138,7 @@ def main(): ) # Reformat files containing changes in place. + has_diff = False for filename, lines in lines_by_file.items(): if args.i and args.verbose: print("Formatting {}".format(filename)) @@ -169,7 +170,7 @@ def main(): stdout, stderr = p.communicate() if p.returncode != 0: - sys.exit(p.returncode) + return p.returncode if not args.i: with open(filename) as f: @@ -185,9 +186,12 @@ def main(): ) diff_string = "".join(diff) if len(diff_string) > 0: + has_diff = True sys.stdout.write(diff_string) - sys.exit(1) + + if has_diff: + return 1 if __name__ == "__main__": - main() + sys.exit(main()) -- GitLab From 6b7ecc7979134c152ee5f8286f904bba18f41185 Mon Sep 17 00:00:00 2001 From: Heejin Ahn Date: Thu, 28 Mar 2024 04:41:29 +0000 Subject: [PATCH 019/788] Revert "[WebAssembly] Remove threwValue comparison after __wasm_setjmp_test (#86633)" This reverts commit 52431fdb1ab8d29be078edd55250e06381e4b6b0. The PR assumed `__threwValue` couldn't be 0, but it could be when the thrown thing is not a longjmp but an exception, so that `if` check was actually necessary. --- .../WebAssembly/WebAssemblyLowerEmscriptenEHSjLj.cpp | 8 +++++--- llvm/test/CodeGen/WebAssembly/lower-em-ehsjlj.ll | 7 ++++--- llvm/test/CodeGen/WebAssembly/lower-em-sjlj.ll | 4 +++- 3 files changed, 12 insertions(+), 7 deletions(-) diff --git a/llvm/lib/Target/WebAssembly/WebAssemblyLowerEmscriptenEHSjLj.cpp b/llvm/lib/Target/WebAssembly/WebAssemblyLowerEmscriptenEHSjLj.cpp index 0788d0c3a721..027ee1086bf4 100644 --- a/llvm/lib/Target/WebAssembly/WebAssemblyLowerEmscriptenEHSjLj.cpp +++ b/llvm/lib/Target/WebAssembly/WebAssemblyLowerEmscriptenEHSjLj.cpp @@ -153,7 +153,7 @@ /// %__THREW__.val = __THREW__; /// __THREW__ = 0; /// %__threwValue.val = __threwValue; -/// if (%__THREW__.val != 0) { +/// if (%__THREW__.val != 0 & %__threwValue.val != 0) { /// %label = __wasm_setjmp_test(%__THREW__.val, functionInvocationId); /// if (%label == 0) /// emscripten_longjmp(%__THREW__.val, %__threwValue.val); @@ -712,10 +712,12 @@ void WebAssemblyLowerEmscriptenEHSjLj::wrapTestSetjmp( BasicBlock *ThenBB1 = BasicBlock::Create(C, "if.then1", F); BasicBlock *ElseBB1 = BasicBlock::Create(C, "if.else1", F); BasicBlock *EndBB1 = BasicBlock::Create(C, "if.end", F); + Value *ThrewCmp = IRB.CreateICmpNE(Threw, getAddrSizeInt(M, 0)); Value *ThrewValue = IRB.CreateLoad(IRB.getInt32Ty(), ThrewValueGV, ThrewValueGV->getName() + ".val"); - Value *ThrewCmp = IRB.CreateICmpNE(Threw, getAddrSizeInt(M, 0)); - IRB.CreateCondBr(ThrewCmp, ThenBB1, ElseBB1); + Value *ThrewValueCmp = IRB.CreateICmpNE(ThrewValue, IRB.getInt32(0)); + Value *Cmp1 = IRB.CreateAnd(ThrewCmp, ThrewValueCmp, "cmp1"); + IRB.CreateCondBr(Cmp1, ThenBB1, ElseBB1); // Generate call.em.longjmp BB once and share it within the function if (!CallEmLongjmpBB) { diff --git a/llvm/test/CodeGen/WebAssembly/lower-em-ehsjlj.ll b/llvm/test/CodeGen/WebAssembly/lower-em-ehsjlj.ll index d88f42a4dc58..32942cd92e68 100644 --- a/llvm/test/CodeGen/WebAssembly/lower-em-ehsjlj.ll +++ b/llvm/test/CodeGen/WebAssembly/lower-em-ehsjlj.ll @@ -22,8 +22,10 @@ entry: to label %try.cont unwind label %lpad ; CHECK: entry.split.split: -; CHECK: %__threwValue.val = load i32, ptr @__threwValue -; CHECK-NEXT: %[[CMP:.*]] = icmp ne i32 %__THREW__.val, 0 +; CHECK: %[[CMP0:.*]] = icmp ne i32 %__THREW__.val, 0 +; CHECK-NEXT: %__threwValue.val = load i32, ptr @__threwValue +; CHECK-NEXT: %[[CMP1:.*]] = icmp ne i32 %__threwValue.val, 0 +; CHECK-NEXT: %[[CMP:.*]] = and i1 %[[CMP0]], %[[CMP1]] ; CHECK-NEXT: br i1 %[[CMP]], label %if.then1, label %if.else1 ; This is exception checking part. %if.else1 leads here @@ -119,7 +121,6 @@ if.end: ; preds = %entry ; CHECK-NEXT: unreachable ; CHECK: normal: -; CHECK-NEXT: %__threwValue.val = load i32, ptr @__threwValue, align 4 ; CHECK-NEXT: icmp ne i32 %__THREW__.val, 0 return: ; preds = %if.end, %entry diff --git a/llvm/test/CodeGen/WebAssembly/lower-em-sjlj.ll b/llvm/test/CodeGen/WebAssembly/lower-em-sjlj.ll index dca4c59d7c87..27ec95a2c462 100644 --- a/llvm/test/CodeGen/WebAssembly/lower-em-sjlj.ll +++ b/llvm/test/CodeGen/WebAssembly/lower-em-sjlj.ll @@ -37,8 +37,10 @@ entry: ; CHECK-NEXT: call cc{{.*}} void @__invoke_void_[[PTR]]_i32(ptr @emscripten_longjmp, [[PTR]] %[[JMPBUF]], i32 1) ; CHECK-NEXT: %[[__THREW__VAL:.*]] = load [[PTR]], ptr @__THREW__ ; CHECK-NEXT: store [[PTR]] 0, ptr @__THREW__ +; CHECK-NEXT: %[[CMP0:.*]] = icmp ne [[PTR]] %__THREW__.val, 0 ; CHECK-NEXT: %[[THREWVALUE_VAL:.*]] = load i32, ptr @__threwValue -; CHECK-NEXT: %[[CMP:.*]] = icmp ne [[PTR]] %__THREW__.val, 0 +; CHECK-NEXT: %[[CMP1:.*]] = icmp ne i32 %[[THREWVALUE_VAL]], 0 +; CHECK-NEXT: %[[CMP:.*]] = and i1 %[[CMP0]], %[[CMP1]] ; CHECK-NEXT: br i1 %[[CMP]], label %if.then1, label %if.else1 ; CHECK: entry.split.split.split: -- GitLab From a41bfea5c049737e9c51e8d9a5769f72fbc55f59 Mon Sep 17 00:00:00 2001 From: Fangrui Song Date: Wed, 27 Mar 2024 22:10:11 -0700 Subject: [PATCH 020/788] [MC] Simplify ELFObjectWriter. NFC And fix `if (hasRelocationAddend())` to `usesRela` to properly treat SHT_LLVM_CALL_GRAPH_PROFILE as SHT_REL. The incorrect does not cause a problem because the synthesized SHT_LLVM_CALL_GRAPH_PROFILE has zero addends. --- llvm/lib/MC/ELFObjectWriter.cpp | 36 ++++++++++++++++----------------- 1 file changed, 17 insertions(+), 19 deletions(-) diff --git a/llvm/lib/MC/ELFObjectWriter.cpp b/llvm/lib/MC/ELFObjectWriter.cpp index f4c6cbc8dd44..005521bad6e0 100644 --- a/llvm/lib/MC/ELFObjectWriter.cpp +++ b/llvm/lib/MC/ELFObjectWriter.cpp @@ -141,7 +141,6 @@ struct ELFWriter { // TargetObjectWriter wrappers. bool is64Bit() const; - bool usesRela(const MCSectionELF &Sec) const; uint64_t align(Align Alignment); @@ -260,6 +259,7 @@ public: void recordRelocation(MCAssembler &Asm, const MCAsmLayout &Layout, const MCFragment *Fragment, const MCFixup &Fixup, MCValue Target, uint64_t &FixedValue) override; + bool usesRela(const MCSectionELF &Sec) const; void executePostLayoutBinding(MCAssembler &Asm, const MCAsmLayout &Layout) override; @@ -394,11 +394,6 @@ bool ELFWriter::is64Bit() const { return OWriter.TargetObjectWriter->is64Bit(); } -bool ELFWriter::usesRela(const MCSectionELF &Sec) const { - return OWriter.hasRelocationAddend() && - Sec.getType() != ELF::SHT_LLVM_CALL_GRAPH_PROFILE; -} - // Emit the ELF header. void ELFWriter::writeHeader(const MCAssembler &Asm) { // ELF Header @@ -825,24 +820,22 @@ MCSectionELF *ELFWriter::createRelocationSection(MCContext &Ctx, if (OWriter.Relocations[&Sec].empty()) return nullptr; - const StringRef SectionName = Sec.getName(); - bool Rela = usesRela(Sec); - std::string RelaSectionName = Rela ? ".rela" : ".rel"; - RelaSectionName += SectionName; + unsigned Flags = ELF::SHF_INFO_LINK; + if (Sec.getFlags() & ELF::SHF_GROUP) + Flags = ELF::SHF_GROUP; + const StringRef SectionName = Sec.getName(); + const bool Rela = OWriter.usesRela(Sec); unsigned EntrySize; if (Rela) EntrySize = is64Bit() ? sizeof(ELF::Elf64_Rela) : sizeof(ELF::Elf32_Rela); else EntrySize = is64Bit() ? sizeof(ELF::Elf64_Rel) : sizeof(ELF::Elf32_Rel); - unsigned Flags = ELF::SHF_INFO_LINK; - if (Sec.getFlags() & ELF::SHF_GROUP) - Flags = ELF::SHF_GROUP; - - MCSectionELF *RelaSection = Ctx.createELFRelSection( - RelaSectionName, Rela ? ELF::SHT_RELA : ELF::SHT_REL, Flags, EntrySize, - Sec.getGroup(), &Sec); + MCSectionELF *RelaSection = + Ctx.createELFRelSection(((Rela ? ".rela" : ".rel") + SectionName), + Rela ? ELF::SHT_RELA : ELF::SHT_REL, Flags, + EntrySize, Sec.getGroup(), &Sec); RelaSection->setAlignment(is64Bit() ? Align(8) : Align(4)); return RelaSection; } @@ -938,11 +931,11 @@ void ELFWriter::WriteSecHdrEntry(uint32_t Name, uint32_t Type, uint64_t Flags, void ELFWriter::writeRelocations(const MCAssembler &Asm, const MCSectionELF &Sec) { std::vector &Relocs = OWriter.Relocations[&Sec]; + const bool Rela = OWriter.usesRela(Sec); // Sort the relocation entries. MIPS needs this. OWriter.TargetObjectWriter->sortRelocs(Asm, Relocs); - const bool Rela = usesRela(Sec); if (OWriter.TargetObjectWriter->getEMachine() == ELF::EM_MIPS) { for (const ELFRelocationEntry &Entry : Relocs) { uint32_t Symidx = Entry.Symbol ? Entry.Symbol->getIndex() : 0; @@ -1499,7 +1492,7 @@ void ELFObjectWriter::recordRelocation(MCAssembler &Asm, FixedValue = !RelocateWithSymbol && SymA && !SymA->isUndefined() ? C + Layout.getSymbolOffset(*SymA) : C; - if (hasRelocationAddend()) { + if (usesRela(FixupSection)) { Addend = FixedValue; FixedValue = 0; } @@ -1528,6 +1521,11 @@ void ELFObjectWriter::recordRelocation(MCAssembler &Asm, Relocations[&FixupSection].push_back(Rec); } +bool ELFObjectWriter::usesRela(const MCSectionELF &Sec) const { + return hasRelocationAddend() && + Sec.getType() != ELF::SHT_LLVM_CALL_GRAPH_PROFILE; +} + bool ELFObjectWriter::isSymbolRefDifferenceFullyResolvedImpl( const MCAssembler &Asm, const MCSymbol &SA, const MCFragment &FB, bool InSet, bool IsPCRel) const { -- GitLab From f8bab38b6dd02f2cd3acc28521d0ccb3186ef616 Mon Sep 17 00:00:00 2001 From: Lei Wang Date: Wed, 27 Mar 2024 22:27:22 -0700 Subject: [PATCH 021/788] [CSSPGO] Fix the issue of missing callee profile matches (#85715) Two fixes related to the callee/inlinee profile: 1. Fix the bug that the matching results are missing to distribute to the callee profiles (should be pass-by-reference). 2. Narrow imported function matching to checksum mismatched functions. More context: before we run matchings for all imported functions even checksums are matched, however, after we fix 1), we got a regression, it's likely due to the matching is not no-op for checksum matched function, so we want to make it consistent to only run matching for checksum mismatched (imported)functions. Since the metadata(pseudo_probe_desc) are dropped for imported function, we leverage the function attribute mechanism and add a new function attribute(`profile-checksum-mismatch`) to transfer the info from pre-link to post-link. --- .../Utils/SampleProfileLoaderBaseImpl.h | 25 +++---- llvm/lib/Transforms/IPO/SampleProfile.cpp | 46 +++++++++---- .../pseudo-probe-callee-profile-mismatch.prof | 16 +++++ .../csspgo-profile-checksum-mismatch-attr.ll | 67 +++++++++++++++++++ .../pseudo-probe-callee-profile-mismatch.ll | 63 +++++++++++++++++ ...pseudo-probe-stale-profile-matching-lto.ll | 2 +- .../pseudo-probe-stale-profile-matching.ll | 2 + 7 files changed, 194 insertions(+), 27 deletions(-) create mode 100644 llvm/test/Transforms/SampleProfile/Inputs/pseudo-probe-callee-profile-mismatch.prof create mode 100644 llvm/test/Transforms/SampleProfile/csspgo-profile-checksum-mismatch-attr.ll create mode 100644 llvm/test/Transforms/SampleProfile/pseudo-probe-callee-profile-mismatch.ll diff --git a/llvm/include/llvm/Transforms/Utils/SampleProfileLoaderBaseImpl.h b/llvm/include/llvm/Transforms/Utils/SampleProfileLoaderBaseImpl.h index 66814d395273..bd7496a799c5 100644 --- a/llvm/include/llvm/Transforms/Utils/SampleProfileLoaderBaseImpl.h +++ b/llvm/include/llvm/Transforms/Utils/SampleProfileLoaderBaseImpl.h @@ -86,9 +86,12 @@ template <> struct IRTraits { // SampleProfileProber. class PseudoProbeManager { DenseMap GUIDToProbeDescMap; + const ThinOrFullLTOPhase LTOPhase; public: - PseudoProbeManager(const Module &M) { + PseudoProbeManager(const Module &M, + ThinOrFullLTOPhase LTOPhase = ThinOrFullLTOPhase::None) + : LTOPhase(LTOPhase) { if (NamedMDNode *FuncInfo = M.getNamedMetadata(PseudoProbeDescMetadataName)) { for (const auto *Operand : FuncInfo->operands()) { @@ -126,17 +129,15 @@ public: bool profileIsValid(const Function &F, const FunctionSamples &Samples) const { const auto *Desc = getDesc(F); - if (!Desc) { - LLVM_DEBUG(dbgs() << "Probe descriptor missing for Function " - << F.getName() << "\n"); - return false; - } - if (Desc->getFunctionHash() != Samples.getFunctionHash()) { - LLVM_DEBUG(dbgs() << "Hash mismatch for Function " << F.getName() - << "\n"); - return false; - } - return true; + assert((LTOPhase != ThinOrFullLTOPhase::ThinLTOPostLink || !Desc || + profileIsHashMismatched(*Desc, Samples) == + F.hasFnAttribute("profile-checksum-mismatch")) && + "In post-link, profile checksum matching state doesn't match " + "function 'profile-checksum-mismatch' attribute."); + // The desc for import function is unavailable. Check the function attribute + // for mismatch. + return (!Desc && !F.hasFnAttribute("profile-checksum-mismatch")) || + (Desc && !profileIsHashMismatched(*Desc, Samples)); } }; diff --git a/llvm/lib/Transforms/IPO/SampleProfile.cpp b/llvm/lib/Transforms/IPO/SampleProfile.cpp index 2cbef8a7ae61..7545a92c114e 100644 --- a/llvm/lib/Transforms/IPO/SampleProfile.cpp +++ b/llvm/lib/Transforms/IPO/SampleProfile.cpp @@ -453,6 +453,7 @@ class SampleProfileMatcher { Module &M; SampleProfileReader &Reader; const PseudoProbeManager *ProbeManager; + const ThinOrFullLTOPhase LTOPhase; SampleProfileMap FlattenedProfiles; // For each function, the matcher generates a map, of which each entry is a // mapping from the source location of current build to the source location in @@ -504,8 +505,9 @@ class SampleProfileMatcher { public: SampleProfileMatcher(Module &M, SampleProfileReader &Reader, - const PseudoProbeManager *ProbeManager) - : M(M), Reader(Reader), ProbeManager(ProbeManager){}; + const PseudoProbeManager *ProbeManager, + ThinOrFullLTOPhase LTOPhase) + : M(M), Reader(Reader), ProbeManager(ProbeManager), LTOPhase(LTOPhase){}; void runOnModule(); void clearMatchingData() { // Do not clear FuncMappings, it stores IRLoc to ProfLoc remappings which @@ -521,7 +523,7 @@ private: return &It->second; return nullptr; } - void runOnFunction(const Function &F); + void runOnFunction(Function &F); void findIRAnchors(const Function &F, std::map &IRAnchors); void findProfileAnchors( @@ -1911,15 +1913,22 @@ bool SampleProfileLoader::emitAnnotations(Function &F) { bool Changed = false; if (FunctionSamples::ProfileIsProbeBased) { - if (!ProbeManager->profileIsValid(F, *Samples)) { + LLVM_DEBUG({ + if (!ProbeManager->getDesc(F)) + dbgs() << "Probe descriptor missing for Function " << F.getName() + << "\n"; + }); + + if (ProbeManager->profileIsValid(F, *Samples)) { + ++NumMatchedProfile; + } else { + ++NumMismatchedProfile; LLVM_DEBUG( dbgs() << "Profile is invalid due to CFG mismatch for Function " << F.getName() << "\n"); - ++NumMismatchedProfile; if (!SalvageStaleProfile) return false; } - ++NumMatchedProfile; } else { if (getFunctionLoc(F) == 0) return false; @@ -2185,7 +2194,7 @@ bool SampleProfileLoader::doInitialization(Module &M, // Load pseudo probe descriptors for probe-based function samples. if (Reader->profileIsProbeBased()) { - ProbeManager = std::make_unique(M); + ProbeManager = std::make_unique(M, LTOPhase); if (!ProbeManager->moduleIsProbed(M)) { const char *Msg = "Pseudo-probe-based profile requires SampleProfileProbePass"; @@ -2197,8 +2206,8 @@ bool SampleProfileLoader::doInitialization(Module &M, if (ReportProfileStaleness || PersistProfileStaleness || SalvageStaleProfile) { - MatchingManager = - std::make_unique(M, *Reader, ProbeManager.get()); + MatchingManager = std::make_unique( + M, *Reader, ProbeManager.get(), LTOPhase); } return true; @@ -2452,7 +2461,7 @@ void SampleProfileMatcher::runStaleProfileMatching( } } -void SampleProfileMatcher::runOnFunction(const Function &F) { +void SampleProfileMatcher::runOnFunction(Function &F) { // We need to use flattened function samples for matching. // Unlike IR, which includes all callsites from the source code, the callsites // in profile only show up when they are hit by samples, i,e. the profile @@ -2481,8 +2490,16 @@ void SampleProfileMatcher::runOnFunction(const Function &F) { // support for pseudo-probe. if (SalvageStaleProfile && FunctionSamples::ProfileIsProbeBased && !ProbeManager->profileIsValid(F, *FSFlattened)) { - // The matching result will be saved to IRToProfileLocationMap, create a new - // map for each function. + // For imported functions, the checksum metadata(pseudo_probe_desc) are + // dropped, so we leverage function attribute(profile-checksum-mismatch) to + // transfer the info: add the attribute during pre-link phase and check it + // during post-link phase(see "profileIsValid"). + if (FunctionSamples::ProfileIsProbeBased && + LTOPhase == ThinOrFullLTOPhase::ThinLTOPreLink) + F.addFnAttr("profile-checksum-mismatch"); + + // The matching result will be saved to IRToProfileLocationMap, create a + // new map for each function. auto &IRToProfileLocationMap = getIRToProfileLocationMap(F); runStaleProfileMatching(F, IRAnchors, ProfileAnchors, IRToProfileLocationMap); @@ -2758,8 +2775,9 @@ void SampleProfileMatcher::distributeIRToProfileLocationMap( FS.setIRToProfileLocationMap(&(ProfileMappings->second)); } - for (auto &Inlinees : FS.getCallsiteSamples()) { - for (auto FS : Inlinees.second) { + for (auto &Callees : + const_cast(FS.getCallsiteSamples())) { + for (auto &FS : Callees.second) { distributeIRToProfileLocationMap(FS.second); } } diff --git a/llvm/test/Transforms/SampleProfile/Inputs/pseudo-probe-callee-profile-mismatch.prof b/llvm/test/Transforms/SampleProfile/Inputs/pseudo-probe-callee-profile-mismatch.prof new file mode 100644 index 000000000000..76a8fc9d19a8 --- /dev/null +++ b/llvm/test/Transforms/SampleProfile/Inputs/pseudo-probe-callee-profile-mismatch.prof @@ -0,0 +1,16 @@ +main:252:0 + 1: 0 + 2: 50 + 5: 50 + 7: bar:102 + 1: 51 + 2: baz:51 + 1: 51 + !CFGChecksum: 4294967295 + !Attributes: 3 + !CFGChecksum: 281479271677951 + !Attributes: 2 + !CFGChecksum: 281582081721716 +bar:1:1 + 1: 1 + !CFGChecksum: 281479271677951 diff --git a/llvm/test/Transforms/SampleProfile/csspgo-profile-checksum-mismatch-attr.ll b/llvm/test/Transforms/SampleProfile/csspgo-profile-checksum-mismatch-attr.ll new file mode 100644 index 000000000000..df56b55dcdf3 --- /dev/null +++ b/llvm/test/Transforms/SampleProfile/csspgo-profile-checksum-mismatch-attr.ll @@ -0,0 +1,67 @@ +; REQUIRES: x86_64-linux +; REQUIRES: asserts +; RUN: opt < %s -passes='thinlto-pre-link' -pgo-kind=pgo-sample-use-pipeline -sample-profile-file=%S/Inputs/pseudo-probe-callee-profile-mismatch.prof -pass-remarks=inline -S -o %t 2>&1 | FileCheck %s --check-prefix=INLINE +; RUN: FileCheck %s < %t +; RUN: FileCheck %s < %t --check-prefix=MERGE + + +; Make sure bar is inlined into main for attr merging verification. +; INLINE: 'bar' inlined into 'main' + +target datalayout = "e-m:e-p270:32:32-p271:32:32-p272:64:64-i64:64-i128:128-f80:128-n8:16:32:64-S128" +target triple = "x86_64-unknown-linux-gnu" + +define i32 @baz() #0 { +entry: + ret i32 0 +} + +define i32 @bar() #0 !dbg !11 { +; CHECK: define {{.*}} @bar() {{.*}} #[[#BAR_ATTR:]] ! +entry: + %call = call i32 @baz() + ret i32 0 +} + +define i32 @main() #0 { +; MERGE: define {{.*}} @main() {{.*}} #[[#MAIN_ATTR:]] ! +entry: + br label %for.cond + +for.cond: ; preds = %for.cond, %entry + %call = call i32 @bar(), !dbg !14 + br label %for.cond +} + +; CHECK: attributes #[[#BAR_ATTR]] = {{{.*}} "profile-checksum-mismatch" {{.*}}} + +; Verify the attribute is not merged into the caller. +; MERGE-NOT: attributes #[[#MAIN_ATTR]] = {{{.*}} "profile-checksum-mismatch" {{.*}}} + +attributes #0 = { "use-sample-profile" } + +!llvm.dbg.cu = !{!0} +!llvm.module.flags = !{!7} +!llvm.pseudo_probe_desc = !{!8, !9, !10} + +!0 = distinct !DICompileUnit(language: DW_LANG_C11, file: !1, producer: "clang version 19.0.0", isOptimized: true, runtimeVersion: 0, emissionKind: FullDebug, globals: !2, splitDebugInlining: false, nameTableKind: None) +!1 = !DIFile(filename: "test.c", directory: "/home", checksumkind: CSK_MD5, checksum: "0df0c950a93a603a7d13f0a9d4623642") +!2 = !{!3} +!3 = !DIGlobalVariableExpression(var: !4, expr: !DIExpression()) +!4 = distinct !DIGlobalVariable(name: "x", scope: !0, file: !1, line: 2, type: !5, isLocal: false, isDefinition: true) +!5 = !DIDerivedType(tag: DW_TAG_volatile_type, baseType: !6) +!6 = !DIBasicType(name: "int", size: 32, encoding: DW_ATE_signed) +!7 = !{i32 2, !"Debug Info Version", i32 3} +!8 = !{i64 7546896869197086323, i64 4294967295, !"baz"} +!9 = !{i64 -2012135647395072713, i64 281530612780802, !"bar"} +!10 = !{i64 -2624081020897602054, i64 281582081721716, !"main"} +!11 = distinct !DISubprogram(name: "bar", scope: !1, file: !1, line: 5, type: !12, scopeLine: 5, flags: DIFlagPrototyped | DIFlagAllCallsDescribed, spFlags: DISPFlagDefinition | DISPFlagOptimized, unit: !0, retainedNodes: !13) +!12 = distinct !DISubroutineType(types: !13) +!13 = !{} +!14 = !DILocation(line: 15, column: 10, scope: !15) +!15 = !DILexicalBlockFile(scope: !16, file: !1, discriminator: 186646591) +!16 = distinct !DILexicalBlock(scope: !17, file: !1, line: 14, column: 40) +!17 = distinct !DILexicalBlock(scope: !18, file: !1, line: 14, column: 3) +!18 = distinct !DILexicalBlock(scope: !19, file: !1, line: 14, column: 3) +!19 = distinct !DISubprogram(name: "main", scope: !1, file: !1, line: 12, type: !20, scopeLine: 13, flags: DIFlagAllCallsDescribed, spFlags: DISPFlagDefinition | DISPFlagOptimized, unit: !0, retainedNodes: !13) +!20 = !DISubroutineType(types: !13) diff --git a/llvm/test/Transforms/SampleProfile/pseudo-probe-callee-profile-mismatch.ll b/llvm/test/Transforms/SampleProfile/pseudo-probe-callee-profile-mismatch.ll new file mode 100644 index 000000000000..e00b737cae4e --- /dev/null +++ b/llvm/test/Transforms/SampleProfile/pseudo-probe-callee-profile-mismatch.ll @@ -0,0 +1,63 @@ +; REQUIRES: x86_64-linux +; REQUIRES: asserts +; RUN: opt < %s -passes=sample-profile -sample-profile-file=%S/Inputs/pseudo-probe-callee-profile-mismatch.prof --salvage-stale-profile -S --debug-only=sample-profile,sample-profile-impl -pass-remarks=inline 2>&1 | FileCheck %s + + +; CHECK: Run stale profile matching for bar +; CHECK: Callsite with callee:baz is matched from 4 to 2 +; CHECK: 'baz' inlined into 'main' to match profiling context with (cost=always): preinliner at callsite bar:3:8.4 @ main:3:10.7 + +; CHECK: Probe descriptor missing for Function bar +; CHECK: Profile is invalid due to CFG mismatch for Function bar + + +target datalayout = "e-m:e-p270:32:32-p271:32:32-p272:64:64-i64:64-i128:128-f80:128-n8:16:32:64-S128" +target triple = "x86_64-unknown-linux-gnu" + +define i32 @main() #0 { + %1 = call i32 @bar(), !dbg !13 + ret i32 0 +} + +define available_externally i32 @bar() #1 !dbg !21 { + %1 = call i32 @baz(), !dbg !23 + ret i32 0 +} + +define available_externally i32 @baz() #0 !dbg !25 { + ret i32 0 +} + +attributes #0 = { "use-sample-profile" } +attributes #1 = { "profile-checksum-mismatch" "use-sample-profile" } + +!llvm.dbg.cu = !{!0, !7, !9} +!llvm.module.flags = !{!11} +!llvm.pseudo_probe_desc = !{!12} + +!0 = distinct !DICompileUnit(language: DW_LANG_C11, file: !1, producer: "clang version 19.0.0", isOptimized: true, runtimeVersion: 0, emissionKind: FullDebug, globals: !2, splitDebugInlining: false, nameTableKind: None) +!1 = !DIFile(filename: "test.c", directory: "/home/test", checksumkind: CSK_MD5, checksum: "7220f1a2d70ff869f1a6ab7958e3c393") +!2 = !{!3} +!3 = !DIGlobalVariableExpression(var: !4, expr: !DIExpression()) +!4 = distinct !DIGlobalVariable(name: "x", scope: !0, file: !1, line: 2, type: !5, isLocal: false, isDefinition: true) +!5 = !DIDerivedType(tag: DW_TAG_volatile_type, baseType: !6) +!6 = !DIBasicType(name: "int", size: 32, encoding: DW_ATE_signed) +!7 = distinct !DICompileUnit(language: DW_LANG_C11, file: !8, producer: "clang version 19.0.0", isOptimized: true, runtimeVersion: 0, emissionKind: FullDebug, splitDebugInlining: false, nameTableKind: None) +!8 = !DIFile(filename: "test1.v1.c", directory: "/home/test", checksumkind: CSK_MD5, checksum: "76696bd6bfe16a9f227fe03cfdb6a82c") +!9 = distinct !DICompileUnit(language: DW_LANG_C11, file: !10, producer: "clang version 19.0.0", isOptimized: true, runtimeVersion: 0, emissionKind: FullDebug, splitDebugInlining: false, nameTableKind: None) +!10 = !DIFile(filename: "test2.c", directory: "/home/test", checksumkind: CSK_MD5, checksum: "553093afc026f9c73562eb3b0c5b7532") +!11 = !{i32 2, !"Debug Info Version", i32 3} +!12 = !{i64 -2624081020897602054, i64 281582081721716, !"main"} +!13 = !DILocation(line: 8, column: 10, scope: !14) +!14 = !DILexicalBlockFile(scope: !15, file: !1, discriminator: 186646591) +!15 = distinct !DILexicalBlock(scope: !16, file: !1, line: 7, column: 40) +!16 = distinct !DILexicalBlock(scope: !17, file: !1, line: 7, column: 3) +!17 = distinct !DILexicalBlock(scope: !18, file: !1, line: 7, column: 3) +!18 = distinct !DISubprogram(name: "main", scope: !1, file: !1, line: 5, type: !19, scopeLine: 6, flags: DIFlagAllCallsDescribed, spFlags: DISPFlagDefinition | DISPFlagOptimized, unit: !0, retainedNodes: !20) +!19 = distinct !DISubroutineType(types: !20) +!20 = !{} +!21 = distinct !DISubprogram(name: "bar", scope: !8, file: !8, line: 3, type: !22, scopeLine: 3, flags: DIFlagPrototyped | DIFlagAllCallsDescribed, spFlags: DISPFlagDefinition | DISPFlagOptimized, unit: !7, retainedNodes: !20) +!22 = !DISubroutineType(types: !20) +!23 = !DILocation(line: 6, column: 8, scope: !24) +!24 = !DILexicalBlockFile(scope: !21, file: !8, discriminator: 186646567) +!25 = distinct !DISubprogram(name: "baz", scope: !10, file: !10, line: 1, type: !22, scopeLine: 1, flags: DIFlagPrototyped | DIFlagAllCallsDescribed, spFlags: DISPFlagDefinition | DISPFlagOptimized, unit: !9, retainedNodes: !20) diff --git a/llvm/test/Transforms/SampleProfile/pseudo-probe-stale-profile-matching-lto.ll b/llvm/test/Transforms/SampleProfile/pseudo-probe-stale-profile-matching-lto.ll index 55225b415d4a..270beee4ebc2 100644 --- a/llvm/test/Transforms/SampleProfile/pseudo-probe-stale-profile-matching-lto.ll +++ b/llvm/test/Transforms/SampleProfile/pseudo-probe-stale-profile-matching-lto.ll @@ -106,7 +106,7 @@ define available_externally dso_local i32 @bar(i32 noundef %0) local_unnamed_add ret i32 %2, !dbg !132 } -attributes #0 = { nounwind uwtable "disable-tail-calls"="true" "frame-pointer"="all" "min-legal-vector-width"="0" "no-trapping-math"="true" "stack-protector-buffer-size"="8" "target-cpu"="x86-64" "target-features"="+cmov,+cx8,+fxsr,+mmx,+sse,+sse2,+x87" "tune-cpu"="generic" "use-sample-profile" } +attributes #0 = { nounwind uwtable "disable-tail-calls"="true" "frame-pointer"="all" "min-legal-vector-width"="0" "no-trapping-math"="true" "stack-protector-buffer-size"="8" "target-cpu"="x86-64" "target-features"="+cmov,+cx8,+fxsr,+mmx,+sse,+sse2,+x87" "tune-cpu"="generic" "use-sample-profile" "profile-checksum-mismatch"} attributes #1 = { nocallback nofree nosync nounwind willreturn memory(inaccessiblemem: readwrite) } attributes #2 = { nocallback nofree nosync nounwind speculatable willreturn memory(none) } attributes #3 = { mustprogress nofree norecurse nosync nounwind willreturn memory(none) uwtable "disable-tail-calls"="true" "frame-pointer"="all" "min-legal-vector-width"="0" "no-trapping-math"="true" "stack-protector-buffer-size"="8" "target-cpu"="x86-64" "target-features"="+cmov,+cx8,+fxsr,+mmx,+sse,+sse2,+x87" "tune-cpu"="generic" "use-sample-profile" } diff --git a/llvm/test/Transforms/SampleProfile/pseudo-probe-stale-profile-matching.ll b/llvm/test/Transforms/SampleProfile/pseudo-probe-stale-profile-matching.ll index 89477ea5fecf..29877fb22a2c 100644 --- a/llvm/test/Transforms/SampleProfile/pseudo-probe-stale-profile-matching.ll +++ b/llvm/test/Transforms/SampleProfile/pseudo-probe-stale-profile-matching.ll @@ -48,6 +48,8 @@ ; } ; } +; Verify not running profile matching for checksum matched function. +; CHECK-NOT: Run stale profile matching for bar ; CHECK: Run stale profile matching for main -- GitLab From ed801ab460f387a4e125ccfaa5ccdea1dd499ebf Mon Sep 17 00:00:00 2001 From: Kazu Hirata Date: Wed, 27 Mar 2024 23:11:16 -0700 Subject: [PATCH 022/788] [Transforms] Fix an unused variable warning llvm/include/llvm/Transforms/Utils/SampleProfileLoaderBaseImpl.h:89:28: error: private field 'LTOPhase' is not used [-Werror,-Wunused-private-field] --- llvm/include/llvm/Transforms/Utils/SampleProfileLoaderBaseImpl.h | 1 + 1 file changed, 1 insertion(+) diff --git a/llvm/include/llvm/Transforms/Utils/SampleProfileLoaderBaseImpl.h b/llvm/include/llvm/Transforms/Utils/SampleProfileLoaderBaseImpl.h index bd7496a799c5..048b97c34ee2 100644 --- a/llvm/include/llvm/Transforms/Utils/SampleProfileLoaderBaseImpl.h +++ b/llvm/include/llvm/Transforms/Utils/SampleProfileLoaderBaseImpl.h @@ -134,6 +134,7 @@ public: F.hasFnAttribute("profile-checksum-mismatch")) && "In post-link, profile checksum matching state doesn't match " "function 'profile-checksum-mismatch' attribute."); + (void)LTOPhase; // The desc for import function is unavailable. Check the function attribute // for mismatch. return (!Desc && !F.hasFnAttribute("profile-checksum-mismatch")) || -- GitLab From 5dfc446d7545d7ac960e20be362bd9935f390827 Mon Sep 17 00:00:00 2001 From: hchandel <165007698+hchandel@users.noreply.github.com> Date: Thu, 28 Mar 2024 11:43:47 +0530 Subject: [PATCH 023/788] [RISCV] Remove Unnecessary Semicolon. NFC (#86911) Removes Unnecessary Semicolon Co-authored-by: Harsh Chandel --- llvm/lib/Target/RISCV/RISCVISelLowering.h | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/llvm/lib/Target/RISCV/RISCVISelLowering.h b/llvm/lib/Target/RISCV/RISCVISelLowering.h index c11b1464757c..ace5b3fd2b95 100644 --- a/llvm/lib/Target/RISCV/RISCVISelLowering.h +++ b/llvm/lib/Target/RISCV/RISCVISelLowering.h @@ -1000,7 +1000,7 @@ private: /// RISC-V doesn't have flags so it's better to perform the and/or in a GPR. bool shouldNormalizeToSelectSequence(LLVMContext &, EVT) const override { return false; - }; + } /// For available scheduling models FDIV + two independent FMULs are much /// faster than two FDIVs. -- GitLab From e5b93994941245d35827b62ec91a537dfb52c243 Mon Sep 17 00:00:00 2001 From: Petr Hosek Date: Wed, 27 Mar 2024 23:59:24 -0700 Subject: [PATCH 024/788] [libc] Move baremetal write_to_stderr implementation to io.cpp (#86890) This is required to avoid multiple definitions error. --- .../__support/OSUtil/baremetal/CMakeLists.txt | 1 + libc/src/__support/OSUtil/baremetal/io.cpp | 22 +++++++++++++++++++ libc/src/__support/OSUtil/baremetal/io.h | 7 +----- 3 files changed, 24 insertions(+), 6 deletions(-) create mode 100644 libc/src/__support/OSUtil/baremetal/io.cpp diff --git a/libc/src/__support/OSUtil/baremetal/CMakeLists.txt b/libc/src/__support/OSUtil/baremetal/CMakeLists.txt index 23da40326bbb..e78301d104c1 100644 --- a/libc/src/__support/OSUtil/baremetal/CMakeLists.txt +++ b/libc/src/__support/OSUtil/baremetal/CMakeLists.txt @@ -1,6 +1,7 @@ add_object_library( baremetal_util SRCS + io.cpp quick_exit.cpp HDRS io.h diff --git a/libc/src/__support/OSUtil/baremetal/io.cpp b/libc/src/__support/OSUtil/baremetal/io.cpp new file mode 100644 index 000000000000..347c7d405b0a --- /dev/null +++ b/libc/src/__support/OSUtil/baremetal/io.cpp @@ -0,0 +1,22 @@ +//===---------- Baremetal implementation of IO utils ------------*- C++ -*-===// +// +// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. +// See https://llvm.org/LICENSE.txt for license information. +// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception +// +//===----------------------------------------------------------------------===// + +#include "io.h" + +#include "src/__support/CPP/string_view.h" + +// This is intended to be provided by the vendor. +extern "C" void __llvm_libc_log_write(const char *msg, size_t len); + +namespace LIBC_NAMESPACE { + +void write_to_stderr(cpp::string_view msg) { + __llvm_libc_log_write(msg.data(), msg.size()); +} + +} // namespace LIBC_NAMESPACE diff --git a/libc/src/__support/OSUtil/baremetal/io.h b/libc/src/__support/OSUtil/baremetal/io.h index a50c11d4aea1..87534641b1fa 100644 --- a/libc/src/__support/OSUtil/baremetal/io.h +++ b/libc/src/__support/OSUtil/baremetal/io.h @@ -13,12 +13,7 @@ namespace LIBC_NAMESPACE { -// This is intended to be provided by the vendor. -extern "C" void __llvm_libc_log_write(const char *msg, size_t len); - -void write_to_stderr(cpp::string_view msg) { - __llvm_libc_log_write(msg.data(), msg.size()); -} +void write_to_stderr(cpp::string_view msg); } // namespace LIBC_NAMESPACE -- GitLab From b7ac8fddb54816256fab70696ebc176717a391c3 Mon Sep 17 00:00:00 2001 From: Vyacheslav Levytskyy Date: Thu, 28 Mar 2024 08:08:06 +0100 Subject: [PATCH 025/788] [SPIR-V] Improve type inference: deduce types of composite data structures (#86782) This PR improves type inference in general and deduces types of composite data structures in particular. Also added a way to insert a bitcast to make a fun call valid in case of arguments types mismatch due to opaque pointers type inference. The attached test `pointers/nested-struct-opaque-pointers.ll` demonstrates new capabilities: the SPIRV code emitted for this test is now (1) valid in a sense of data field types and (2) accepted by `spirv-val`. More strict LIT checks, support of more composite data structures and improvement of fun calls from the perspective of type correctness are main todo's at the moment. --- llvm/lib/Target/SPIRV/SPIRVCallLowering.cpp | 25 +- llvm/lib/Target/SPIRV/SPIRVEmitIntrinsics.cpp | 216 +++++++++++++----- llvm/lib/Target/SPIRV/SPIRVGlobalRegistry.h | 80 +++++++ llvm/lib/Target/SPIRV/SPIRVISelLowering.cpp | 108 ++++++++- .../Target/SPIRV/SPIRVInstructionSelector.cpp | 2 +- llvm/lib/Target/SPIRV/SPIRVPreLegalizer.cpp | 5 +- llvm/lib/Target/SPIRV/SPIRVUtils.h | 22 +- .../pointers/nested-struct-opaque-pointers.ll | 20 ++ .../SPIRV/pointers/struct-opaque-pointers.ll | 8 +- .../pointers/type-deduce-by-call-chain.ll | 7 +- 10 files changed, 412 insertions(+), 81 deletions(-) create mode 100644 llvm/test/CodeGen/SPIRV/pointers/nested-struct-opaque-pointers.ll diff --git a/llvm/lib/Target/SPIRV/SPIRVCallLowering.cpp b/llvm/lib/Target/SPIRV/SPIRVCallLowering.cpp index afdca01561b0..ad4e72a3128b 100644 --- a/llvm/lib/Target/SPIRV/SPIRVCallLowering.cpp +++ b/llvm/lib/Target/SPIRV/SPIRVCallLowering.cpp @@ -201,21 +201,30 @@ static SPIRVType *getArgSPIRVType(const Function &F, unsigned ArgIdx, if (!isPointerTy(OriginalArgType)) return GR->getOrCreateSPIRVType(OriginalArgType, MIRBuilder, ArgAccessQual); - // In case OriginalArgType is of pointer type, there are three possibilities: + Argument *Arg = F.getArg(ArgIdx); + Type *ArgType = Arg->getType(); + if (isTypedPointerTy(ArgType)) { + SPIRVType *ElementType = GR->getOrCreateSPIRVType( + cast(ArgType)->getElementType(), MIRBuilder); + return GR->getOrCreateSPIRVPointerType( + ElementType, MIRBuilder, + addressSpaceToStorageClass(getPointerAddressSpace(ArgType), ST)); + } + + // In case OriginalArgType is of untyped pointer type, there are three + // possibilities: // 1) This is a pointer of an LLVM IR element type, passed byval/byref. // 2) This is an OpenCL/SPIR-V builtin type if there is spv_assign_type - // intrinsic assigning a TargetExtType. + // intrinsic assigning a TargetExtType. // 3) This is a pointer, try to retrieve pointer element type from a // spv_assign_ptr_type intrinsic or otherwise use default pointer element // type. - Argument *Arg = F.getArg(ArgIdx); - if (HasPointeeTypeAttr(Arg)) { - Type *ByValRefType = Arg->hasByValAttr() ? Arg->getParamByValType() - : Arg->getParamByRefType(); - SPIRVType *ElementType = GR->getOrCreateSPIRVType(ByValRefType, MIRBuilder); + if (hasPointeeTypeAttr(Arg)) { + SPIRVType *ElementType = + GR->getOrCreateSPIRVType(getPointeeTypeByAttr(Arg), MIRBuilder); return GR->getOrCreateSPIRVPointerType( ElementType, MIRBuilder, - addressSpaceToStorageClass(getPointerAddressSpace(Arg->getType()), ST)); + addressSpaceToStorageClass(getPointerAddressSpace(ArgType), ST)); } for (auto User : Arg->users()) { diff --git a/llvm/lib/Target/SPIRV/SPIRVEmitIntrinsics.cpp b/llvm/lib/Target/SPIRV/SPIRVEmitIntrinsics.cpp index 5828db6669ff..7c5a38fa48d0 100644 --- a/llvm/lib/Target/SPIRV/SPIRVEmitIntrinsics.cpp +++ b/llvm/lib/Target/SPIRV/SPIRVEmitIntrinsics.cpp @@ -14,6 +14,7 @@ #include "SPIRV.h" #include "SPIRVBuiltins.h" #include "SPIRVMetadata.h" +#include "SPIRVSubtarget.h" #include "SPIRVTargetMachine.h" #include "SPIRVUtils.h" #include "llvm/IR/IRBuilder.h" @@ -53,14 +54,22 @@ class SPIRVEmitIntrinsics : public FunctionPass, public InstVisitor { SPIRVTargetMachine *TM = nullptr; + SPIRVGlobalRegistry *GR = nullptr; Function *F = nullptr; bool TrackConstants = true; DenseMap AggrConsts; + DenseMap AggrConstTypes; DenseSet AggrStores; - // deduce values type - DenseMap DeducedElTys; + // deduce element type of untyped pointers Type *deduceElementType(Value *I); + Type *deduceElementTypeHelper(Value *I); + Type *deduceElementTypeHelper(Value *I, std::unordered_set &Visited); + + // deduce nested types of composites + Type *deduceNestedTypeHelper(User *U); + Type *deduceNestedTypeHelper(User *U, Type *Ty, + std::unordered_set &Visited); void preprocessCompositeConstants(IRBuilder<> &B); void preprocessUndefs(IRBuilder<> &B); @@ -92,9 +101,9 @@ class SPIRVEmitIntrinsics void insertPtrCastOrAssignTypeInstr(Instruction *I, IRBuilder<> &B); void processGlobalValue(GlobalVariable &GV, IRBuilder<> &B); void processParamTypes(Function *F, IRBuilder<> &B); - Type *deduceFunParamType(Function *F, unsigned OpIdx); - Type *deduceFunParamType(Function *F, unsigned OpIdx, - std::unordered_set &FVisited); + Type *deduceFunParamElementType(Function *F, unsigned OpIdx); + Type *deduceFunParamElementType(Function *F, unsigned OpIdx, + std::unordered_set &FVisited); public: static char ID; @@ -169,17 +178,20 @@ static inline void reportFatalOnTokenType(const Instruction *I) { // Deduce and return a successfully deduced Type of the Instruction, // or nullptr otherwise. -static Type *deduceElementTypeHelper(Value *I, - std::unordered_set &Visited, - DenseMap &DeducedElTys) { +Type *SPIRVEmitIntrinsics::deduceElementTypeHelper(Value *I) { + std::unordered_set Visited; + return deduceElementTypeHelper(I, Visited); +} + +Type *SPIRVEmitIntrinsics::deduceElementTypeHelper( + Value *I, std::unordered_set &Visited) { // allow to pass nullptr as an argument if (!I) return nullptr; // maybe already known - auto It = DeducedElTys.find(I); - if (It != DeducedElTys.end()) - return It->second; + if (Type *KnownTy = GR->findDeducedElementType(I)) + return KnownTy; // maybe a cycle if (Visited.find(I) != Visited.end()) @@ -195,25 +207,99 @@ static Type *deduceElementTypeHelper(Value *I, Ty = Ref->getResultElementType(); } else if (auto *Ref = dyn_cast(I)) { Ty = Ref->getValueType(); + if (Value *Op = Ref->getNumOperands() > 0 ? Ref->getOperand(0) : nullptr) { + if (auto *PtrTy = dyn_cast(Ty)) { + if (Type *NestedTy = deduceElementTypeHelper(Op, Visited)) + Ty = TypedPointerType::get(NestedTy, PtrTy->getAddressSpace()); + } else { + Ty = deduceNestedTypeHelper(dyn_cast(Op), Ty, Visited); + } + } } else if (auto *Ref = dyn_cast(I)) { - Ty = deduceElementTypeHelper(Ref->getPointerOperand(), Visited, - DeducedElTys); + Ty = deduceElementTypeHelper(Ref->getPointerOperand(), Visited); } else if (auto *Ref = dyn_cast(I)) { if (Type *Src = Ref->getSrcTy(), *Dest = Ref->getDestTy(); isPointerTy(Src) && isPointerTy(Dest)) - Ty = deduceElementTypeHelper(Ref->getOperand(0), Visited, DeducedElTys); + Ty = deduceElementTypeHelper(Ref->getOperand(0), Visited); } // remember the found relationship - if (Ty) - DeducedElTys[I] = Ty; + if (Ty) { + // specify nested types if needed, otherwise return unchanged + GR->addDeducedElementType(I, Ty); + } return Ty; } -Type *SPIRVEmitIntrinsics::deduceElementType(Value *I) { +// Re-create a type of the value if it has untyped pointer fields, also nested. +// Return the original value type if no corrections of untyped pointer +// information is found or needed. +Type *SPIRVEmitIntrinsics::deduceNestedTypeHelper(User *U) { std::unordered_set Visited; - if (Type *Ty = deduceElementTypeHelper(I, Visited, DeducedElTys)) + return deduceNestedTypeHelper(U, U->getType(), Visited); +} + +Type *SPIRVEmitIntrinsics::deduceNestedTypeHelper( + User *U, Type *OrigTy, std::unordered_set &Visited) { + if (!U) + return OrigTy; + + // maybe already known + if (Type *KnownTy = GR->findDeducedCompositeType(U)) + return KnownTy; + + // maybe a cycle + if (Visited.find(U) != Visited.end()) + return OrigTy; + Visited.insert(U); + + if (dyn_cast(OrigTy)) { + SmallVector Tys; + bool Change = false; + for (unsigned i = 0; i < U->getNumOperands(); ++i) { + Value *Op = U->getOperand(i); + Type *OpTy = Op->getType(); + Type *Ty = OpTy; + if (Op) { + if (auto *PtrTy = dyn_cast(OpTy)) { + if (Type *NestedTy = deduceElementTypeHelper(Op, Visited)) + Ty = TypedPointerType::get(NestedTy, PtrTy->getAddressSpace()); + } else { + Ty = deduceNestedTypeHelper(dyn_cast(Op), OpTy, Visited); + } + } + Tys.push_back(Ty); + Change |= Ty != OpTy; + } + if (Change) { + Type *NewTy = StructType::create(Tys); + GR->addDeducedCompositeType(U, NewTy); + return NewTy; + } + } else if (auto *ArrTy = dyn_cast(OrigTy)) { + if (Value *Op = U->getNumOperands() > 0 ? U->getOperand(0) : nullptr) { + Type *OpTy = ArrTy->getElementType(); + Type *Ty = OpTy; + if (auto *PtrTy = dyn_cast(OpTy)) { + if (Type *NestedTy = deduceElementTypeHelper(Op, Visited)) + Ty = TypedPointerType::get(NestedTy, PtrTy->getAddressSpace()); + } else { + Ty = deduceNestedTypeHelper(dyn_cast(Op), OpTy, Visited); + } + if (Ty != OpTy) { + Type *NewTy = ArrayType::get(Ty, ArrTy->getNumElements()); + GR->addDeducedCompositeType(U, NewTy); + return NewTy; + } + } + } + + return OrigTy; +} + +Type *SPIRVEmitIntrinsics::deduceElementType(Value *I) { + if (Type *Ty = deduceElementTypeHelper(I)) return Ty; return IntegerType::getInt8Ty(I->getContext()); } @@ -257,6 +343,7 @@ void SPIRVEmitIntrinsics::preprocessUndefs(IRBuilder<> &B) { Worklist.push(IntrUndef); I->replaceUsesOfWith(Op, IntrUndef); AggrConsts[IntrUndef] = AggrUndef; + AggrConstTypes[IntrUndef] = AggrUndef->getType(); } } } @@ -282,6 +369,7 @@ void SPIRVEmitIntrinsics::preprocessCompositeConstants(IRBuilder<> &B) { I->replaceUsesOfWith(Op, CCI); KeepInst = true; SEI.AggrConsts[CCI] = AggrC; + SEI.AggrConstTypes[CCI] = SEI.deduceNestedTypeHelper(AggrC); }; if (auto *AggrC = dyn_cast(Op)) { @@ -396,8 +484,7 @@ void SPIRVEmitIntrinsics::replacePointerOperandWithPtrCast( Pointer = BC->getOperand(0); // Do not emit spv_ptrcast if Pointer's element type is ExpectedElementType - std::unordered_set Visited; - Type *PointerElemTy = deduceElementTypeHelper(Pointer, Visited, DeducedElTys); + Type *PointerElemTy = deduceElementTypeHelper(Pointer); if (PointerElemTy == ExpectedElementType) return; @@ -456,8 +543,8 @@ void SPIRVEmitIntrinsics::replacePointerOperandWithPtrCast( CallInst *CI = buildIntrWithMD( Intrinsic::spv_assign_ptr_type, {Pointer->getType()}, ExpectedElementTypeConst, Pointer, {B.getInt32(AddressSpace)}, B); - DeducedElTys[CI] = ExpectedElementType; - DeducedElTys[Pointer] = ExpectedElementType; + GR->addDeducedElementType(CI, ExpectedElementType); + GR->addDeducedElementType(Pointer, ExpectedElementType); return; } @@ -498,25 +585,29 @@ void SPIRVEmitIntrinsics::insertPtrCastOrAssignTypeInstr(Instruction *I, Function *CalledF = CI->getCalledFunction(); SmallVector CalledArgTys; bool HaveTypes = false; - for (auto &CalledArg : CalledF->args()) { - if (!isPointerTy(CalledArg.getType())) { + for (unsigned OpIdx = 0; OpIdx < CalledF->arg_size(); ++OpIdx) { + Argument *CalledArg = CalledF->getArg(OpIdx); + Type *ArgType = CalledArg->getType(); + if (!isPointerTy(ArgType)) { CalledArgTys.push_back(nullptr); - continue; - } - auto It = DeducedElTys.find(&CalledArg); - Type *ParamTy = It != DeducedElTys.end() ? It->second : nullptr; - if (!ParamTy) { - for (User *U : CalledArg.users()) { - if (Instruction *Inst = dyn_cast(U)) { - std::unordered_set Visited; - ParamTy = deduceElementTypeHelper(Inst, Visited, DeducedElTys); - if (ParamTy) - break; + } else if (isTypedPointerTy(ArgType)) { + CalledArgTys.push_back(cast(ArgType)->getElementType()); + HaveTypes = true; + } else { + Type *ElemTy = GR->findDeducedElementType(CalledArg); + if (!ElemTy && hasPointeeTypeAttr(CalledArg)) + ElemTy = getPointeeTypeByAttr(CalledArg); + if (!ElemTy) { + for (User *U : CalledArg->users()) { + if (Instruction *Inst = dyn_cast(U)) { + if ((ElemTy = deduceElementTypeHelper(Inst)) != nullptr) + break; + } } } + HaveTypes |= ElemTy != nullptr; + CalledArgTys.push_back(ElemTy); } - HaveTypes |= ParamTy != nullptr; - CalledArgTys.push_back(ParamTy); } std::string DemangledName = @@ -706,6 +797,10 @@ void SPIRVEmitIntrinsics::processGlobalValue(GlobalVariable &GV, if (GV.getName() == "llvm.global.annotations") return; if (GV.hasInitializer() && !isa(GV.getInitializer())) { + // Deduce element type and store results in Global Registry. + // Result is ignored, because TypedPointerType is not supported + // by llvm IR general logic. + deduceElementTypeHelper(&GV); Constant *Init = GV.getInitializer(); Type *Ty = isAggrToReplace(Init) ? B.getInt32Ty() : Init->getType(); Constant *Const = isAggrToReplace(Init) ? B.getInt32(1) : Init; @@ -732,7 +827,7 @@ void SPIRVEmitIntrinsics::insertAssignPtrTypeIntrs(Instruction *I, unsigned AddressSpace = getPointerAddressSpace(I->getType()); CallInst *CI = buildIntrWithMD(Intrinsic::spv_assign_ptr_type, {I->getType()}, EltTyConst, I, {B.getInt32(AddressSpace)}, B); - DeducedElTys[CI] = ElemTy; + GR->addDeducedElementType(CI, ElemTy); } void SPIRVEmitIntrinsics::insertAssignTypeIntrs(Instruction *I, @@ -745,9 +840,10 @@ void SPIRVEmitIntrinsics::insertAssignTypeIntrs(Instruction *I, if (auto *II = dyn_cast(I)) { if (II->getIntrinsicID() == Intrinsic::spv_const_composite || II->getIntrinsicID() == Intrinsic::spv_undef) { - auto t = AggrConsts.find(II); - assert(t != AggrConsts.end()); - TypeToAssign = t->second->getType(); + auto It = AggrConstTypes.find(II); + if (It == AggrConstTypes.end()) + report_fatal_error("Unknown composite intrinsic type"); + TypeToAssign = It->second; } } Constant *Const = UndefValue::get(TypeToAssign); @@ -807,12 +903,13 @@ void SPIRVEmitIntrinsics::processInstrAfterVisit(Instruction *I, } } -Type *SPIRVEmitIntrinsics::deduceFunParamType(Function *F, unsigned OpIdx) { +Type *SPIRVEmitIntrinsics::deduceFunParamElementType(Function *F, + unsigned OpIdx) { std::unordered_set FVisited; - return deduceFunParamType(F, OpIdx, FVisited); + return deduceFunParamElementType(F, OpIdx, FVisited); } -Type *SPIRVEmitIntrinsics::deduceFunParamType( +Type *SPIRVEmitIntrinsics::deduceFunParamElementType( Function *F, unsigned OpIdx, std::unordered_set &FVisited) { // maybe a cycle if (FVisited.find(F) != FVisited.end()) @@ -830,15 +927,15 @@ Type *SPIRVEmitIntrinsics::deduceFunParamType( if (!isPointerTy(OpArg->getType())) continue; // maybe we already know operand's element type - if (auto It = DeducedElTys.find(OpArg); It != DeducedElTys.end()) - return It->second; + if (Type *KnownTy = GR->findDeducedElementType(OpArg)) + return KnownTy; // search in actual parameter's users for (User *OpU : OpArg->users()) { Instruction *Inst = dyn_cast(OpU); if (!Inst || Inst == CI) continue; Visited.clear(); - if (Type *Ty = deduceElementTypeHelper(Inst, Visited, DeducedElTys)) + if (Type *Ty = deduceElementTypeHelper(Inst, Visited)) return Ty; } // check if it's a formal parameter of the outer function @@ -857,7 +954,7 @@ Type *SPIRVEmitIntrinsics::deduceFunParamType( // search in function parameters for (auto &Pair : Lookup) { - if (Type *Ty = deduceFunParamType(Pair.first, Pair.second, FVisited)) + if (Type *Ty = deduceFunParamElementType(Pair.first, Pair.second, FVisited)) return Ty; } @@ -866,19 +963,23 @@ Type *SPIRVEmitIntrinsics::deduceFunParamType( void SPIRVEmitIntrinsics::processParamTypes(Function *F, IRBuilder<> &B) { B.SetInsertPointPastAllocas(F); - DenseMap Args; for (unsigned OpIdx = 0; OpIdx < F->arg_size(); ++OpIdx) { Argument *Arg = F->getArg(OpIdx); - if (isUntypedPointerTy(Arg->getType()) && - DeducedElTys.find(Arg) == DeducedElTys.end() && - !HasPointeeTypeAttr(Arg)) { - if (Type *ElemTy = deduceFunParamType(F, OpIdx)) { + if (!isUntypedPointerTy(Arg->getType())) + continue; + + Type *ElemTy = GR->findDeducedElementType(Arg); + if (!ElemTy) { + if (hasPointeeTypeAttr(Arg) && + (ElemTy = getPointeeTypeByAttr(Arg)) != nullptr) { + GR->addDeducedElementType(Arg, ElemTy); + } else if ((ElemTy = deduceFunParamElementType(F, OpIdx)) != nullptr) { CallInst *AssignPtrTyCI = buildIntrWithMD( Intrinsic::spv_assign_ptr_type, {Arg->getType()}, Constant::getNullValue(ElemTy), Arg, {B.getInt32(getPointerAddressSpace(Arg->getType()))}, B); - DeducedElTys[AssignPtrTyCI] = ElemTy; - DeducedElTys[Arg] = ElemTy; + GR->addDeducedElementType(AssignPtrTyCI, ElemTy); + GR->addDeducedElementType(Arg, ElemTy); } } } @@ -887,9 +988,14 @@ void SPIRVEmitIntrinsics::processParamTypes(Function *F, IRBuilder<> &B) { bool SPIRVEmitIntrinsics::runOnFunction(Function &Func) { if (Func.isDeclaration()) return false; + + const SPIRVSubtarget &ST = TM->getSubtarget(Func); + GR = ST.getSPIRVGlobalRegistry(); + F = &Func; IRBuilder<> B(Func.getContext()); AggrConsts.clear(); + AggrConstTypes.clear(); AggrStores.clear(); // StoreInst's operand type can be changed during the next transformations, diff --git a/llvm/lib/Target/SPIRV/SPIRVGlobalRegistry.h b/llvm/lib/Target/SPIRV/SPIRVGlobalRegistry.h index ed0f90ff89ce..e0099e529447 100644 --- a/llvm/lib/Target/SPIRV/SPIRVGlobalRegistry.h +++ b/llvm/lib/Target/SPIRV/SPIRVGlobalRegistry.h @@ -41,9 +41,13 @@ class SPIRVGlobalRegistry { // map a Function to its definition (as a machine instruction operand) DenseMap FunctionToInstr; + DenseMap FunctionToInstrRev; // map function pointer (as a machine instruction operand) to the used // Function DenseMap InstrToFunction; + // Maps Functions to their calls (in a form of the machine instruction, + // OpFunctionCall) that happened before the definition is available + DenseMap> ForwardCalls; // Look for an equivalent of the newType in the map. Return the equivalent // if it's found, otherwise insert newType to the map and return the type. @@ -59,6 +63,13 @@ class SPIRVGlobalRegistry { // Holds the maximum ID we have in the module. unsigned Bound; + // Maps values associated with untyped pointers into deduced element types of + // untyped pointers. + DenseMap DeducedElTys; + // Maps composite values to deduced types where untyped pointers are replaced + // with typed ones + DenseMap DeducedNestedTys; + // Add a new OpTypeXXX instruction without checking for duplicates. SPIRVType *createSPIRVType(const Type *Type, MachineIRBuilder &MIRBuilder, SPIRV::AccessQualifier::AccessQualifier AQ = @@ -122,6 +133,37 @@ public: void setBound(unsigned V) { Bound = V; } unsigned getBound() { return Bound; } + // Deduced element types of untyped pointers and composites: + // - Add a record to the map of deduced element types. + void addDeducedElementType(Value *Val, Type *Ty) { DeducedElTys[Val] = Ty; } + // - Find a record in the map of deduced element types. + Type *findDeducedElementType(const Value *Val) { + auto It = DeducedElTys.find(Val); + return It == DeducedElTys.end() ? nullptr : It->second; + } + // - Add a record to the map of deduced composite types. + void addDeducedCompositeType(Value *Val, Type *Ty) { + DeducedNestedTys[Val] = Ty; + } + // - Find a record in the map of deduced composite types. + Type *findDeducedCompositeType(const Value *Val) { + auto It = DeducedNestedTys.find(Val); + return It == DeducedNestedTys.end() ? nullptr : It->second; + } + // - Find a type of the given Global value + Type *getDeducedGlobalValueType(const GlobalValue *Global) { + // we may know element type if it was deduced earlier + Type *ElementTy = findDeducedElementType(Global); + if (!ElementTy) { + // or we may know element type if it's associated with a composite + // value + if (Value *GlobalElem = + Global->getNumOperands() > 0 ? Global->getOperand(0) : nullptr) + ElementTy = findDeducedCompositeType(GlobalElem); + } + return ElementTy ? ElementTy : Global->getValueType(); + } + // Map a machine operand that represents a use of a function via function // pointer to a machine operand that represents the function definition. // Return either the register or invalid value, because we have no context for @@ -133,18 +175,56 @@ public: auto ResReg = FunctionToInstr.find(ResF->second); return ResReg == FunctionToInstr.end() ? nullptr : ResReg->second; } + + // Map a Function to a machine instruction that represents the function + // definition. + const MachineInstr *getFunctionDefinition(const Function *F) { + if (!F) + return nullptr; + auto MOIt = FunctionToInstr.find(F); + return MOIt == FunctionToInstr.end() ? nullptr : MOIt->second->getParent(); + } + + // Map a Function to a machine instruction that represents the function + // definition. + const Function *getFunctionByDefinition(const MachineInstr *MI) { + if (!MI) + return nullptr; + auto FIt = FunctionToInstrRev.find(MI); + return FIt == FunctionToInstrRev.end() ? nullptr : FIt->second; + } + // map function pointer (as a machine instruction operand) to the used // Function void recordFunctionPointer(const MachineOperand *MO, const Function *F) { InstrToFunction[MO] = F; } + // map a Function to its definition (as a machine instruction) void recordFunctionDefinition(const Function *F, const MachineOperand *MO) { FunctionToInstr[F] = MO; + FunctionToInstrRev[MO->getParent()] = F; } + // Return true if any OpConstantFunctionPointerINTEL were generated bool hasConstFunPtr() { return !InstrToFunction.empty(); } + // Add a record about forward function call. + void addForwardCall(const Function *F, MachineInstr *MI) { + auto It = ForwardCalls.find(F); + if (It == ForwardCalls.end()) + ForwardCalls[F] = {MI}; + else + It->second.push_back(MI); + } + + // Map a Function to the vector of machine instructions that represents + // forward function calls or to nullptr if not found. + SmallVector *getForwardCalls(const Function *F) { + auto It = ForwardCalls.find(F); + return It == ForwardCalls.end() ? nullptr : &It->second; + } + // Get or create a SPIR-V type corresponding the given LLVM IR type, // and map it to the given VReg by creating an ASSIGN_TYPE instruction. SPIRVType *assignTypeToVReg(const Type *Type, Register VReg, diff --git a/llvm/lib/Target/SPIRV/SPIRVISelLowering.cpp b/llvm/lib/Target/SPIRV/SPIRVISelLowering.cpp index 55b4c47c197d..4f5c1dc4f90b 100644 --- a/llvm/lib/Target/SPIRV/SPIRVISelLowering.cpp +++ b/llvm/lib/Target/SPIRV/SPIRVISelLowering.cpp @@ -86,8 +86,8 @@ bool SPIRVTargetLowering::getTgtMemIntrinsic(IntrinsicInfo &Info, // when there is a type mismatch between results and operand types. static void validatePtrTypes(const SPIRVSubtarget &STI, MachineRegisterInfo *MRI, SPIRVGlobalRegistry &GR, - MachineInstr &I, SPIRVType *ResType, - unsigned OpIdx) { + MachineInstr &I, unsigned OpIdx, + SPIRVType *ResType, const Type *ResTy = nullptr) { Register OpReg = I.getOperand(OpIdx).getReg(); SPIRVType *TypeInst = MRI->getVRegDef(OpReg); SPIRVType *OpType = GR.getSPIRVTypeForVReg( @@ -97,7 +97,13 @@ static void validatePtrTypes(const SPIRVSubtarget &STI, if (!ResType || !OpType || OpType->getOpcode() != SPIRV::OpTypePointer) return; SPIRVType *ElemType = GR.getSPIRVTypeForVReg(OpType->getOperand(2).getReg()); - if (!ElemType || ElemType == ResType) + if (!ElemType) + return; + bool IsSameMF = + ElemType->getParent()->getParent() == ResType->getParent()->getParent(); + bool IsEqualTypes = IsSameMF ? ElemType == ResType + : GR.getTypeForSPIRVType(ElemType) == ResTy; + if (IsEqualTypes) return; // There is a type mismatch between results and operand types // and we insert a bitcast before the instruction to keep SPIR-V code valid @@ -105,7 +111,11 @@ static void validatePtrTypes(const SPIRVSubtarget &STI, static_cast( OpType->getOperand(1).getImm()); MachineIRBuilder MIB(I); - SPIRVType *NewPtrType = GR.getOrCreateSPIRVPointerType(ResType, MIB, SC); + SPIRVType *NewBaseType = + IsSameMF ? ResType + : GR.getOrCreateSPIRVType( + ResTy, MIB, SPIRV::AccessQualifier::ReadWrite, false); + SPIRVType *NewPtrType = GR.getOrCreateSPIRVPointerType(NewBaseType, MIB, SC); if (!GR.isBitcastCompatible(NewPtrType, OpType)) report_fatal_error( "insert validation bitcast: incompatible result and operand types"); @@ -123,6 +133,74 @@ static void validatePtrTypes(const SPIRVSubtarget &STI, I.getOperand(OpIdx).setReg(NewReg); } +// Insert a bitcast before the function call instruction to keep SPIR-V code +// valid when there is a type mismatch between actual and expected types of an +// argument: +// %formal = OpFunctionParameter %formal_type +// ... +// %res = OpFunctionCall %ty %fun %actual ... +// implies that %actual is of %formal_type, and in case of opaque pointers. +// We may need to insert a bitcast to ensure this. +void validateFunCallMachineDef(const SPIRVSubtarget &STI, + MachineRegisterInfo *DefMRI, + MachineRegisterInfo *CallMRI, + SPIRVGlobalRegistry &GR, MachineInstr &FunCall, + MachineInstr *FunDef) { + if (FunDef->getOpcode() != SPIRV::OpFunction) + return; + unsigned OpIdx = 3; + for (FunDef = FunDef->getNextNode(); + FunDef && FunDef->getOpcode() == SPIRV::OpFunctionParameter && + OpIdx < FunCall.getNumOperands(); + FunDef = FunDef->getNextNode(), OpIdx++) { + SPIRVType *DefPtrType = DefMRI->getVRegDef(FunDef->getOperand(1).getReg()); + SPIRVType *DefElemType = + DefPtrType && DefPtrType->getOpcode() == SPIRV::OpTypePointer + ? GR.getSPIRVTypeForVReg(DefPtrType->getOperand(2).getReg()) + : nullptr; + if (DefElemType) { + const Type *DefElemTy = GR.getTypeForSPIRVType(DefElemType); + // Switch GR context to the call site instead of the (default) definition + // side + GR.setCurrentFunc(*FunCall.getParent()->getParent()); + validatePtrTypes(STI, CallMRI, GR, FunCall, OpIdx, DefElemType, + DefElemTy); + GR.setCurrentFunc(*FunDef->getParent()->getParent()); + } + } +} + +// Ensure there is no mismatch between actual and expected arg types: calls +// with a processed definition. Return Function pointer if it's a forward +// call (ahead of definition), and nullptr otherwise. +const Function *validateFunCall(const SPIRVSubtarget &STI, + MachineRegisterInfo *MRI, + SPIRVGlobalRegistry &GR, + MachineInstr &FunCall) { + const GlobalValue *GV = FunCall.getOperand(2).getGlobal(); + const Function *F = dyn_cast(GV); + MachineInstr *FunDef = + const_cast(GR.getFunctionDefinition(F)); + if (!FunDef) + return F; + validateFunCallMachineDef(STI, MRI, MRI, GR, FunCall, FunDef); + return nullptr; +} + +// Ensure there is no mismatch between actual and expected arg types: calls +// ahead of a processed definition. +void validateForwardCalls(const SPIRVSubtarget &STI, + MachineRegisterInfo *DefMRI, SPIRVGlobalRegistry &GR, + MachineInstr &FunDef) { + const Function *F = GR.getFunctionByDefinition(&FunDef); + if (SmallVector *FwdCalls = GR.getForwardCalls(F)) + for (MachineInstr *FunCall : *FwdCalls) { + MachineRegisterInfo *CallMRI = + &FunCall->getParent()->getParent()->getRegInfo(); + validateFunCallMachineDef(STI, DefMRI, CallMRI, GR, *FunCall, &FunDef); + } +} + // TODO: the logic of inserting additional bitcast's is to be moved // to pre-IRTranslation passes eventually void SPIRVTargetLowering::finalizeLowering(MachineFunction &MF) const { @@ -137,14 +215,28 @@ void SPIRVTargetLowering::finalizeLowering(MachineFunction &MF) const { switch (MI.getOpcode()) { case SPIRV::OpLoad: // OpLoad , ptr %Op implies that %Op is a pointer to - validatePtrTypes(STI, MRI, GR, MI, - GR.getSPIRVTypeForVReg(MI.getOperand(0).getReg()), 2); + validatePtrTypes(STI, MRI, GR, MI, 2, + GR.getSPIRVTypeForVReg(MI.getOperand(0).getReg())); break; case SPIRV::OpStore: // OpStore ptr %Op, implies that %Op points to the 's type - validatePtrTypes(STI, MRI, GR, MI, - GR.getSPIRVTypeForVReg(MI.getOperand(1).getReg()), 0); + validatePtrTypes(STI, MRI, GR, MI, 0, + GR.getSPIRVTypeForVReg(MI.getOperand(1).getReg())); break; + + case SPIRV::OpFunctionCall: + // ensure there is no mismatch between actual and expected arg types: + // calls with a processed definition + if (MI.getNumOperands() > 3) + if (const Function *F = validateFunCall(STI, MRI, GR, MI)) + GR.addForwardCall(F, &MI); + break; + case SPIRV::OpFunction: + // ensure there is no mismatch between actual and expected arg types: + // calls ahead of a processed definition + validateForwardCalls(STI, MRI, GR, MI); + break; + // ensure that LLVM IR bitwise instructions result in logical SPIR-V // instructions when applied to bool type case SPIRV::OpBitwiseOrS: diff --git a/llvm/lib/Target/SPIRV/SPIRVInstructionSelector.cpp b/llvm/lib/Target/SPIRV/SPIRVInstructionSelector.cpp index 505b19a4d66e..f4525e713c98 100644 --- a/llvm/lib/Target/SPIRV/SPIRVInstructionSelector.cpp +++ b/llvm/lib/Target/SPIRV/SPIRVInstructionSelector.cpp @@ -1897,7 +1897,7 @@ bool SPIRVInstructionSelector::selectGlobalValue( // FIXME: don't use MachineIRBuilder here, replace it with BuildMI. MachineIRBuilder MIRBuilder(I); const GlobalValue *GV = I.getOperand(1).getGlobal(); - Type *GVType = GV->getValueType(); + Type *GVType = GR.getDeducedGlobalValueType(GV); SPIRVType *PointerBaseType; if (GVType->isArrayTy()) { SPIRVType *ArrayElementType = diff --git a/llvm/lib/Target/SPIRV/SPIRVPreLegalizer.cpp b/llvm/lib/Target/SPIRV/SPIRVPreLegalizer.cpp index 41807da6afcb..b133f0ae85de 100644 --- a/llvm/lib/Target/SPIRV/SPIRVPreLegalizer.cpp +++ b/llvm/lib/Target/SPIRV/SPIRVPreLegalizer.cpp @@ -186,8 +186,9 @@ static SPIRVType *propagateSPIRVType(MachineInstr *MI, SPIRVGlobalRegistry *GR, } case TargetOpcode::G_GLOBAL_VALUE: { MIB.setInsertPt(*MI->getParent(), MI); - const auto *Global = MI->getOperand(1).getGlobal(); - auto *Ty = TypedPointerType::get(Global->getValueType(), + const GlobalValue *Global = MI->getOperand(1).getGlobal(); + Type *ElementTy = GR->getDeducedGlobalValueType(Global); + auto *Ty = TypedPointerType::get(ElementTy, Global->getType()->getAddressSpace()); SpirvTy = GR->getOrCreateSPIRVType(Ty, MIB); break; diff --git a/llvm/lib/Target/SPIRV/SPIRVUtils.h b/llvm/lib/Target/SPIRV/SPIRVUtils.h index eb87349f0941..c2c3475e1a93 100644 --- a/llvm/lib/Target/SPIRV/SPIRVUtils.h +++ b/llvm/lib/Target/SPIRV/SPIRVUtils.h @@ -127,8 +127,26 @@ inline unsigned getPointerAddressSpace(const Type *T) { } // Return true if the Argument is decorated with a pointee type -inline bool HasPointeeTypeAttr(Argument *Arg) { - return Arg->hasByValAttr() || Arg->hasByRefAttr(); +inline bool hasPointeeTypeAttr(Argument *Arg) { + return Arg->hasByValAttr() || Arg->hasByRefAttr() || Arg->hasStructRetAttr(); +} + +// Return the pointee type of the argument or nullptr otherwise +inline Type *getPointeeTypeByAttr(Argument *Arg) { + if (Arg->hasByValAttr()) + return Arg->getParamByValType(); + if (Arg->hasStructRetAttr()) + return Arg->getParamStructRetType(); + if (Arg->hasByRefAttr()) + return Arg->getParamByRefType(); + return nullptr; +} + +inline Type *reconstructFunctionType(Function *F) { + SmallVector ArgTys; + for (unsigned i = 0; i < F->arg_size(); ++i) + ArgTys.push_back(F->getArg(i)->getType()); + return FunctionType::get(F->getReturnType(), ArgTys, F->isVarArg()); } } // namespace llvm diff --git a/llvm/test/CodeGen/SPIRV/pointers/nested-struct-opaque-pointers.ll b/llvm/test/CodeGen/SPIRV/pointers/nested-struct-opaque-pointers.ll new file mode 100644 index 000000000000..77b895c7762f --- /dev/null +++ b/llvm/test/CodeGen/SPIRV/pointers/nested-struct-opaque-pointers.ll @@ -0,0 +1,20 @@ +; RUN: llc -O0 -mtriple=spirv32-unknown-unknown %s -o - | FileCheck %s +; RUN: %if spirv-tools %{ llc -O0 -mtriple=spirv32-unknown-unknown %s -o - -filetype=obj | spirv-val %} + +; CHECK-NOT: OpTypeInt 8 0 + +@GI = addrspace(1) constant i64 42 + +@GS = addrspace(1) global {ptr addrspace(1), ptr addrspace(1)} { ptr addrspace(1) @GI, ptr addrspace(1) @GI } +@GS2 = addrspace(1) global {ptr addrspace(1), ptr addrspace(1)} { ptr addrspace(1) @GS, ptr addrspace(1) @GS } +@GS3 = addrspace(1) global {ptr addrspace(1), ptr addrspace(1)} { ptr addrspace(1) @GS2, ptr addrspace(1) @GS2 } + +@GPS = addrspace(1) global ptr addrspace(1) @GS3 + +@GPI1 = addrspace(1) global ptr addrspace(1) @GI +@GPI2 = addrspace(1) global ptr addrspace(1) @GPI1 +@GPI3 = addrspace(1) global ptr addrspace(1) @GPI2 + +define spir_kernel void @foo() { + ret void +} diff --git a/llvm/test/CodeGen/SPIRV/pointers/struct-opaque-pointers.ll b/llvm/test/CodeGen/SPIRV/pointers/struct-opaque-pointers.ll index ce3ab8895a59..6d4913f802c2 100644 --- a/llvm/test/CodeGen/SPIRV/pointers/struct-opaque-pointers.ll +++ b/llvm/test/CodeGen/SPIRV/pointers/struct-opaque-pointers.ll @@ -1,14 +1,14 @@ ; RUN: llc -O0 -mtriple=spirv32-unknown-unknown %s -o - | FileCheck %s ; RUN: %if spirv-tools %{ llc -O0 -mtriple=spirv32-unknown-unknown %s -o - -filetype=obj | spirv-val %} -; CHECK: %[[TyInt8:.*]] = OpTypeInt 8 0 -; CHECK: %[[TyInt8Ptr:.*]] = OpTypePointer {{[a-zA-Z]+}} %[[TyInt8]] -; CHECK: %[[TyStruct:.*]] = OpTypeStruct %[[TyInt8Ptr]] %[[TyInt8Ptr]] +; CHECK: %[[TyInt64:.*]] = OpTypeInt 64 0 +; CHECK: %[[TyInt64Ptr:.*]] = OpTypePointer {{[a-zA-Z]+}} %[[TyInt64]] +; CHECK: %[[TyStruct:.*]] = OpTypeStruct %[[TyInt64Ptr]] %[[TyInt64Ptr]] ; CHECK: %[[ConstStruct:.*]] = OpConstantComposite %[[TyStruct]] %[[ConstField:.*]] %[[ConstField]] ; CHECK: %[[TyStructPtr:.*]] = OpTypePointer {{[a-zA-Z]+}} %[[TyStruct]] ; CHECK: OpVariable %[[TyStructPtr]] {{[a-zA-Z]+}} %[[ConstStruct]] -@a = addrspace(1) constant i32 123 +@a = addrspace(1) constant i64 42 @struct = addrspace(1) global {ptr addrspace(1), ptr addrspace(1)} { ptr addrspace(1) @a, ptr addrspace(1) @a } define spir_kernel void @foo() { diff --git a/llvm/test/CodeGen/SPIRV/pointers/type-deduce-by-call-chain.ll b/llvm/test/CodeGen/SPIRV/pointers/type-deduce-by-call-chain.ll index 703f1e22a032..1071d3443056 100644 --- a/llvm/test/CodeGen/SPIRV/pointers/type-deduce-by-call-chain.ll +++ b/llvm/test/CodeGen/SPIRV/pointers/type-deduce-by-call-chain.ll @@ -34,6 +34,12 @@ entry: %addr = addrspacecast ptr addrspace(1) %lptr to ptr addrspace(4) %object = bitcast ptr addrspace(4) %addr to ptr addrspace(4) call spir_func void @foo(ptr addrspace(4) %object, i32 3) + %halfptr = getelementptr inbounds half, ptr addrspace(1) %_arg_cum, i64 1 + %halfaddr = addrspacecast ptr addrspace(1) %halfptr to ptr addrspace(4) + call spir_func void @foo(ptr addrspace(4) %halfaddr, i32 3) + %dblptr = getelementptr inbounds double, ptr addrspace(1) %_arg_cum, i64 1 + %dbladdr = addrspacecast ptr addrspace(1) %dblptr to ptr addrspace(4) + call spir_func void @foo(ptr addrspace(4) %dbladdr, i32 3) ret void } @@ -49,4 +55,3 @@ define void @foo(ptr addrspace(4) noundef %foo_object, i32 noundef %mem_order) { tail call void @foo_stub(ptr addrspace(4) noundef %foo_object, i32 noundef %mem_order) ret void } - -- GitLab From 38f5596feda3276a8aa64fc14e074334017088ca Mon Sep 17 00:00:00 2001 From: Haohai Wen Date: Thu, 28 Mar 2024 15:33:01 +0800 Subject: [PATCH 026/788] [LoopRotate] Add test to track update for inaccurate branch weight (#86495) Branch weight from sample-based PGO may be not inaccurate due to sampling. This test tracks such case where updateBranchWeights wraps unsigned. --- .../LoopRotate/update-branch-weights.ll | 42 +++++++++++++++++++ 1 file changed, 42 insertions(+) diff --git a/llvm/test/Transforms/LoopRotate/update-branch-weights.ll b/llvm/test/Transforms/LoopRotate/update-branch-weights.ll index 5d742b64e0ad..acb2038d17bb 100644 --- a/llvm/test/Transforms/LoopRotate/update-branch-weights.ll +++ b/llvm/test/Transforms/LoopRotate/update-branch-weights.ll @@ -232,6 +232,46 @@ loop_exit: ret void } +; BFI_BEFORE-LABEL: block-frequency-info: func6_inaccurate_branch_weight +; BFI_BEFORE: - entry: {{.*}} count = 1024 +; BFI_BEFORE: - loop_header: {{.*}} count = 2047 +; BFI_BEFORE: - loop_body: {{.*}} count = 1023 +; BFI_BEFORE: - loop_exit: {{.*}} count = 1024 + +; BFI_AFTER-LABEL: block-frequency-info: func6_inaccurate_branch_weight +; BFI_AFTER: - entry: {{.*}} count = 1024 +; BFI_AFTER: - loop_body: {{.*}} count = 4294967296 +; BFI_AFTER: - loop_exit: {{.*}} count = 1024 + +; IR-LABEL: define void @func6_inaccurate_branch_weight( +; IR: entry: +; IR: br label %loop_body +; IR: loop_body: +; IR: br i1 %cmp, label %loop_body, label %loop_exit, !prof [[PROF_FUNC6_0:![0-9]+]] +; IR: loop_exit: +; IR: ret void + +; Branch weight from sample-based PGO may be inaccurate due to sampling. +; Count for loop_body in following case should be not less than loop_exit. +; However this may not hold for Sample-based PGO. +define void @func6_inaccurate_branch_weight() !prof !3 { +entry: + br label %loop_header + +loop_header: + %i = phi i32 [0, %entry], [%i_inc, %loop_body] + %cmp = icmp slt i32 %i, 2 + br i1 %cmp, label %loop_body, label %loop_exit, !prof !9 + +loop_body: + store volatile i32 %i, ptr @g, align 4 + %i_inc = add i32 %i, 1 + br label %loop_header + +loop_exit: + ret void +} + !0 = !{!"function_entry_count", i64 1} !1 = !{!"branch_weights", i32 1000, i32 1} !2 = !{!"branch_weights", i32 3000, i32 1000} @@ -241,6 +281,7 @@ loop_exit: !6 = !{!"branch_weights", i32 0, i32 1} !7 = !{!"branch_weights", i32 1, i32 0} !8 = !{!"branch_weights", i32 0, i32 0} +!9 = !{!"branch_weights", i32 1023, i32 1024} ; IR: [[PROF_FUNC0_0]] = !{!"branch_weights", i32 2000, i32 1000} ; IR: [[PROF_FUNC0_1]] = !{!"branch_weights", i32 999, i32 1} @@ -251,3 +292,4 @@ loop_exit: ; IR: [[PROF_FUNC3_0]] = !{!"branch_weights", i32 0, i32 1} ; IR: [[PROF_FUNC4_0]] = !{!"branch_weights", i32 1, i32 0} ; IR: [[PROF_FUNC5_0]] = !{!"branch_weights", i32 0, i32 0} +; IR: [[PROF_FUNC6_0]] = !{!"branch_weights", i32 -1, i32 1024} -- GitLab From 63ea5a4088ff73a47cd3411fad3b42c92a3c64f0 Mon Sep 17 00:00:00 2001 From: Haojian Wu Date: Thu, 28 Mar 2024 09:13:26 +0100 Subject: [PATCH 027/788] [clang] Invalidate the alias template decl if it has multiple written template parameter lists. (#85413) Fixes #85406. - Set the invalid bit for alias template decl where it has multiple written template parameter lists (as the AST node is ill-formed) - don't perform CTAD for invalid alias template decls --- clang/lib/Sema/SemaDeclCXX.cpp | 1 + clang/lib/Sema/SemaTemplate.cpp | 2 ++ clang/test/AST/ast-dump-invalid.cpp | 9 +++++++++ clang/test/SemaCXX/cxx20-ctad-type-alias.cpp | 12 ++++++++++++ 4 files changed, 24 insertions(+) diff --git a/clang/lib/Sema/SemaDeclCXX.cpp b/clang/lib/Sema/SemaDeclCXX.cpp index e9fecaea84b0..f32ff396f8a5 100644 --- a/clang/lib/Sema/SemaDeclCXX.cpp +++ b/clang/lib/Sema/SemaDeclCXX.cpp @@ -13589,6 +13589,7 @@ Decl *Sema::ActOnAliasDeclaration(Scope *S, AccessSpecifier AS, Diag(UsingLoc, diag::err_alias_template_extra_headers) << SourceRange(TemplateParamLists[1]->getTemplateLoc(), TemplateParamLists[TemplateParamLists.size()-1]->getRAngleLoc()); + Invalid = true; } TemplateParameterList *TemplateParams = TemplateParamLists[0]; diff --git a/clang/lib/Sema/SemaTemplate.cpp b/clang/lib/Sema/SemaTemplate.cpp index aab72dbaf48c..e575bb2df97f 100644 --- a/clang/lib/Sema/SemaTemplate.cpp +++ b/clang/lib/Sema/SemaTemplate.cpp @@ -2731,6 +2731,8 @@ bool hasDeclaredDeductionGuides(DeclarationName Name, DeclContext *DC) { // Build deduction guides for a type alias template. void DeclareImplicitDeductionGuidesForTypeAlias( Sema &SemaRef, TypeAliasTemplateDecl *AliasTemplate, SourceLocation Loc) { + if (AliasTemplate->isInvalidDecl()) + return; auto &Context = SemaRef.Context; // FIXME: if there is an explicit deduction guide after the first use of the // type alias usage, we will not cover this explicit deduction guide. fix this diff --git a/clang/test/AST/ast-dump-invalid.cpp b/clang/test/AST/ast-dump-invalid.cpp index 0a301dba51d2..5b6d74194b98 100644 --- a/clang/test/AST/ast-dump-invalid.cpp +++ b/clang/test/AST/ast-dump-invalid.cpp @@ -60,3 +60,12 @@ double Str::foo1(double, invalid_type) // CHECK-NEXT: `-ReturnStmt {{.*}} // CHECK-NEXT: `-ImplicitCastExpr {{.*}} 'double' // CHECK-NEXT: `-IntegerLiteral {{.*}} 'int' 45 + +namespace TestAliasTemplateDecl { +template class A; + +template +template using InvalidAlias = A; +// CHECK: TypeAliasTemplateDecl {{.*}} invalid InvalidAlias +// CHECK-NEXT: |-TemplateTypeParmDecl {{.*}} typename depth 0 index 0 T +} diff --git a/clang/test/SemaCXX/cxx20-ctad-type-alias.cpp b/clang/test/SemaCXX/cxx20-ctad-type-alias.cpp index 3ce26c8fcd98..ce403285b0f5 100644 --- a/clang/test/SemaCXX/cxx20-ctad-type-alias.cpp +++ b/clang/test/SemaCXX/cxx20-ctad-type-alias.cpp @@ -247,3 +247,15 @@ using Bar = Foo; // expected-note {{could not match 'Foo' Bar s = {1}; // expected-error {{no viable constructor or deduction guide for deduction of template arguments}} } // namespace test18 + +// GH85406, verify no crash on invalid alias templates. +namespace test19 { +template +class Foo {}; + +template +template +using Bar2 = Foo; // expected-error {{extraneous template parameter list in alias template declaration}} + +Bar2 b = 1; // expected-error {{no viable constructor or deduction guide for deduction of template arguments}} +} // namespace test19 -- GitLab From 2a2fd488b6bc1f3df7a8c103f53fec8bf849da4a Mon Sep 17 00:00:00 2001 From: Orlando Cazalet-Hyams Date: Thu, 28 Mar 2024 08:54:27 +0000 Subject: [PATCH 028/788] [RemoveDIs] Update DIBuilder C API and OCaml bindings [2/2] (#86529) Follow on from #84915 which adds the DbgRecord function variants. The C API changes were reviewed in #85657. # C API Update the LLVMDIBuilderInsert... functions to insert DbgRecords instead of debug intrinsics. LLVMDIBuilderInsertDeclareBefore LLVMDIBuilderInsertDeclareAtEnd LLVMDIBuilderInsertDbgValueBefore LLVMDIBuilderInsertDbgValueAtEnd Calling these functions will now cause an assertion if the module is in the wrong debug info format. They should only be used when the module is in "new debug format". Use LLVMIsNewDbgInfoFormat to query and LLVMSetIsNewDbgInfoFormat to change the debug info format of a module. Please see https://llvm.org/docs/RemoveDIsDebugInfo.html#c-api-change (RemoveDIsDebugInfo.md) for more info. # OCaml bindings Add set_is_new_dbg_info_format and is_new_dbg_info_format to the OCaml bindings. These can be used to set and query the current debug info mode. These will eventually be removed, but are useful while we're transitioning between old and new debug info formats. Add string_of_lldbgrecord, like string_of_llvalue but prints DbgRecords. In test dbginfo.ml, unconditionally set the module debug info to the new mode and update CHECK lines to check for DbgRecords. Without this change the test crashes because it attempts to insert DbgRecords (new default behaviour of llvm_dibuild_insert_declare_...) into a module that is in the old debug info mode. --- .../ocaml/debuginfo/debuginfo_ocaml.c | 15 ++- .../ocaml/debuginfo/llvm_debuginfo.ml | 10 +- .../ocaml/debuginfo/llvm_debuginfo.mli | 10 +- llvm/bindings/ocaml/llvm/llvm.ml | 2 + llvm/bindings/ocaml/llvm/llvm.mli | 6 + llvm/bindings/ocaml/llvm/llvm_ocaml.c | 9 ++ llvm/bindings/ocaml/llvm/llvm_ocaml.h | 1 + llvm/docs/RemoveDIsDebugInfo.md | 11 +- llvm/include/llvm-c/Core.h | 8 ++ llvm/include/llvm-c/DebugInfo.h | 60 ++++++--- llvm/lib/IR/Core.cpp | 14 ++ llvm/lib/IR/DebugInfo.cpp | 121 ++++++++++++------ llvm/test/Bindings/OCaml/debuginfo.ml | 10 +- llvm/tools/llvm-c-test/debuginfo.c | 13 +- 14 files changed, 212 insertions(+), 78 deletions(-) diff --git a/llvm/bindings/ocaml/debuginfo/debuginfo_ocaml.c b/llvm/bindings/ocaml/debuginfo/debuginfo_ocaml.c index a793e893524f..fbe45c0c1e0b 100644 --- a/llvm/bindings/ocaml/debuginfo/debuginfo_ocaml.c +++ b/llvm/bindings/ocaml/debuginfo/debuginfo_ocaml.c @@ -972,7 +972,7 @@ value llvm_dibuild_create_parameter_variable_bytecode(value *argv, int arg) { value llvm_dibuild_insert_declare_before_native(value Builder, value Storage, value VarInfo, value Expr, value DebugLoc, value Instr) { - LLVMValueRef Value = LLVMDIBuilderInsertDeclareBefore( + LLVMDbgRecordRef Value = LLVMDIBuilderInsertDeclareBefore( DIBuilder_val(Builder), Value_val(Storage), Metadata_val(VarInfo), Metadata_val(Expr), Metadata_val(DebugLoc), Value_val(Instr)); return to_val(Value); @@ -992,7 +992,7 @@ value llvm_dibuild_insert_declare_before_bytecode(value *argv, int arg) { value llvm_dibuild_insert_declare_at_end_native(value Builder, value Storage, value VarInfo, value Expr, value DebugLoc, value Block) { - LLVMValueRef Value = LLVMDIBuilderInsertDeclareAtEnd( + LLVMDbgRecordRef Value = LLVMDIBuilderInsertDeclareAtEnd( DIBuilder_val(Builder), Value_val(Storage), Metadata_val(VarInfo), Metadata_val(Expr), Metadata_val(DebugLoc), BasicBlock_val(Block)); return to_val(Value); @@ -1012,3 +1012,14 @@ value llvm_dibuild_expression(value Builder, value Addr) { return to_val(LLVMDIBuilderCreateExpression( DIBuilder_val(Builder), (uint64_t *)Op_val(Addr), Wosize_val(Addr))); } + +/* llmodule -> bool */ +value llvm_is_new_dbg_info_format(value Module) { + return Val_bool(LLVMIsNewDbgInfoFormat(Module_val(Module))); +} + +/* llmodule -> bool -> unit */ +value llvm_set_is_new_dbg_info_format(value Module, value UseNewFormat) { + LLVMSetIsNewDbgInfoFormat(Module_val(Module), Bool_val(UseNewFormat)); + return Val_unit; +} diff --git a/llvm/bindings/ocaml/debuginfo/llvm_debuginfo.ml b/llvm/bindings/ocaml/debuginfo/llvm_debuginfo.ml index a6d74ed0eb81..8bb5edb17a2c 100644 --- a/llvm/bindings/ocaml/debuginfo/llvm_debuginfo.ml +++ b/llvm/bindings/ocaml/debuginfo/llvm_debuginfo.ml @@ -599,7 +599,7 @@ external dibuild_insert_declare_before : expr:Llvm.llmetadata -> location:Llvm.llmetadata -> instr:Llvm.llvalue -> - Llvm.llvalue + Llvm.lldbgrecord = "llvm_dibuild_insert_declare_before_bytecode" "llvm_dibuild_insert_declare_before_native" external dibuild_insert_declare_at_end : @@ -609,7 +609,7 @@ external dibuild_insert_declare_at_end : expr:Llvm.llmetadata -> location:Llvm.llmetadata -> block:Llvm.llbasicblock -> - Llvm.llvalue + Llvm.lldbgrecord = "llvm_dibuild_insert_declare_at_end_bytecode" "llvm_dibuild_insert_declare_at_end_native" external dibuild_expression : @@ -617,3 +617,9 @@ external dibuild_expression : Int64.t array -> Llvm.llmetadata = "llvm_dibuild_expression" + +external is_new_dbg_info_format : Llvm.llmodule -> bool + = "llvm_is_new_dbg_info_format" + +external set_is_new_dbg_info_format : Llvm.llmodule -> bool -> unit + = "llvm_set_is_new_dbg_info_format" diff --git a/llvm/bindings/ocaml/debuginfo/llvm_debuginfo.mli b/llvm/bindings/ocaml/debuginfo/llvm_debuginfo.mli index e92778b07589..7c7882ccce85 100644 --- a/llvm/bindings/ocaml/debuginfo/llvm_debuginfo.mli +++ b/llvm/bindings/ocaml/debuginfo/llvm_debuginfo.mli @@ -659,7 +659,7 @@ val dibuild_insert_declare_before : expr:Llvm.llmetadata -> location:Llvm.llmetadata -> instr:Llvm.llvalue -> - Llvm.llvalue + Llvm.lldbgrecord (** [dibuild_insert_declare_before] Insert a new llvm.dbg.declare intrinsic call before the given instruction [instr]. *) @@ -670,7 +670,7 @@ val dibuild_insert_declare_at_end : expr:Llvm.llmetadata -> location:Llvm.llmetadata -> block:Llvm.llbasicblock -> - Llvm.llvalue + Llvm.lldbgrecord (** [dibuild_insert_declare_at_end] Insert a new llvm.dbg.declare intrinsic call at the end of basic block [block]. If [block] has a terminator instruction, the intrinsic is inserted @@ -680,3 +680,9 @@ val dibuild_expression : lldibuilder -> Int64.t array -> Llvm.llmetadata (** [dibuild_expression] Create a new descriptor for the specified variable which has a complex address expression for its address. See LLVMDIBuilderCreateExpression. *) + +val is_new_dbg_info_format : Llvm.llmodule -> bool +(** [is_new_dbg_info_format] See LLVMIsNewDbgInfoFormat *) + +val set_is_new_dbg_info_format : Llvm.llmodule -> bool -> unit +(** [set_is_new_dbg_info_format] See LLVMSetIsNewDbgInfoFormat *) diff --git a/llvm/bindings/ocaml/llvm/llvm.ml b/llvm/bindings/ocaml/llvm/llvm.ml index 057798fc0cea..003fd750cd9f 100644 --- a/llvm/bindings/ocaml/llvm/llvm.ml +++ b/llvm/bindings/ocaml/llvm/llvm.ml @@ -12,6 +12,7 @@ type llmodule type llmetadata type lltype type llvalue +type lldbgrecord type lluse type llbasicblock type llbuilder @@ -528,6 +529,7 @@ external value_name : llvalue -> string = "llvm_value_name" external set_value_name : string -> llvalue -> unit = "llvm_set_value_name" external dump_value : llvalue -> unit = "llvm_dump_value" external string_of_llvalue : llvalue -> string = "llvm_string_of_llvalue" +external string_of_lldbgrecord : lldbgrecord -> string = "llvm_string_of_lldbgrecord" external replace_all_uses_with : llvalue -> llvalue -> unit = "llvm_replace_all_uses_with" diff --git a/llvm/bindings/ocaml/llvm/llvm.mli b/llvm/bindings/ocaml/llvm/llvm.mli index e0febb79a2b6..93540c619efb 100644 --- a/llvm/bindings/ocaml/llvm/llvm.mli +++ b/llvm/bindings/ocaml/llvm/llvm.mli @@ -36,6 +36,9 @@ type lltype This type covers a wide range of subclasses. *) type llvalue +(** Non-instruction debug info record. See the [llvm::DbgRecord] class.*) +type lldbgrecord + (** Used to store users and usees of values. See the [llvm::Use] class. *) type lluse @@ -793,6 +796,9 @@ val dump_value : llvalue -> unit (** [string_of_llvalue v] returns a string describing the value [v]. *) val string_of_llvalue : llvalue -> string +(** [string_of_lldbgrecord r] returns a string describing the DbgRecord [r]. *) +val string_of_lldbgrecord : lldbgrecord -> string + (** [replace_all_uses_with old new] replaces all uses of the value [old] with the value [new]. See the method [llvm::Value::replaceAllUsesWith]. *) val replace_all_uses_with : llvalue -> llvalue -> unit diff --git a/llvm/bindings/ocaml/llvm/llvm_ocaml.c b/llvm/bindings/ocaml/llvm/llvm_ocaml.c index 55679f218b30..6d08d78b8445 100644 --- a/llvm/bindings/ocaml/llvm/llvm_ocaml.c +++ b/llvm/bindings/ocaml/llvm/llvm_ocaml.c @@ -800,6 +800,15 @@ value llvm_string_of_llvalue(value M) { return ValueStr; } +/* lldbgrecord -> string */ +value llvm_string_of_lldbgrecord(value Record) { + char *ValueCStr = LLVMPrintDbgRecordToString(DbgRecord_val(Record)); + value ValueStr = caml_copy_string(ValueCStr); + LLVMDisposeMessage(ValueCStr); + + return ValueStr; +} + /* llvalue -> llvalue -> unit */ value llvm_replace_all_uses_with(value OldVal, value NewVal) { LLVMReplaceAllUsesWith(Value_val(OldVal), Value_val(NewVal)); diff --git a/llvm/bindings/ocaml/llvm/llvm_ocaml.h b/llvm/bindings/ocaml/llvm/llvm_ocaml.h index a3791744e647..ec60d6a5dad6 100644 --- a/llvm/bindings/ocaml/llvm/llvm_ocaml.h +++ b/llvm/bindings/ocaml/llvm/llvm_ocaml.h @@ -53,6 +53,7 @@ void *from_val_array(value Elements); #define Metadata_val(v) ((LLVMMetadataRef)from_val(v)) #define Type_val(v) ((LLVMTypeRef)from_val(v)) #define Value_val(v) ((LLVMValueRef)from_val(v)) +#define DbgRecord_val(v) ((LLVMDbgRecordRef)from_val(v)) #define Use_val(v) ((LLVMUseRef)from_val(v)) #define BasicBlock_val(v) ((LLVMBasicBlockRef)from_val(v)) #define MemoryBuffer_val(v) ((LLVMMemoryBufferRef)from_val(v)) diff --git a/llvm/docs/RemoveDIsDebugInfo.md b/llvm/docs/RemoveDIsDebugInfo.md index a2f1e173d9d9..9e50a2a604aa 100644 --- a/llvm/docs/RemoveDIsDebugInfo.md +++ b/llvm/docs/RemoveDIsDebugInfo.md @@ -40,15 +40,22 @@ New functions (all to be deprecated) LLVMIsNewDbgInfoFormat # Returns true if the module is in the new non-instruction mode. LLVMSetIsNewDbgInfoFormat # Convert to the requested debug info format. -LLVMDIBuilderInsertDeclareIntrinsicBefore # Insert a debug intrinsic (old debug info format). +LLVMDIBuilderInsertDeclareIntrinsicBefore # Insert a debug intrinsic (old debug info format). LLVMDIBuilderInsertDeclareIntrinsicAtEnd # Same as above. LLVMDIBuilderInsertDbgValueIntrinsicBefore # Same as above. LLVMDIBuilderInsertDbgValueIntrinsicAtEnd # Same as above. -LLVMDIBuilderInsertDeclareRecordBefore # Insert a debug record (new debug info format). +LLVMDIBuilderInsertDeclareRecordBefore # Insert a debug record (new debug info format). LLVMDIBuilderInsertDeclareRecordAtEnd # Same as above. LLVMDIBuilderInsertDbgValueRecordBefore # Same as above. LLVMDIBuilderInsertDbgValueRecordAtEnd # Same as above. + +Existing functions (behaviour change) +------------------------------------- +LLVMDIBuilderInsertDeclareBefore # Insert a debug record (new debug info format) instead of a debug intrinsic (old debug info format). +LLVMDIBuilderInsertDeclareAtEnd # Same as above. +LLVMDIBuilderInsertDbgValueBefore # Same as above. +LLVMDIBuilderInsertDbgValueAtEnd # Same as above. ``` # Anything else? diff --git a/llvm/include/llvm-c/Core.h b/llvm/include/llvm-c/Core.h index 254c298abe4b..6be5957ce610 100644 --- a/llvm/include/llvm-c/Core.h +++ b/llvm/include/llvm-c/Core.h @@ -1866,6 +1866,14 @@ void LLVMDumpValue(LLVMValueRef Val); */ char *LLVMPrintValueToString(LLVMValueRef Val); +/** + * Return a string representation of the DbgRecord. Use + * LLVMDisposeMessage to free the string. + * + * @see llvm::DbgRecord::print() + */ +char *LLVMPrintDbgRecordToString(LLVMDbgRecordRef Record); + /** * Replace all uses of a value with another one. * diff --git a/llvm/include/llvm-c/DebugInfo.h b/llvm/include/llvm-c/DebugInfo.h index b23ff63c862f..dab1d697761b 100644 --- a/llvm/include/llvm-c/DebugInfo.h +++ b/llvm/include/llvm-c/DebugInfo.h @@ -1249,7 +1249,12 @@ LLVMMetadataRef LLVMDIBuilderCreateTempGlobalVariableFwdDecl( LLVMMetadataRef Decl, uint32_t AlignInBits); /* - * Insert a new llvm.dbg.declare intrinsic call before the given instruction. + * Insert a new Declare DbgRecord before the given instruction. + * + * Only use in "new debug mode" (LLVMIsNewDbgInfoFormat() is true). + * Use LLVMSetIsNewDbgInfoFormat(LLVMBool) to convert between formats. + * See https://llvm.org/docs/RemoveDIsDebugInfo.html#c-api-changes + * * \param Builder The DIBuilder. * \param Storage The storage of the variable to declare. * \param VarInfo The variable's debug info descriptor. @@ -1257,13 +1262,13 @@ LLVMMetadataRef LLVMDIBuilderCreateTempGlobalVariableFwdDecl( * \param DebugLoc Debug info location. * \param Instr Instruction acting as a location for the new intrinsic. */ -LLVMValueRef +LLVMDbgRecordRef LLVMDIBuilderInsertDeclareBefore(LLVMDIBuilderRef Builder, LLVMValueRef Storage, LLVMMetadataRef VarInfo, LLVMMetadataRef Expr, LLVMMetadataRef DebugLoc, LLVMValueRef Instr); /** * Soon to be deprecated. - * Only use in "old debug mode" (LLVMIsNewDbgFormat() is false). + * Only use in "old debug mode" (LLVMIsNewDbgInfoFormat() is false). * See https://llvm.org/docs/RemoveDIsDebugInfo.html#c-api-changes * * Insert a new llvm.dbg.declare intrinsic call before the given instruction. @@ -1279,7 +1284,7 @@ LLVMValueRef LLVMDIBuilderInsertDeclareIntrinsicBefore( LLVMMetadataRef Expr, LLVMMetadataRef DebugLoc, LLVMValueRef Instr); /** * Soon to be deprecated. - * Only use in "new debug mode" (LLVMIsNewDbgFormat() is true). + * Only use in "new debug mode" (LLVMIsNewDbgInfoFormat() is true). * See https://llvm.org/docs/RemoveDIsDebugInfo.html#c-api-changes * * Insert a Declare DbgRecord before the given instruction. @@ -1295,9 +1300,14 @@ LLVMDbgRecordRef LLVMDIBuilderInsertDeclareRecordBefore( LLVMMetadataRef Expr, LLVMMetadataRef DebugLoc, LLVMValueRef Instr); /** - * Insert a new llvm.dbg.declare intrinsic call at the end of the given basic - * block. If the basic block has a terminator instruction, the intrinsic is - * inserted before that terminator instruction. + * Insert a new Declare DbgRecord at the end of the given basic block. If the + * basic block has a terminator instruction, the intrinsic is inserted before + * that terminator instruction. + * + * Only use in "new debug mode" (LLVMIsNewDbgInfoFormat() is true). + * Use LLVMSetIsNewDbgInfoFormat(LLVMBool) to convert between formats. + * See https://llvm.org/docs/RemoveDIsDebugInfo.html#c-api-changes + * * \param Builder The DIBuilder. * \param Storage The storage of the variable to declare. * \param VarInfo The variable's debug info descriptor. @@ -1305,12 +1315,12 @@ LLVMDbgRecordRef LLVMDIBuilderInsertDeclareRecordBefore( * \param DebugLoc Debug info location. * \param Block Basic block acting as a location for the new intrinsic. */ -LLVMValueRef LLVMDIBuilderInsertDeclareAtEnd( +LLVMDbgRecordRef LLVMDIBuilderInsertDeclareAtEnd( LLVMDIBuilderRef Builder, LLVMValueRef Storage, LLVMMetadataRef VarInfo, LLVMMetadataRef Expr, LLVMMetadataRef DebugLoc, LLVMBasicBlockRef Block); /** * Soon to be deprecated. - * Only use in "old debug mode" (LLVMIsNewDbgFormat() is false). + * Only use in "old debug mode" (LLVMIsNewDbgInfoFormat() is false). * See https://llvm.org/docs/RemoveDIsDebugInfo.html#c-api-changes * * Insert a new llvm.dbg.declare intrinsic call at the end of the given basic @@ -1328,7 +1338,7 @@ LLVMValueRef LLVMDIBuilderInsertDeclareIntrinsicAtEnd( LLVMMetadataRef Expr, LLVMMetadataRef DebugLoc, LLVMBasicBlockRef Block); /** * Soon to be deprecated. - * Only use in "new debug mode" (LLVMIsNewDbgFormat() is true). + * Only use in "new debug mode" (LLVMIsNewDbgInfoFormat() is true). * See https://llvm.org/docs/RemoveDIsDebugInfo.html#c-api-changes * * Insert a Declare DbgRecord at the end of the given basic block. If the basic @@ -1346,7 +1356,12 @@ LLVMDbgRecordRef LLVMDIBuilderInsertDeclareRecordAtEnd( LLVMMetadataRef Expr, LLVMMetadataRef DebugLoc, LLVMBasicBlockRef Block); /** - * Insert a new llvm.dbg.value intrinsic call before the given instruction. + * Insert a new Value DbgRecord before the given instruction. + * + * Only use in "new debug mode" (LLVMIsNewDbgInfoFormat() is true). + * Use LLVMSetIsNewDbgInfoFormat(LLVMBool) to convert between formats. + * See https://llvm.org/docs/RemoveDIsDebugInfo.html#c-api-changes + * * \param Builder The DIBuilder. * \param Val The value of the variable. * \param VarInfo The variable's debug info descriptor. @@ -1354,13 +1369,13 @@ LLVMDbgRecordRef LLVMDIBuilderInsertDeclareRecordAtEnd( * \param DebugLoc Debug info location. * \param Instr Instruction acting as a location for the new intrinsic. */ -LLVMValueRef +LLVMDbgRecordRef LLVMDIBuilderInsertDbgValueBefore(LLVMDIBuilderRef Builder, LLVMValueRef Val, LLVMMetadataRef VarInfo, LLVMMetadataRef Expr, LLVMMetadataRef DebugLoc, LLVMValueRef Instr); /** * Soon to be deprecated. - * Only use in "old debug mode" (Module::IsNewDbgInfoFormat is false). + * Only use in "old debug mode" (LLVMIsNewDbgInfoFormat() is false). * See https://llvm.org/docs/RemoveDIsDebugInfo.html#c-api-changes * * Insert a new llvm.dbg.value intrinsic call before the given instruction. @@ -1376,7 +1391,7 @@ LLVMValueRef LLVMDIBuilderInsertDbgValueIntrinsicBefore( LLVMMetadataRef Expr, LLVMMetadataRef DebugLoc, LLVMValueRef Instr); /** * Soon to be deprecated. - * Only use in "new debug mode" (Module::IsNewDbgInfoFormat is true). + * Only use in "new debug mode" (LLVMIsNewDbgInfoFormat() is true). * See https://llvm.org/docs/RemoveDIsDebugInfo.html#c-api-changes * * Insert a new llvm.dbg.value intrinsic call before the given instruction. @@ -1392,9 +1407,14 @@ LLVMDbgRecordRef LLVMDIBuilderInsertDbgValueRecordBefore( LLVMMetadataRef Expr, LLVMMetadataRef DebugLoc, LLVMValueRef Instr); /** - * Insert a new llvm.dbg.value intrinsic call at the end of the given basic - * block. If the basic block has a terminator instruction, the intrinsic is - * inserted before that terminator instruction. + * Insert a new Value DbgRecord at the end of the given basic block. If the + * basic block has a terminator instruction, the intrinsic is inserted before + * that terminator instruction. + * + * Only use in "new debug mode" (LLVMIsNewDbgInfoFormat() is true). + * Use LLVMSetIsNewDbgInfoFormat(LLVMBool) to convert between formats. + * See https://llvm.org/docs/RemoveDIsDebugInfo.html#c-api-changes + * * \param Builder The DIBuilder. * \param Val The value of the variable. * \param VarInfo The variable's debug info descriptor. @@ -1402,12 +1422,12 @@ LLVMDbgRecordRef LLVMDIBuilderInsertDbgValueRecordBefore( * \param DebugLoc Debug info location. * \param Block Basic block acting as a location for the new intrinsic. */ -LLVMValueRef LLVMDIBuilderInsertDbgValueAtEnd( +LLVMDbgRecordRef LLVMDIBuilderInsertDbgValueAtEnd( LLVMDIBuilderRef Builder, LLVMValueRef Val, LLVMMetadataRef VarInfo, LLVMMetadataRef Expr, LLVMMetadataRef DebugLoc, LLVMBasicBlockRef Block); /** * Soon to be deprecated. - * Only use in "old debug mode" (Module::IsNewDbgInfoFormat is false). + * Only use in "old debug mode" (LLVMIsNewDbgInfoFormat() is false). * See https://llvm.org/docs/RemoveDIsDebugInfo.html#c-api-changes * * Insert a new llvm.dbg.value intrinsic call at the end of the given basic @@ -1425,7 +1445,7 @@ LLVMValueRef LLVMDIBuilderInsertDbgValueIntrinsicAtEnd( LLVMMetadataRef Expr, LLVMMetadataRef DebugLoc, LLVMBasicBlockRef Block); /** * Soon to be deprecated. - * Only use in "new debug mode" (Module::IsNewDbgInfoFormat is true). + * Only use in "new debug mode" (LLVMIsNewDbgInfoFormat() is true). * See https://llvm.org/docs/RemoveDIsDebugInfo.html#c-api-changes * * Insert a new llvm.dbg.value intrinsic call at the end of the given basic diff --git a/llvm/lib/IR/Core.cpp b/llvm/lib/IR/Core.cpp index 3aee61957252..8ce9c5ca63be 100644 --- a/llvm/lib/IR/Core.cpp +++ b/llvm/lib/IR/Core.cpp @@ -990,6 +990,20 @@ char* LLVMPrintValueToString(LLVMValueRef Val) { return strdup(buf.c_str()); } +char *LLVMPrintDbgRecordToString(LLVMDbgRecordRef Record) { + std::string buf; + raw_string_ostream os(buf); + + if (unwrap(Record)) + unwrap(Record)->print(os); + else + os << "Printing DbgRecord"; + + os.flush(); + + return strdup(buf.c_str()); +} + void LLVMReplaceAllUsesWith(LLVMValueRef OldVal, LLVMValueRef NewVal) { unwrap(OldVal)->replaceAllUsesWith(unwrap(NewVal)); } diff --git a/llvm/lib/IR/DebugInfo.cpp b/llvm/lib/IR/DebugInfo.cpp index 09bce9df1f33..4206162d1768 100644 --- a/llvm/lib/IR/DebugInfo.cpp +++ b/llvm/lib/IR/DebugInfo.cpp @@ -1665,12 +1665,12 @@ LLVMMetadataRef LLVMDIBuilderCreateTempGlobalVariableFwdDecl( unwrapDI(Decl), nullptr, AlignInBits)); } -LLVMValueRef +LLVMDbgRecordRef LLVMDIBuilderInsertDeclareBefore(LLVMDIBuilderRef Builder, LLVMValueRef Storage, LLVMMetadataRef VarInfo, LLVMMetadataRef Expr, LLVMMetadataRef DL, LLVMValueRef Instr) { - return LLVMDIBuilderInsertDeclareIntrinsicBefore(Builder, Storage, VarInfo, - Expr, DL, Instr); + return LLVMDIBuilderInsertDeclareRecordBefore(Builder, Storage, VarInfo, Expr, + DL, Instr); } LLVMValueRef LLVMDIBuilderInsertDeclareIntrinsicBefore( LLVMDIBuilderRef Builder, LLVMValueRef Storage, LLVMMetadataRef VarInfo, @@ -1679,27 +1679,38 @@ LLVMValueRef LLVMDIBuilderInsertDeclareIntrinsicBefore( unwrap(Storage), unwrap(VarInfo), unwrap(Expr), unwrap(DL), unwrap(Instr)); + // This assert will fail if the module is in the new debug info format. + // This function should only be called if the module is in the old + // debug info format. + // See https://llvm.org/docs/RemoveDIsDebugInfo.html#c-api-changes, + // LLVMIsNewDbgInfoFormat, and LLVMSetIsNewDbgInfoFormat for more info. assert(isa(DbgInst) && - "Inserted a DbgRecord into function using old debug info mode"); + "Function unexpectedly in new debug info format"); return wrap(cast(DbgInst)); } LLVMDbgRecordRef LLVMDIBuilderInsertDeclareRecordBefore( LLVMDIBuilderRef Builder, LLVMValueRef Storage, LLVMMetadataRef VarInfo, LLVMMetadataRef Expr, LLVMMetadataRef DL, LLVMValueRef Instr) { - return wrap( - unwrap(Builder) - ->insertDeclare(unwrap(Storage), unwrap(VarInfo), - unwrap(Expr), unwrap(DL), - unwrap(Instr)) - .get()); + DbgInstPtr DbgInst = unwrap(Builder)->insertDeclare( + unwrap(Storage), unwrap(VarInfo), + unwrap(Expr), unwrap(DL), + unwrap(Instr)); + // This assert will fail if the module is in the old debug info format. + // This function should only be called if the module is in the new + // debug info format. + // See https://llvm.org/docs/RemoveDIsDebugInfo.html#c-api-changes, + // LLVMIsNewDbgInfoFormat, and LLVMSetIsNewDbgInfoFormat for more info. + assert(isa(DbgInst) && + "Function unexpectedly in old debug info format"); + return wrap(cast(DbgInst)); } -LLVMValueRef +LLVMDbgRecordRef LLVMDIBuilderInsertDeclareAtEnd(LLVMDIBuilderRef Builder, LLVMValueRef Storage, LLVMMetadataRef VarInfo, LLVMMetadataRef Expr, LLVMMetadataRef DL, LLVMBasicBlockRef Block) { - return LLVMDIBuilderInsertDeclareIntrinsicAtEnd(Builder, Storage, VarInfo, - Expr, DL, Block); + return LLVMDIBuilderInsertDeclareRecordAtEnd(Builder, Storage, VarInfo, Expr, + DL, Block); } LLVMValueRef LLVMDIBuilderInsertDeclareIntrinsicAtEnd( LLVMDIBuilderRef Builder, LLVMValueRef Storage, LLVMMetadataRef VarInfo, @@ -1707,26 +1718,36 @@ LLVMValueRef LLVMDIBuilderInsertDeclareIntrinsicAtEnd( DbgInstPtr DbgInst = unwrap(Builder)->insertDeclare( unwrap(Storage), unwrap(VarInfo), unwrap(Expr), unwrap(DL), unwrap(Block)); + // This assert will fail if the module is in the new debug info format. + // This function should only be called if the module is in the old + // debug info format. + // See https://llvm.org/docs/RemoveDIsDebugInfo.html#c-api-changes, + // LLVMIsNewDbgInfoFormat, and LLVMSetIsNewDbgInfoFormat for more info. assert(isa(DbgInst) && - "Inserted a DbgRecord into function using old debug info mode"); + "Function unexpectedly in new debug info format"); return wrap(cast(DbgInst)); } LLVMDbgRecordRef LLVMDIBuilderInsertDeclareRecordAtEnd( LLVMDIBuilderRef Builder, LLVMValueRef Storage, LLVMMetadataRef VarInfo, LLVMMetadataRef Expr, LLVMMetadataRef DL, LLVMBasicBlockRef Block) { - return wrap(unwrap(Builder) - ->insertDeclare(unwrap(Storage), - unwrap(VarInfo), - unwrap(Expr), - unwrap(DL), unwrap(Block)) - .get()); + DbgInstPtr DbgInst = unwrap(Builder)->insertDeclare( + unwrap(Storage), unwrap(VarInfo), + unwrap(Expr), unwrap(DL), unwrap(Block)); + // This assert will fail if the module is in the old debug info format. + // This function should only be called if the module is in the new + // debug info format. + // See https://llvm.org/docs/RemoveDIsDebugInfo.html#c-api-changes, + // LLVMIsNewDbgInfoFormat, and LLVMSetIsNewDbgInfoFormat for more info. + assert(isa(DbgInst) && + "Function unexpectedly in old debug info format"); + return wrap(cast(DbgInst)); } -LLVMValueRef LLVMDIBuilderInsertDbgValueBefore( +LLVMDbgRecordRef LLVMDIBuilderInsertDbgValueBefore( LLVMDIBuilderRef Builder, LLVMValueRef Val, LLVMMetadataRef VarInfo, LLVMMetadataRef Expr, LLVMMetadataRef DebugLoc, LLVMValueRef Instr) { - return LLVMDIBuilderInsertDbgValueIntrinsicBefore(Builder, Val, VarInfo, Expr, - DebugLoc, Instr); + return LLVMDIBuilderInsertDbgValueRecordBefore(Builder, Val, VarInfo, Expr, + DebugLoc, Instr); } LLVMValueRef LLVMDIBuilderInsertDbgValueIntrinsicBefore( LLVMDIBuilderRef Builder, LLVMValueRef Val, LLVMMetadataRef VarInfo, @@ -1734,26 +1755,36 @@ LLVMValueRef LLVMDIBuilderInsertDbgValueIntrinsicBefore( DbgInstPtr DbgInst = unwrap(Builder)->insertDbgValueIntrinsic( unwrap(Val), unwrap(VarInfo), unwrap(Expr), unwrap(DebugLoc), unwrap(Instr)); + // This assert will fail if the module is in the new debug info format. + // This function should only be called if the module is in the old + // debug info format. + // See https://llvm.org/docs/RemoveDIsDebugInfo.html#c-api-changes, + // LLVMIsNewDbgInfoFormat, and LLVMSetIsNewDbgInfoFormat for more info. assert(isa(DbgInst) && - "Inserted a DbgRecord into function using old debug info mode"); + "Function unexpectedly in new debug info format"); return wrap(cast(DbgInst)); } LLVMDbgRecordRef LLVMDIBuilderInsertDbgValueRecordBefore( LLVMDIBuilderRef Builder, LLVMValueRef Val, LLVMMetadataRef VarInfo, LLVMMetadataRef Expr, LLVMMetadataRef DebugLoc, LLVMValueRef Instr) { - return wrap(unwrap(Builder) - ->insertDbgValueIntrinsic( - unwrap(Val), unwrap(VarInfo), - unwrap(Expr), unwrap(DebugLoc), - unwrap(Instr)) - .get()); + DbgInstPtr DbgInst = unwrap(Builder)->insertDbgValueIntrinsic( + unwrap(Val), unwrap(VarInfo), unwrap(Expr), + unwrap(DebugLoc), unwrap(Instr)); + // This assert will fail if the module is in the old debug info format. + // This function should only be called if the module is in the new + // debug info format. + // See https://llvm.org/docs/RemoveDIsDebugInfo.html#c-api-changes, + // LLVMIsNewDbgInfoFormat, and LLVMSetIsNewDbgInfoFormat for more info. + assert(isa(DbgInst) && + "Function unexpectedly in old debug info format"); + return wrap(cast(DbgInst)); } -LLVMValueRef LLVMDIBuilderInsertDbgValueAtEnd( +LLVMDbgRecordRef LLVMDIBuilderInsertDbgValueAtEnd( LLVMDIBuilderRef Builder, LLVMValueRef Val, LLVMMetadataRef VarInfo, LLVMMetadataRef Expr, LLVMMetadataRef DebugLoc, LLVMBasicBlockRef Block) { - return LLVMDIBuilderInsertDbgValueIntrinsicAtEnd(Builder, Val, VarInfo, Expr, - DebugLoc, Block); + return LLVMDIBuilderInsertDbgValueRecordAtEnd(Builder, Val, VarInfo, Expr, + DebugLoc, Block); } LLVMValueRef LLVMDIBuilderInsertDbgValueIntrinsicAtEnd( LLVMDIBuilderRef Builder, LLVMValueRef Val, LLVMMetadataRef VarInfo, @@ -1761,19 +1792,29 @@ LLVMValueRef LLVMDIBuilderInsertDbgValueIntrinsicAtEnd( DbgInstPtr DbgInst = unwrap(Builder)->insertDbgValueIntrinsic( unwrap(Val), unwrap(VarInfo), unwrap(Expr), unwrap(DebugLoc), unwrap(Block)); + // This assert will fail if the module is in the new debug info format. + // This function should only be called if the module is in the old + // debug info format. + // See https://llvm.org/docs/RemoveDIsDebugInfo.html#c-api-changes, + // LLVMIsNewDbgInfoFormat, and LLVMSetIsNewDbgInfoFormat for more info. assert(isa(DbgInst) && - "Inserted a DbgRecord into function using old debug info mode"); + "Function unexpectedly in new debug info format"); return wrap(cast(DbgInst)); } LLVMDbgRecordRef LLVMDIBuilderInsertDbgValueRecordAtEnd( LLVMDIBuilderRef Builder, LLVMValueRef Val, LLVMMetadataRef VarInfo, LLVMMetadataRef Expr, LLVMMetadataRef DebugLoc, LLVMBasicBlockRef Block) { - return wrap(unwrap(Builder) - ->insertDbgValueIntrinsic( - unwrap(Val), unwrap(VarInfo), - unwrap(Expr), unwrap(DebugLoc), - unwrap(Block)) - .get()); + DbgInstPtr DbgInst = unwrap(Builder)->insertDbgValueIntrinsic( + unwrap(Val), unwrap(VarInfo), unwrap(Expr), + unwrap(DebugLoc), unwrap(Block)); + // This assert will fail if the module is in the old debug info format. + // This function should only be called if the module is in the new + // debug info format. + // See https://llvm.org/docs/RemoveDIsDebugInfo.html#c-api-changes, + // LLVMIsNewDbgInfoFormat, and LLVMSetIsNewDbgInfoFormat for more info. + assert(isa(DbgInst) && + "Function unexpectedly in old debug info format"); + return wrap(cast(DbgInst)); } LLVMMetadataRef LLVMDIBuilderCreateAutoVariable( diff --git a/llvm/test/Bindings/OCaml/debuginfo.ml b/llvm/test/Bindings/OCaml/debuginfo.ml index d469d4715b00..f95800dfcb02 100644 --- a/llvm/test/Bindings/OCaml/debuginfo.ml +++ b/llvm/test/Bindings/OCaml/debuginfo.ml @@ -39,6 +39,8 @@ let prepare_target llmod = let new_module () = let m = Llvm.create_module context module_name in let () = prepare_target m in + let () = Llvm_debuginfo.set_is_new_dbg_info_format m true in + insist (Llvm_debuginfo.is_new_dbg_info_format m); m let test_get_module () = @@ -285,8 +287,8 @@ let test_variables f dibuilder file_di fun_di = ~var_info:auto_var ~expr:(Llvm_debuginfo.dibuild_expression dibuilder [||]) ~location ~instr:entry_term in - let () = Printf.printf "%s\n" (Llvm.string_of_llvalue vdi) in - (* CHECK: call void @llvm.dbg.declare(metadata ptr %my_alloca, metadata {{![0-9]+}}, metadata !DIExpression()), !dbg {{\![0-9]+}} + let () = Printf.printf "%s\n" (Llvm.string_of_lldbgrecord vdi) in + (* CHECK: dbg_declare(ptr %my_alloca, ![[#]], !DIExpression(), ![[#]]) *) let arg0 = (Llvm.params f).(0) in let arg_var = Llvm_debuginfo.dibuild_create_parameter_variable dibuilder ~scope:fun_di @@ -297,8 +299,8 @@ let test_variables f dibuilder file_di fun_di = ~var_info:arg_var ~expr:(Llvm_debuginfo.dibuild_expression dibuilder [||]) ~location ~instr:entry_term in - let () = Printf.printf "%s\n" (Llvm.string_of_llvalue argdi) in - (* CHECK: call void @llvm.dbg.declare(metadata i32 %0, metadata {{![0-9]+}}, metadata !DIExpression()), !dbg {{\![0-9]+}} + let () = Printf.printf "%s\n" (Llvm.string_of_lldbgrecord argdi) in + (* CHECK: dbg_declare(i32 %0, ![[#]], !DIExpression(), ![[#]]) *) () diff --git a/llvm/tools/llvm-c-test/debuginfo.c b/llvm/tools/llvm-c-test/debuginfo.c index 78ccaf12a380..9b5c37b05d90 100644 --- a/llvm/tools/llvm-c-test/debuginfo.c +++ b/llvm/tools/llvm-c-test/debuginfo.c @@ -136,12 +136,13 @@ int llvm_test_dibuilder(bool NewDebugInfoFormat) { LLVMMetadataRef FooParamVar1 = LLVMDIBuilderCreateParameterVariable(DIB, FunctionMetadata, "a", 1, 1, File, 42, Int64Ty, true, 0); + if (LLVMIsNewDbgInfoFormat(M)) - LLVMDIBuilderInsertDeclareRecordAtEnd( + LLVMDIBuilderInsertDeclareAtEnd( DIB, LLVMConstInt(LLVMInt64Type(), 0, false), FooParamVar1, FooParamExpression, FooParamLocation, FooEntryBlock); else - LLVMDIBuilderInsertDeclareAtEnd( + LLVMDIBuilderInsertDeclareIntrinsicAtEnd( DIB, LLVMConstInt(LLVMInt64Type(), 0, false), FooParamVar1, FooParamExpression, FooParamLocation, FooEntryBlock); LLVMMetadataRef FooParamVar2 = @@ -149,11 +150,11 @@ int llvm_test_dibuilder(bool NewDebugInfoFormat) { 42, Int64Ty, true, 0); if (LLVMIsNewDbgInfoFormat(M)) - LLVMDIBuilderInsertDeclareRecordAtEnd( + LLVMDIBuilderInsertDeclareAtEnd( DIB, LLVMConstInt(LLVMInt64Type(), 0, false), FooParamVar2, FooParamExpression, FooParamLocation, FooEntryBlock); else - LLVMDIBuilderInsertDeclareAtEnd( + LLVMDIBuilderInsertDeclareIntrinsicAtEnd( DIB, LLVMConstInt(LLVMInt64Type(), 0, false), FooParamVar2, FooParamExpression, FooParamLocation, FooEntryBlock); @@ -161,11 +162,11 @@ int llvm_test_dibuilder(bool NewDebugInfoFormat) { LLVMDIBuilderCreateParameterVariable(DIB, FunctionMetadata, "c", 1, 3, File, 42, VectorTy, true, 0); if (LLVMIsNewDbgInfoFormat(M)) - LLVMDIBuilderInsertDeclareRecordAtEnd( + LLVMDIBuilderInsertDeclareAtEnd( DIB, LLVMConstInt(LLVMInt64Type(), 0, false), FooParamVar3, FooParamExpression, FooParamLocation, FooEntryBlock); else - LLVMDIBuilderInsertDeclareAtEnd( + LLVMDIBuilderInsertDeclareIntrinsicAtEnd( DIB, LLVMConstInt(LLVMInt64Type(), 0, false), FooParamVar3, FooParamExpression, FooParamLocation, FooEntryBlock); -- GitLab From 88b10f3e3aa93232f1f530cf8dfe1227f5f74ae9 Mon Sep 17 00:00:00 2001 From: Simon Tatham Date: Thu, 28 Mar 2024 08:57:27 +0000 Subject: [PATCH 029/788] [MC][AArch64] Segregate constant pool caches by size. (#86832) If you write a 32- and a 64-bit LDR instruction that both refer to the same constant or symbol using the = syntax: ``` ldr w0, =something ldr x1, =something ``` then the first call to `ConstantPool::addEntry` will insert the constant into its cache of existing entries, and the second one will find the cache entry and reuse it. This results in a 64-bit load from a 32-bit constant, reading nonsense into the other half of the target register. In this patch I've done the simplest fix: include the size of the constant pool entry as part of the key used to index the cache. So now 32- and 64-bit constant loads will never share a constant pool entry. There's scope for doing this better, in principle: you could imagine merging the two slots with appropriate overlap, so that the 32-bit load loads the LSW of the 64-bit value. But that's much more complicated: you have to take endianness into account, and maybe also adjust the size of an existing entry. This is the simplest fix that restores correctness. --- llvm/include/llvm/MC/ConstantPools.h | 9 ++++++-- llvm/lib/MC/ConstantPools.cpp | 9 ++++---- llvm/test/MC/AArch64/constant-pool-sizes.s | 25 ++++++++++++++++++++++ 3 files changed, 37 insertions(+), 6 deletions(-) create mode 100644 llvm/test/MC/AArch64/constant-pool-sizes.s diff --git a/llvm/include/llvm/MC/ConstantPools.h b/llvm/include/llvm/MC/ConstantPools.h index 7eac75362eff..ff21ccda07a8 100644 --- a/llvm/include/llvm/MC/ConstantPools.h +++ b/llvm/include/llvm/MC/ConstantPools.h @@ -43,8 +43,13 @@ struct ConstantPoolEntry { class ConstantPool { using EntryVecTy = SmallVector; EntryVecTy Entries; - std::map CachedConstantEntries; - DenseMap CachedSymbolEntries; + + // Caches of entries that already exist, indexed by their contents + // and also the size of the constant. + std::map, const MCSymbolRefExpr *> + CachedConstantEntries; + DenseMap, const MCSymbolRefExpr *> + CachedSymbolEntries; public: // Initialize a new empty constant pool diff --git a/llvm/lib/MC/ConstantPools.cpp b/llvm/lib/MC/ConstantPools.cpp index f895cc6413d7..824d2463f30f 100644 --- a/llvm/lib/MC/ConstantPools.cpp +++ b/llvm/lib/MC/ConstantPools.cpp @@ -43,14 +43,15 @@ const MCExpr *ConstantPool::addEntry(const MCExpr *Value, MCContext &Context, // Check if there is existing entry for the same constant. If so, reuse it. if (C) { - auto CItr = CachedConstantEntries.find(C->getValue()); + auto CItr = CachedConstantEntries.find(std::make_pair(C->getValue(), Size)); if (CItr != CachedConstantEntries.end()) return CItr->second; } // Check if there is existing entry for the same symbol. If so, reuse it. if (S) { - auto SItr = CachedSymbolEntries.find(&(S->getSymbol())); + auto SItr = + CachedSymbolEntries.find(std::make_pair(&(S->getSymbol()), Size)); if (SItr != CachedSymbolEntries.end()) return SItr->second; } @@ -60,9 +61,9 @@ const MCExpr *ConstantPool::addEntry(const MCExpr *Value, MCContext &Context, Entries.push_back(ConstantPoolEntry(CPEntryLabel, Value, Size, Loc)); const auto SymRef = MCSymbolRefExpr::create(CPEntryLabel, Context); if (C) - CachedConstantEntries[C->getValue()] = SymRef; + CachedConstantEntries[std::make_pair(C->getValue(), Size)] = SymRef; if (S) - CachedSymbolEntries[&(S->getSymbol())] = SymRef; + CachedSymbolEntries[std::make_pair(&(S->getSymbol()), Size)] = SymRef; return SymRef; } diff --git a/llvm/test/MC/AArch64/constant-pool-sizes.s b/llvm/test/MC/AArch64/constant-pool-sizes.s new file mode 100644 index 000000000000..279402af025f --- /dev/null +++ b/llvm/test/MC/AArch64/constant-pool-sizes.s @@ -0,0 +1,25 @@ +// RUN: llvm-mc -triple aarch64-none-linux-gnu %s | FileCheck %s + + ldr w0, =symbol + ldr x1, =symbol + + ldr w2, =1234567890 + ldr x3, =1234567890 + +// CHECK: ldr w0, .Ltmp0 +// CHECK: ldr x1, .Ltmp1 +// CHECK: ldr w2, .Ltmp2 +// CHECK: ldr x3, .Ltmp3 + +// CHECK: .p2align 2, 0x0 +// CHECK-NEXT:.Ltmp0: +// CHECK-NEXT: .word symbol +// CHECK: .p2align 3, 0x0 +// CHECK-NEXT:.Ltmp1: +// CHECK-NEXT: .xword symbol +// CHECK: .p2align 2, 0x0 +// CHECK-NEXT:.Ltmp2: +// CHECK-NEXT: .word 1234567890 +// CHECK: .p2align 3, 0x0 +// CHECK-NEXT:.Ltmp3: +// CHECK-NEXT: .xword 1234567890 -- GitLab From eff4593a642692deb2b76d9d144ad5611bb69e08 Mon Sep 17 00:00:00 2001 From: Luke Lau Date: Thu, 28 Mar 2024 16:56:13 +0800 Subject: [PATCH 030/788] [RISCV] Add test case for missed vwaddu.vv due to add->or combine. NFC We should be able to recover this with combineBinOp_VLToVWBinOp_VL if we check that the or has the disjoint flag set. --- llvm/test/CodeGen/RISCV/rvv/vwadd-sdnode.ll | 22 +++++++++++++++++++++ 1 file changed, 22 insertions(+) diff --git a/llvm/test/CodeGen/RISCV/rvv/vwadd-sdnode.ll b/llvm/test/CodeGen/RISCV/rvv/vwadd-sdnode.ll index 0a7051633a19..36bc10f055b8 100644 --- a/llvm/test/CodeGen/RISCV/rvv/vwadd-sdnode.ll +++ b/llvm/test/CodeGen/RISCV/rvv/vwadd-sdnode.ll @@ -1392,3 +1392,25 @@ define @i1_zext( %va, %vb store i9 42, ptr %p ret %vd } + +; %x.i32 and %y.i32 are disjoint, so DAGCombiner will combine it into an or. +; FIXME: We should be able to recover the or into vwaddu.vv if the disjoint +; flag is set. +define @disjoint_or( %x.i8, %y.i8) { +; CHECK-LABEL: disjoint_or: +; CHECK: # %bb.0: +; CHECK-NEXT: vsetvli a0, zero, e16, mf2, ta, ma +; CHECK-NEXT: vzext.vf2 v10, v8 +; CHECK-NEXT: vsll.vi v8, v10, 8 +; CHECK-NEXT: vsetvli zero, zero, e32, m1, ta, ma +; CHECK-NEXT: vzext.vf2 v10, v8 +; CHECK-NEXT: vzext.vf4 v8, v9 +; CHECK-NEXT: vor.vv v8, v10, v8 +; CHECK-NEXT: ret + %x.i16 = zext %x.i8 to + %x.shl = shl %x.i16, shufflevector( insertelement( poison, i16 8, i32 0), poison, zeroinitializer) + %x.i32 = zext %x.shl to + %y.i32 = zext %y.i8 to + %add = add %x.i32, %y.i32 + ret %add +} -- GitLab From 8d77d362af6ade32f087c051fe4774a3891f6ec9 Mon Sep 17 00:00:00 2001 From: martinboehme Date: Thu, 28 Mar 2024 10:12:45 +0100 Subject: [PATCH 031/788] [clang][dataflow] Introduce a helper class for handling record initializer lists. (#86675) This is currently only used in one place, but I'm working on a patch that will use this from a second place. And I think this already improves the readability of the one place this is used so far. --- .../FlowSensitive/DataflowEnvironment.h | 29 +++++++++ .../FlowSensitive/DataflowEnvironment.cpp | 36 +++++++++++ clang/lib/Analysis/FlowSensitive/Transfer.cpp | 61 +++++-------------- 3 files changed, 81 insertions(+), 45 deletions(-) diff --git a/clang/include/clang/Analysis/FlowSensitive/DataflowEnvironment.h b/clang/include/clang/Analysis/FlowSensitive/DataflowEnvironment.h index 2330697299fd..c30bccd06674 100644 --- a/clang/include/clang/Analysis/FlowSensitive/DataflowEnvironment.h +++ b/clang/include/clang/Analysis/FlowSensitive/DataflowEnvironment.h @@ -744,6 +744,35 @@ RecordStorageLocation *getBaseObjectLocation(const MemberExpr &ME, std::vector getFieldsForInitListExpr(const InitListExpr *InitList); +/// Helper class for initialization of a record with an `InitListExpr`. +/// `InitListExpr::inits()` contains the initializers for both the base classes +/// and the fields of the record; this helper class separates these out into two +/// different lists. In addition, it deals with special cases associated with +/// unions. +class RecordInitListHelper { +public: + // `InitList` must have record type. + RecordInitListHelper(const InitListExpr *InitList); + + // Base classes with their associated initializer expressions. + ArrayRef> base_inits() const { + return BaseInits; + } + + // Fields with their associated initializer expressions. + ArrayRef> field_inits() const { + return FieldInits; + } + +private: + SmallVector> BaseInits; + SmallVector> FieldInits; + + // We potentially synthesize an `ImplicitValueInitExpr` for unions. It's a + // member variable because we store a pointer to it in `FieldInits`. + std::optional ImplicitValueInitForUnion; +}; + /// Associates a new `RecordValue` with `Loc` and returns the new value. RecordValue &refreshRecordValue(RecordStorageLocation &Loc, Environment &Env); diff --git a/clang/lib/Analysis/FlowSensitive/DataflowEnvironment.cpp b/clang/lib/Analysis/FlowSensitive/DataflowEnvironment.cpp index 70e0623805a8..f729d676dd0d 100644 --- a/clang/lib/Analysis/FlowSensitive/DataflowEnvironment.cpp +++ b/clang/lib/Analysis/FlowSensitive/DataflowEnvironment.cpp @@ -1169,6 +1169,42 @@ getFieldsForInitListExpr(const InitListExpr *InitList) { return Fields; } +RecordInitListHelper::RecordInitListHelper(const InitListExpr *InitList) { + auto *RD = InitList->getType()->getAsCXXRecordDecl(); + assert(RD != nullptr); + + std::vector Fields = getFieldsForInitListExpr(InitList); + ArrayRef Inits = InitList->inits(); + + // Unions initialized with an empty initializer list need special treatment. + // For structs/classes initialized with an empty initializer list, Clang + // puts `ImplicitValueInitExpr`s in `InitListExpr::inits()`, but for unions, + // it doesn't do this -- so we create an `ImplicitValueInitExpr` ourselves. + SmallVector InitsForUnion; + if (InitList->getType()->isUnionType() && Inits.empty()) { + assert(Fields.size() == 1); + ImplicitValueInitForUnion.emplace(Fields.front()->getType()); + InitsForUnion.push_back(&*ImplicitValueInitForUnion); + Inits = InitsForUnion; + } + + size_t InitIdx = 0; + + assert(Fields.size() + RD->getNumBases() == Inits.size()); + for (const CXXBaseSpecifier &Base : RD->bases()) { + assert(InitIdx < Inits.size()); + Expr *Init = Inits[InitIdx++]; + BaseInits.emplace_back(&Base, Init); + } + + assert(Fields.size() == Inits.size() - InitIdx); + for (const FieldDecl *Field : Fields) { + assert(InitIdx < Inits.size()); + Expr *Init = Inits[InitIdx++]; + FieldInits.emplace_back(Field, Init); + } +} + RecordValue &refreshRecordValue(RecordStorageLocation &Loc, Environment &Env) { auto &NewVal = Env.create(Loc); Env.setValue(Loc, NewVal); diff --git a/clang/lib/Analysis/FlowSensitive/Transfer.cpp b/clang/lib/Analysis/FlowSensitive/Transfer.cpp index 960e9688ffb7..0a2e8368d541 100644 --- a/clang/lib/Analysis/FlowSensitive/Transfer.cpp +++ b/clang/lib/Analysis/FlowSensitive/Transfer.cpp @@ -689,51 +689,22 @@ public: } llvm::DenseMap FieldLocs; - - // This only contains the direct fields for the given type. - std::vector FieldsForInit = getFieldsForInitListExpr(S); - - // `S->inits()` contains all the initializer expressions, including the - // ones for direct base classes. - ArrayRef Inits = S->inits(); - size_t InitIdx = 0; - - // Unions initialized with an empty initializer list need special treatment. - // For structs/classes initialized with an empty initializer list, Clang - // puts `ImplicitValueInitExpr`s in `InitListExpr::inits()`, but for unions, - // it doesn't do this -- so we create an `ImplicitValueInitExpr` ourselves. - std::optional ImplicitValueInitForUnion; - SmallVector InitsForUnion; - if (S->getType()->isUnionType() && Inits.empty()) { - assert(FieldsForInit.size() == 1); - ImplicitValueInitForUnion.emplace(FieldsForInit.front()->getType()); - InitsForUnion.push_back(&*ImplicitValueInitForUnion); - Inits = InitsForUnion; - } - - // Initialize base classes. - if (auto* R = S->getType()->getAsCXXRecordDecl()) { - assert(FieldsForInit.size() + R->getNumBases() == Inits.size()); - for ([[maybe_unused]] const CXXBaseSpecifier &Base : R->bases()) { - assert(InitIdx < Inits.size()); - auto Init = Inits[InitIdx++]; - assert(Base.getType().getCanonicalType() == - Init->getType().getCanonicalType()); - auto *BaseVal = Env.get(*Init); - if (!BaseVal) - BaseVal = cast(Env.createValue(Init->getType())); - // Take ownership of the fields of the `RecordValue` for the base class - // and incorporate them into the "flattened" set of fields for the - // derived class. - auto Children = BaseVal->getLoc().children(); - FieldLocs.insert(Children.begin(), Children.end()); - } - } - - assert(FieldsForInit.size() == Inits.size() - InitIdx); - for (auto Field : FieldsForInit) { - assert(InitIdx < Inits.size()); - auto Init = Inits[InitIdx++]; + RecordInitListHelper InitListHelper(S); + + for (auto [Base, Init] : InitListHelper.base_inits()) { + assert(Base->getType().getCanonicalType() == + Init->getType().getCanonicalType()); + auto *BaseVal = Env.get(*Init); + if (!BaseVal) + BaseVal = cast(Env.createValue(Init->getType())); + // Take ownership of the fields of the `RecordValue` for the base class + // and incorporate them into the "flattened" set of fields for the + // derived class. + auto Children = BaseVal->getLoc().children(); + FieldLocs.insert(Children.begin(), Children.end()); + } + + for (auto [Field, Init] : InitListHelper.field_inits()) { assert( // The types are same, or Field->getType().getCanonicalType().getUnqualifiedType() == -- GitLab From 912e2c47589d7f4de3e59e99920fe9a60281db2a Mon Sep 17 00:00:00 2001 From: Shan Huang <52285902006@stu.ecnu.edu.cn> Date: Thu, 28 Mar 2024 17:37:33 +0800 Subject: [PATCH 032/788] [Debuginfo][TailCallElim] Fix #86262: drop the debug location of entry branch (#86269) This pr fixes #86262. --------- Co-authored-by: Stephen Tozer --- llvm/lib/Transforms/Scalar/TailRecursionElimination.cpp | 4 +++- llvm/test/Transforms/TailCallElim/debugloc.ll | 4 ++-- 2 files changed, 5 insertions(+), 3 deletions(-) diff --git a/llvm/lib/Transforms/Scalar/TailRecursionElimination.cpp b/llvm/lib/Transforms/Scalar/TailRecursionElimination.cpp index 519ff3221a3b..34d39f3fe6dc 100644 --- a/llvm/lib/Transforms/Scalar/TailRecursionElimination.cpp +++ b/llvm/lib/Transforms/Scalar/TailRecursionElimination.cpp @@ -510,7 +510,9 @@ void TailRecursionEliminator::createTailRecurseLoopHeader(CallInst *CI) { NewEntry->takeName(HeaderBB); HeaderBB->setName("tailrecurse"); BranchInst *BI = BranchInst::Create(HeaderBB, NewEntry); - BI->setDebugLoc(CI->getDebugLoc()); + // If the new branch preserves the debug location of CI, it could result in + // misleading stepping, if CI is located in a conditional branch. + // So, here we don't give any debug location to BI. // Move all fixed sized allocas from HeaderBB to NewEntry. for (BasicBlock::iterator OEBI = HeaderBB->begin(), E = HeaderBB->end(), diff --git a/llvm/test/Transforms/TailCallElim/debugloc.ll b/llvm/test/Transforms/TailCallElim/debugloc.ll index 3abbd6552efc..49957695a421 100644 --- a/llvm/test/Transforms/TailCallElim/debugloc.ll +++ b/llvm/test/Transforms/TailCallElim/debugloc.ll @@ -4,13 +4,13 @@ define void @foo() { entry: ; CHECK-LABEL: entry: -; CHECK: br label %tailrecurse, !dbg ![[DbgLoc:[0-9]+]] +; CHECK: br label %tailrecurse{{$}} call void @foo() ;; line 1 ret void ; CHECK-LABEL: tailrecurse: -; CHECK: br label %tailrecurse, !dbg ![[DbgLoc]] +; CHECK: br label %tailrecurse, !dbg ![[DbgLoc:[0-9]+]] } ;; Make sure tailrecurse has the call instruction's DL -- GitLab From 856e815ca1c416de263438e90e8120947e33a03c Mon Sep 17 00:00:00 2001 From: Luke Lau Date: Thu, 28 Mar 2024 18:08:59 +0800 Subject: [PATCH 033/788] [DAGCombiner] Set disjoint flag in add->or and xor->or combines (#86925) We check DAG.haveNoCommonBitsSet so the operands will be known to be disjoint. I couldn't think of a codegen test case since most targets aren't checking hasDisjoint yet, apart from RISCV in the or_is_add pattern, but it also falls back to computeKnownBits. --- llvm/lib/CodeGen/SelectionDAG/DAGCombiner.cpp | 14 ++++++++++---- .../Inputs/lanai_isel.ll.expected | 6 +++--- 2 files changed, 13 insertions(+), 7 deletions(-) diff --git a/llvm/lib/CodeGen/SelectionDAG/DAGCombiner.cpp b/llvm/lib/CodeGen/SelectionDAG/DAGCombiner.cpp index 36abe27d2621..6dd3fbb3c97e 100644 --- a/llvm/lib/CodeGen/SelectionDAG/DAGCombiner.cpp +++ b/llvm/lib/CodeGen/SelectionDAG/DAGCombiner.cpp @@ -2887,8 +2887,11 @@ SDValue DAGCombiner::visitADD(SDNode *N) { // fold (a+b) -> (a|b) iff a and b share no bits. if ((!LegalOperations || TLI.isOperationLegal(ISD::OR, VT)) && - DAG.haveNoCommonBitsSet(N0, N1)) - return DAG.getNode(ISD::OR, DL, VT, N0, N1); + DAG.haveNoCommonBitsSet(N0, N1)) { + SDNodeFlags Flags; + Flags.setDisjoint(true); + return DAG.getNode(ISD::OR, DL, VT, N0, N1, Flags); + } // Fold (add (vscale * C0), (vscale * C1)) to (vscale * (C0 + C1)). if (N0.getOpcode() == ISD::VSCALE && N1.getOpcode() == ISD::VSCALE) { @@ -9289,8 +9292,11 @@ SDValue DAGCombiner::visitXOR(SDNode *N) { // fold (a^b) -> (a|b) iff a and b share no bits. if ((!LegalOperations || TLI.isOperationLegal(ISD::OR, VT)) && - DAG.haveNoCommonBitsSet(N0, N1)) - return DAG.getNode(ISD::OR, DL, VT, N0, N1); + DAG.haveNoCommonBitsSet(N0, N1)) { + SDNodeFlags Flags; + Flags.setDisjoint(true); + return DAG.getNode(ISD::OR, DL, VT, N0, N1, Flags); + } // look for 'add-like' folds: // XOR(N0,MIN_SIGNED_VALUE) == ADD(N0,MIN_SIGNED_VALUE) diff --git a/llvm/test/tools/UpdateTestChecks/update_llc_test_checks/Inputs/lanai_isel.ll.expected b/llvm/test/tools/UpdateTestChecks/update_llc_test_checks/Inputs/lanai_isel.ll.expected index 80145c5e098e..71e82eca6c3e 100644 --- a/llvm/test/tools/UpdateTestChecks/update_llc_test_checks/Inputs/lanai_isel.ll.expected +++ b/llvm/test/tools/UpdateTestChecks/update_llc_test_checks/Inputs/lanai_isel.ll.expected @@ -7,7 +7,7 @@ define i64 @i64_test(i64 %i) nounwind readnone { ; CHECK-NEXT: t0: ch,glue = EntryToken ; CHECK-NEXT: t5: i32,ch = LDW_RI TargetFrameIndex:i32<-2>, TargetConstant:i32<0>, TargetConstant:i32<0>, t0 ; CHECK-NEXT: t7: i32 = ADD_I_LO TargetFrameIndex:i32<0>, TargetConstant:i32<0> -; CHECK-NEXT: t29: i32 = OR_I_LO t7, TargetConstant:i32<4> +; CHECK-NEXT: t29: i32 = OR_I_LO disjoint t7, TargetConstant:i32<4> ; CHECK-NEXT: t22: i32,ch = LDW_RI t29, TargetConstant:i32<0>, TargetConstant:i32<0>, t0 ; CHECK-NEXT: t24: i32 = ADD_R t5, t22, TargetConstant:i32<0> ; CHECK-NEXT: t3: i32,ch = LDW_RI TargetFrameIndex:i32<-1>, TargetConstant:i32<0>, TargetConstant:i32<0>, t0 @@ -52,7 +52,7 @@ define i64 @i16_test(i16 %i) nounwind readnone { ; CHECK-NEXT: t33: i32,ch = CopyFromReg t0, Register:i32 $r0 ; CHECK-NEXT: t14: ch,glue = CopyToReg t0, Register:i32 $rv, t33 ; CHECK-NEXT: t1: i32 = ADD_I_LO TargetFrameIndex:i32<-1>, TargetConstant:i32<0> -; CHECK-NEXT: t21: i32 = OR_I_LO t1, TargetConstant:i32<2> +; CHECK-NEXT: t21: i32 = OR_I_LO disjoint t1, TargetConstant:i32<2> ; CHECK-NEXT: t23: i32,ch = LDHz_RI t21, TargetConstant:i32<0>, TargetConstant:i32<0>, t0 ; CHECK-NEXT: t22: i32,ch = LDHz_RI TargetFrameIndex:i32<0>, TargetConstant:i32<0>, TargetConstant:i32<0>, t0 ; CHECK-NEXT: t24: i32 = ADD_R t23, t22, TargetConstant:i32<0> @@ -75,7 +75,7 @@ define i64 @i8_test(i8 %i) nounwind readnone { ; CHECK-NEXT: t33: i32,ch = CopyFromReg t0, Register:i32 $r0 ; CHECK-NEXT: t14: ch,glue = CopyToReg t0, Register:i32 $rv, t33 ; CHECK-NEXT: t1: i32 = ADD_I_LO TargetFrameIndex:i32<-1>, TargetConstant:i32<0> -; CHECK-NEXT: t21: i32 = OR_I_LO t1, TargetConstant:i32<3> +; CHECK-NEXT: t21: i32 = OR_I_LO disjoint t1, TargetConstant:i32<3> ; CHECK-NEXT: t23: i32,ch = LDBz_RI t21, TargetConstant:i32<0>, TargetConstant:i32<0>, t0 ; CHECK-NEXT: t22: i32,ch = LDBz_RI TargetFrameIndex:i32<0>, TargetConstant:i32<0>, TargetConstant:i32<0>, t0 ; CHECK-NEXT: t24: i32 = ADD_R t23, t22, TargetConstant:i32<0> -- GitLab From e640d9e725ef06b9787ab0ab884598f4f5532e48 Mon Sep 17 00:00:00 2001 From: bvlgah Date: Thu, 28 Mar 2024 18:09:18 +0800 Subject: [PATCH 034/788] =?UTF-8?q?[RISCV][GlobalISel]=20Fix=20legalizing?= =?UTF-8?q?=20=E2=80=98llvm.va=5Fcopy=E2=80=99=20intrinsic=20(#86863)?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Hi, I spotted a problem when running benchmarking programs on a RISCV64 device. ## Issue Segmentation faults only occurred while running the programs compiled with `GlobalISel` enabled. Here is a small but complete example (it is adopted from [Google's benchmark framework](https://github.com/llvm/llvm-test-suite/blob/95a9f0d0b45056274f0bb4b0e0dd019023e414dc/MicroBenchmarks/libs/benchmark/src/colorprint.cc#L85-L119) to reproduce the issue, ```cpp #include #include #include #include #include std::string FormatString(const char* msg, va_list args) { // we might need a second shot at this, so pre-emptivly make a copy va_list args_cp; va_copy(args_cp, args); std::size_t size = 256; char local_buff[256]; auto ret = vsnprintf(local_buff, size, msg, args_cp); va_end(args_cp); // currently there is no error handling for failure, so this is hack. // BM_CHECK(ret >= 0); if (ret == 0) // handle empty expansion return {}; else if (static_cast(ret) < size) return local_buff; else { // we did not provide a long enough buffer on our first attempt. size = static_cast(ret) + 1; // + 1 for the null byte std::unique_ptr buff(new char[size]); ret = vsnprintf(buff.get(), size, msg, args); // BM_CHECK(ret > 0 && (static_cast(ret)) < size); return buff.get(); } } std::string FormatString(const char* msg, ...) { va_list args; va_start(args, msg); auto tmp = FormatString(msg, args); va_end(args); return tmp; } int main() { std::string Str = FormatString("%-*s %13s %15s %12s", static_cast(20), "Benchmark", "Time", "CPU", "Iterations"); std::cout << Str << std::endl; } ``` Use `clang++ -fglobal-isel -o main main.cpp` to compile it. ## Cause I have examined MIR, it shows that these segmentation faults resulted from a small mistake about legalizing the intrinsic function `llvm.va_copy`. https://github.com/llvm/llvm-project/blob/36e74cfdbde208e384c72bcb52ea638303fb7d67/llvm/lib/Target/RISCV/GISel/RISCVLegalizerInfo.cpp#L451-L453 `DstLst` and `Tmp` are placed in the wrong order. ## Changes I have tweaked the test case `CodeGen/RISCV/GlobalISel/vararg.ll` so that `s0` is used as the frame pointer (not in all checks) which points to the starting address of the save area. I believe that it helps reason about how `llvm.va_copy` is handled. --- .../Target/RISCV/GISel/RISCVLegalizerInfo.cpp | 2 +- .../GlobalISel/legalizer/legalize-vacopy.mir | 2 +- llvm/test/CodeGen/RISCV/GlobalISel/vararg.ll | 936 +++++++++++++++++- 3 files changed, 933 insertions(+), 7 deletions(-) diff --git a/llvm/lib/Target/RISCV/GISel/RISCVLegalizerInfo.cpp b/llvm/lib/Target/RISCV/GISel/RISCVLegalizerInfo.cpp index 9a388f4cd271..22cae389cc33 100644 --- a/llvm/lib/Target/RISCV/GISel/RISCVLegalizerInfo.cpp +++ b/llvm/lib/Target/RISCV/GISel/RISCVLegalizerInfo.cpp @@ -450,7 +450,7 @@ bool RISCVLegalizerInfo::legalizeIntrinsic(LegalizerHelper &Helper, // Store the result in the destination va_list MachineMemOperand *StoreMMO = MF.getMachineMemOperand( MachinePointerInfo(), MachineMemOperand::MOStore, PtrTy, Alignment); - MIRBuilder.buildStore(DstLst, Tmp, *StoreMMO); + MIRBuilder.buildStore(Tmp, DstLst, *StoreMMO); MI.eraseFromParent(); return true; diff --git a/llvm/test/CodeGen/RISCV/GlobalISel/legalizer/legalize-vacopy.mir b/llvm/test/CodeGen/RISCV/GlobalISel/legalizer/legalize-vacopy.mir index f9eda1252937..16542f580012 100644 --- a/llvm/test/CodeGen/RISCV/GlobalISel/legalizer/legalize-vacopy.mir +++ b/llvm/test/CodeGen/RISCV/GlobalISel/legalizer/legalize-vacopy.mir @@ -14,7 +14,7 @@ body: | ; CHECK-NEXT: [[COPY:%[0-9]+]]:_(p0) = COPY $x10 ; CHECK-NEXT: [[COPY1:%[0-9]+]]:_(p0) = COPY $x11 ; CHECK-NEXT: [[LOAD:%[0-9]+]]:_(p0) = G_LOAD [[COPY1]](p0) :: (load (p0)) - ; CHECK-NEXT: G_STORE [[COPY]](p0), [[LOAD]](p0) :: (store (p0)) + ; CHECK-NEXT: G_STORE [[LOAD]](p0), [[COPY]](p0) :: (store (p0)) ; CHECK-NEXT: PseudoRET %0:_(p0) = COPY $x10 %1:_(p0) = COPY $x11 diff --git a/llvm/test/CodeGen/RISCV/GlobalISel/vararg.ll b/llvm/test/CodeGen/RISCV/GlobalISel/vararg.ll index 7b110e562e05..d55adf371119 100644 --- a/llvm/test/CodeGen/RISCV/GlobalISel/vararg.ll +++ b/llvm/test/CodeGen/RISCV/GlobalISel/vararg.ll @@ -17,6 +17,12 @@ ; RUN: sed 's/iXLen/i64/g' %s | llc -mtriple=riscv64 -global-isel -mattr=+d -target-abi lp64d \ ; RUN: -verify-machineinstrs \ ; RUN: | FileCheck -check-prefixes=RV64,LP64D %s +; RUN: sed 's/iXLen/i64/g' %s | llc -mtriple=riscv32 -global-isel \ +; RUN: -frame-pointer=all -target-abi ilp32 -verify-machineinstrs \ +; RUN: | FileCheck -check-prefixes=RV32-WITHFP %s +; RUN: sed 's/iXLen/i64/g' %s | llc -mtriple=riscv64 -global-isel \ +; RUN: -frame-pointer=all -target-abi lp64 -verify-machineinstrs \ +; RUN: | FileCheck -check-prefixes=RV64-WITHFP %s ; The same vararg calling convention is used for ilp32/ilp32f/ilp32d and for ; lp64/lp64f/lp64d. Different CHECK lines are required due to slight @@ -79,6 +85,67 @@ define i32 @va1(ptr %fmt, ...) { ; RV64-NEXT: lw a0, 0(a0) ; RV64-NEXT: addi sp, sp, 80 ; RV64-NEXT: ret +; +; RV32-WITHFP-LABEL: va1: +; RV32-WITHFP: # %bb.0: +; RV32-WITHFP-NEXT: addi sp, sp, -48 +; RV32-WITHFP-NEXT: .cfi_def_cfa_offset 48 +; RV32-WITHFP-NEXT: sw ra, 12(sp) # 4-byte Folded Spill +; RV32-WITHFP-NEXT: sw s0, 8(sp) # 4-byte Folded Spill +; RV32-WITHFP-NEXT: .cfi_offset ra, -36 +; RV32-WITHFP-NEXT: .cfi_offset s0, -40 +; RV32-WITHFP-NEXT: addi s0, sp, 16 +; RV32-WITHFP-NEXT: .cfi_def_cfa s0, 32 +; RV32-WITHFP-NEXT: sw a1, 4(s0) +; RV32-WITHFP-NEXT: sw a2, 8(s0) +; RV32-WITHFP-NEXT: sw a3, 12(s0) +; RV32-WITHFP-NEXT: sw a4, 16(s0) +; RV32-WITHFP-NEXT: addi a0, s0, 4 +; RV32-WITHFP-NEXT: sw a0, -12(s0) +; RV32-WITHFP-NEXT: lw a0, -12(s0) +; RV32-WITHFP-NEXT: sw a5, 20(s0) +; RV32-WITHFP-NEXT: sw a6, 24(s0) +; RV32-WITHFP-NEXT: sw a7, 28(s0) +; RV32-WITHFP-NEXT: addi a1, a0, 4 +; RV32-WITHFP-NEXT: sw a1, -12(s0) +; RV32-WITHFP-NEXT: lw a0, 0(a0) +; RV32-WITHFP-NEXT: lw ra, 12(sp) # 4-byte Folded Reload +; RV32-WITHFP-NEXT: lw s0, 8(sp) # 4-byte Folded Reload +; RV32-WITHFP-NEXT: addi sp, sp, 48 +; RV32-WITHFP-NEXT: ret +; +; RV64-WITHFP-LABEL: va1: +; RV64-WITHFP: # %bb.0: +; RV64-WITHFP-NEXT: addi sp, sp, -96 +; RV64-WITHFP-NEXT: .cfi_def_cfa_offset 96 +; RV64-WITHFP-NEXT: sd ra, 24(sp) # 8-byte Folded Spill +; RV64-WITHFP-NEXT: sd s0, 16(sp) # 8-byte Folded Spill +; RV64-WITHFP-NEXT: .cfi_offset ra, -72 +; RV64-WITHFP-NEXT: .cfi_offset s0, -80 +; RV64-WITHFP-NEXT: addi s0, sp, 32 +; RV64-WITHFP-NEXT: .cfi_def_cfa s0, 64 +; RV64-WITHFP-NEXT: sd a1, 8(s0) +; RV64-WITHFP-NEXT: sd a2, 16(s0) +; RV64-WITHFP-NEXT: sd a3, 24(s0) +; RV64-WITHFP-NEXT: sd a4, 32(s0) +; RV64-WITHFP-NEXT: sd a5, 40(s0) +; RV64-WITHFP-NEXT: addi a0, s0, 8 +; RV64-WITHFP-NEXT: sd a0, -24(s0) +; RV64-WITHFP-NEXT: lw a0, -20(s0) +; RV64-WITHFP-NEXT: lwu a1, -24(s0) +; RV64-WITHFP-NEXT: sd a6, 48(s0) +; RV64-WITHFP-NEXT: sd a7, 56(s0) +; RV64-WITHFP-NEXT: slli a0, a0, 32 +; RV64-WITHFP-NEXT: or a0, a0, a1 +; RV64-WITHFP-NEXT: addi a1, a0, 4 +; RV64-WITHFP-NEXT: srli a2, a1, 32 +; RV64-WITHFP-NEXT: sw a1, -24(s0) +; RV64-WITHFP-NEXT: sw a2, -20(s0) +; RV64-WITHFP-NEXT: lw a0, 0(a0) +; RV64-WITHFP-NEXT: ld ra, 24(sp) # 8-byte Folded Reload +; RV64-WITHFP-NEXT: ld s0, 16(sp) # 8-byte Folded Reload +; RV64-WITHFP-NEXT: addi sp, sp, 96 +; RV64-WITHFP-NEXT: ret %va = alloca ptr call void @llvm.va_start(ptr %va) %argp.cur = load ptr, ptr %va, align 4 @@ -131,6 +198,58 @@ define i32 @va1_va_arg(ptr %fmt, ...) nounwind { ; RV64-NEXT: lw a0, 0(a0) ; RV64-NEXT: addi sp, sp, 80 ; RV64-NEXT: ret +; +; RV32-WITHFP-LABEL: va1_va_arg: +; RV32-WITHFP: # %bb.0: +; RV32-WITHFP-NEXT: addi sp, sp, -48 +; RV32-WITHFP-NEXT: sw ra, 12(sp) # 4-byte Folded Spill +; RV32-WITHFP-NEXT: sw s0, 8(sp) # 4-byte Folded Spill +; RV32-WITHFP-NEXT: addi s0, sp, 16 +; RV32-WITHFP-NEXT: sw a1, 4(s0) +; RV32-WITHFP-NEXT: sw a2, 8(s0) +; RV32-WITHFP-NEXT: sw a3, 12(s0) +; RV32-WITHFP-NEXT: sw a4, 16(s0) +; RV32-WITHFP-NEXT: sw a5, 20(s0) +; RV32-WITHFP-NEXT: sw a6, 24(s0) +; RV32-WITHFP-NEXT: sw a7, 28(s0) +; RV32-WITHFP-NEXT: addi a0, s0, 4 +; RV32-WITHFP-NEXT: sw a0, -12(s0) +; RV32-WITHFP-NEXT: lw a0, -12(s0) +; RV32-WITHFP-NEXT: addi a0, a0, 3 +; RV32-WITHFP-NEXT: andi a0, a0, -4 +; RV32-WITHFP-NEXT: addi a1, a0, 4 +; RV32-WITHFP-NEXT: sw a1, -12(s0) +; RV32-WITHFP-NEXT: lw a0, 0(a0) +; RV32-WITHFP-NEXT: lw ra, 12(sp) # 4-byte Folded Reload +; RV32-WITHFP-NEXT: lw s0, 8(sp) # 4-byte Folded Reload +; RV32-WITHFP-NEXT: addi sp, sp, 48 +; RV32-WITHFP-NEXT: ret +; +; RV64-WITHFP-LABEL: va1_va_arg: +; RV64-WITHFP: # %bb.0: +; RV64-WITHFP-NEXT: addi sp, sp, -96 +; RV64-WITHFP-NEXT: sd ra, 24(sp) # 8-byte Folded Spill +; RV64-WITHFP-NEXT: sd s0, 16(sp) # 8-byte Folded Spill +; RV64-WITHFP-NEXT: addi s0, sp, 32 +; RV64-WITHFP-NEXT: sd a1, 8(s0) +; RV64-WITHFP-NEXT: sd a2, 16(s0) +; RV64-WITHFP-NEXT: sd a3, 24(s0) +; RV64-WITHFP-NEXT: sd a4, 32(s0) +; RV64-WITHFP-NEXT: sd a5, 40(s0) +; RV64-WITHFP-NEXT: sd a6, 48(s0) +; RV64-WITHFP-NEXT: sd a7, 56(s0) +; RV64-WITHFP-NEXT: addi a0, s0, 8 +; RV64-WITHFP-NEXT: sd a0, -24(s0) +; RV64-WITHFP-NEXT: ld a0, -24(s0) +; RV64-WITHFP-NEXT: addi a0, a0, 3 +; RV64-WITHFP-NEXT: andi a0, a0, -4 +; RV64-WITHFP-NEXT: addi a1, a0, 4 +; RV64-WITHFP-NEXT: sd a1, -24(s0) +; RV64-WITHFP-NEXT: lw a0, 0(a0) +; RV64-WITHFP-NEXT: ld ra, 24(sp) # 8-byte Folded Reload +; RV64-WITHFP-NEXT: ld s0, 16(sp) # 8-byte Folded Reload +; RV64-WITHFP-NEXT: addi sp, sp, 96 +; RV64-WITHFP-NEXT: ret %va = alloca ptr call void @llvm.va_start(ptr %va) %1 = va_arg ptr %va, i32 @@ -212,6 +331,78 @@ define i32 @va1_va_arg_alloca(ptr %fmt, ...) nounwind { ; RV64-NEXT: ld s1, 8(sp) # 8-byte Folded Reload ; RV64-NEXT: addi sp, sp, 96 ; RV64-NEXT: ret +; +; RV32-WITHFP-LABEL: va1_va_arg_alloca: +; RV32-WITHFP: # %bb.0: +; RV32-WITHFP-NEXT: addi sp, sp, -48 +; RV32-WITHFP-NEXT: sw ra, 12(sp) # 4-byte Folded Spill +; RV32-WITHFP-NEXT: sw s0, 8(sp) # 4-byte Folded Spill +; RV32-WITHFP-NEXT: sw s1, 4(sp) # 4-byte Folded Spill +; RV32-WITHFP-NEXT: addi s0, sp, 16 +; RV32-WITHFP-NEXT: sw a1, 4(s0) +; RV32-WITHFP-NEXT: sw a2, 8(s0) +; RV32-WITHFP-NEXT: sw a3, 12(s0) +; RV32-WITHFP-NEXT: sw a4, 16(s0) +; RV32-WITHFP-NEXT: sw a5, 20(s0) +; RV32-WITHFP-NEXT: sw a6, 24(s0) +; RV32-WITHFP-NEXT: sw a7, 28(s0) +; RV32-WITHFP-NEXT: addi a0, s0, 4 +; RV32-WITHFP-NEXT: sw a0, -16(s0) +; RV32-WITHFP-NEXT: lw a0, -16(s0) +; RV32-WITHFP-NEXT: addi a0, a0, 3 +; RV32-WITHFP-NEXT: andi a0, a0, -4 +; RV32-WITHFP-NEXT: addi a1, a0, 4 +; RV32-WITHFP-NEXT: sw a1, -16(s0) +; RV32-WITHFP-NEXT: lw s1, 0(a0) +; RV32-WITHFP-NEXT: addi a0, s1, 15 +; RV32-WITHFP-NEXT: andi a0, a0, -16 +; RV32-WITHFP-NEXT: sub a0, sp, a0 +; RV32-WITHFP-NEXT: mv sp, a0 +; RV32-WITHFP-NEXT: call notdead +; RV32-WITHFP-NEXT: mv a0, s1 +; RV32-WITHFP-NEXT: addi sp, s0, -16 +; RV32-WITHFP-NEXT: lw ra, 12(sp) # 4-byte Folded Reload +; RV32-WITHFP-NEXT: lw s0, 8(sp) # 4-byte Folded Reload +; RV32-WITHFP-NEXT: lw s1, 4(sp) # 4-byte Folded Reload +; RV32-WITHFP-NEXT: addi sp, sp, 48 +; RV32-WITHFP-NEXT: ret +; +; RV64-WITHFP-LABEL: va1_va_arg_alloca: +; RV64-WITHFP: # %bb.0: +; RV64-WITHFP-NEXT: addi sp, sp, -96 +; RV64-WITHFP-NEXT: sd ra, 24(sp) # 8-byte Folded Spill +; RV64-WITHFP-NEXT: sd s0, 16(sp) # 8-byte Folded Spill +; RV64-WITHFP-NEXT: sd s1, 8(sp) # 8-byte Folded Spill +; RV64-WITHFP-NEXT: addi s0, sp, 32 +; RV64-WITHFP-NEXT: sd a1, 8(s0) +; RV64-WITHFP-NEXT: sd a2, 16(s0) +; RV64-WITHFP-NEXT: sd a3, 24(s0) +; RV64-WITHFP-NEXT: sd a4, 32(s0) +; RV64-WITHFP-NEXT: sd a5, 40(s0) +; RV64-WITHFP-NEXT: sd a6, 48(s0) +; RV64-WITHFP-NEXT: sd a7, 56(s0) +; RV64-WITHFP-NEXT: addi a0, s0, 8 +; RV64-WITHFP-NEXT: sd a0, -32(s0) +; RV64-WITHFP-NEXT: ld a0, -32(s0) +; RV64-WITHFP-NEXT: addi a0, a0, 3 +; RV64-WITHFP-NEXT: andi a0, a0, -4 +; RV64-WITHFP-NEXT: addi a1, a0, 4 +; RV64-WITHFP-NEXT: sd a1, -32(s0) +; RV64-WITHFP-NEXT: lw s1, 0(a0) +; RV64-WITHFP-NEXT: slli a0, s1, 32 +; RV64-WITHFP-NEXT: srli a0, a0, 32 +; RV64-WITHFP-NEXT: addi a0, a0, 15 +; RV64-WITHFP-NEXT: andi a0, a0, -16 +; RV64-WITHFP-NEXT: sub a0, sp, a0 +; RV64-WITHFP-NEXT: mv sp, a0 +; RV64-WITHFP-NEXT: call notdead +; RV64-WITHFP-NEXT: mv a0, s1 +; RV64-WITHFP-NEXT: addi sp, s0, -32 +; RV64-WITHFP-NEXT: ld ra, 24(sp) # 8-byte Folded Reload +; RV64-WITHFP-NEXT: ld s0, 16(sp) # 8-byte Folded Reload +; RV64-WITHFP-NEXT: ld s1, 8(sp) # 8-byte Folded Reload +; RV64-WITHFP-NEXT: addi sp, sp, 96 +; RV64-WITHFP-NEXT: ret %va = alloca ptr call void @llvm.va_start(ptr %va) %1 = va_arg ptr %va, i32 @@ -273,6 +464,36 @@ define void @va1_caller() nounwind { ; LP64D-NEXT: ld ra, 8(sp) # 8-byte Folded Reload ; LP64D-NEXT: addi sp, sp, 16 ; LP64D-NEXT: ret +; +; RV32-WITHFP-LABEL: va1_caller: +; RV32-WITHFP: # %bb.0: +; RV32-WITHFP-NEXT: addi sp, sp, -16 +; RV32-WITHFP-NEXT: sw ra, 12(sp) # 4-byte Folded Spill +; RV32-WITHFP-NEXT: sw s0, 8(sp) # 4-byte Folded Spill +; RV32-WITHFP-NEXT: addi s0, sp, 16 +; RV32-WITHFP-NEXT: lui a3, 261888 +; RV32-WITHFP-NEXT: li a4, 2 +; RV32-WITHFP-NEXT: li a2, 0 +; RV32-WITHFP-NEXT: call va1 +; RV32-WITHFP-NEXT: lw ra, 12(sp) # 4-byte Folded Reload +; RV32-WITHFP-NEXT: lw s0, 8(sp) # 4-byte Folded Reload +; RV32-WITHFP-NEXT: addi sp, sp, 16 +; RV32-WITHFP-NEXT: ret +; +; RV64-WITHFP-LABEL: va1_caller: +; RV64-WITHFP: # %bb.0: +; RV64-WITHFP-NEXT: addi sp, sp, -16 +; RV64-WITHFP-NEXT: sd ra, 8(sp) # 8-byte Folded Spill +; RV64-WITHFP-NEXT: sd s0, 0(sp) # 8-byte Folded Spill +; RV64-WITHFP-NEXT: addi s0, sp, 16 +; RV64-WITHFP-NEXT: lui a0, %hi(.LCPI3_0) +; RV64-WITHFP-NEXT: ld a1, %lo(.LCPI3_0)(a0) +; RV64-WITHFP-NEXT: li a2, 2 +; RV64-WITHFP-NEXT: call va1 +; RV64-WITHFP-NEXT: ld ra, 8(sp) # 8-byte Folded Reload +; RV64-WITHFP-NEXT: ld s0, 0(sp) # 8-byte Folded Reload +; RV64-WITHFP-NEXT: addi sp, sp, 16 +; RV64-WITHFP-NEXT: ret %1 = call i32 (ptr, ...) @va1(ptr undef, double 1.0, i32 2) ret void } @@ -395,6 +616,59 @@ define i64 @va2(ptr %fmt, ...) nounwind { ; RV64-NEXT: ld a0, 0(a1) ; RV64-NEXT: addi sp, sp, 80 ; RV64-NEXT: ret +; +; RV32-WITHFP-LABEL: va2: +; RV32-WITHFP: # %bb.0: +; RV32-WITHFP-NEXT: addi sp, sp, -48 +; RV32-WITHFP-NEXT: sw ra, 12(sp) # 4-byte Folded Spill +; RV32-WITHFP-NEXT: sw s0, 8(sp) # 4-byte Folded Spill +; RV32-WITHFP-NEXT: addi s0, sp, 16 +; RV32-WITHFP-NEXT: sw a1, 4(s0) +; RV32-WITHFP-NEXT: sw a2, 8(s0) +; RV32-WITHFP-NEXT: sw a3, 12(s0) +; RV32-WITHFP-NEXT: sw a4, 16(s0) +; RV32-WITHFP-NEXT: addi a0, s0, 4 +; RV32-WITHFP-NEXT: sw a0, -12(s0) +; RV32-WITHFP-NEXT: lw a0, -12(s0) +; RV32-WITHFP-NEXT: sw a5, 20(s0) +; RV32-WITHFP-NEXT: sw a6, 24(s0) +; RV32-WITHFP-NEXT: sw a7, 28(s0) +; RV32-WITHFP-NEXT: addi a0, a0, 7 +; RV32-WITHFP-NEXT: andi a1, a0, -8 +; RV32-WITHFP-NEXT: addi a0, a0, 8 +; RV32-WITHFP-NEXT: sw a0, -12(s0) +; RV32-WITHFP-NEXT: lw a0, 0(a1) +; RV32-WITHFP-NEXT: lw a1, 4(a1) +; RV32-WITHFP-NEXT: lw ra, 12(sp) # 4-byte Folded Reload +; RV32-WITHFP-NEXT: lw s0, 8(sp) # 4-byte Folded Reload +; RV32-WITHFP-NEXT: addi sp, sp, 48 +; RV32-WITHFP-NEXT: ret +; +; RV64-WITHFP-LABEL: va2: +; RV64-WITHFP: # %bb.0: +; RV64-WITHFP-NEXT: addi sp, sp, -96 +; RV64-WITHFP-NEXT: sd ra, 24(sp) # 8-byte Folded Spill +; RV64-WITHFP-NEXT: sd s0, 16(sp) # 8-byte Folded Spill +; RV64-WITHFP-NEXT: addi s0, sp, 32 +; RV64-WITHFP-NEXT: sd a1, 8(s0) +; RV64-WITHFP-NEXT: sd a2, 16(s0) +; RV64-WITHFP-NEXT: sd a3, 24(s0) +; RV64-WITHFP-NEXT: sd a4, 32(s0) +; RV64-WITHFP-NEXT: addi a0, s0, 8 +; RV64-WITHFP-NEXT: sd a0, -24(s0) +; RV64-WITHFP-NEXT: ld a0, -24(s0) +; RV64-WITHFP-NEXT: sd a5, 40(s0) +; RV64-WITHFP-NEXT: sd a6, 48(s0) +; RV64-WITHFP-NEXT: sd a7, 56(s0) +; RV64-WITHFP-NEXT: addi a1, a0, 7 +; RV64-WITHFP-NEXT: andi a1, a1, -8 +; RV64-WITHFP-NEXT: addi a0, a0, 15 +; RV64-WITHFP-NEXT: sd a0, -24(s0) +; RV64-WITHFP-NEXT: ld a0, 0(a1) +; RV64-WITHFP-NEXT: ld ra, 24(sp) # 8-byte Folded Reload +; RV64-WITHFP-NEXT: ld s0, 16(sp) # 8-byte Folded Reload +; RV64-WITHFP-NEXT: addi sp, sp, 96 +; RV64-WITHFP-NEXT: ret %va = alloca ptr call void @llvm.va_start(ptr %va) %argp.cur = load ptr, ptr %va @@ -459,6 +733,61 @@ define i64 @va2_va_arg(ptr %fmt, ...) nounwind { ; RV64-NEXT: srli a0, a0, 32 ; RV64-NEXT: addi sp, sp, 80 ; RV64-NEXT: ret +; +; RV32-WITHFP-LABEL: va2_va_arg: +; RV32-WITHFP: # %bb.0: +; RV32-WITHFP-NEXT: addi sp, sp, -48 +; RV32-WITHFP-NEXT: sw ra, 12(sp) # 4-byte Folded Spill +; RV32-WITHFP-NEXT: sw s0, 8(sp) # 4-byte Folded Spill +; RV32-WITHFP-NEXT: addi s0, sp, 16 +; RV32-WITHFP-NEXT: sw a1, 4(s0) +; RV32-WITHFP-NEXT: sw a2, 8(s0) +; RV32-WITHFP-NEXT: sw a3, 12(s0) +; RV32-WITHFP-NEXT: sw a4, 16(s0) +; RV32-WITHFP-NEXT: sw a5, 20(s0) +; RV32-WITHFP-NEXT: sw a6, 24(s0) +; RV32-WITHFP-NEXT: sw a7, 28(s0) +; RV32-WITHFP-NEXT: addi a0, s0, 4 +; RV32-WITHFP-NEXT: sw a0, -12(s0) +; RV32-WITHFP-NEXT: lw a0, -12(s0) +; RV32-WITHFP-NEXT: addi a0, a0, 3 +; RV32-WITHFP-NEXT: andi a0, a0, -4 +; RV32-WITHFP-NEXT: addi a1, a0, 4 +; RV32-WITHFP-NEXT: sw a1, -12(s0) +; RV32-WITHFP-NEXT: lw a0, 0(a0) +; RV32-WITHFP-NEXT: li a1, 0 +; RV32-WITHFP-NEXT: lw ra, 12(sp) # 4-byte Folded Reload +; RV32-WITHFP-NEXT: lw s0, 8(sp) # 4-byte Folded Reload +; RV32-WITHFP-NEXT: addi sp, sp, 48 +; RV32-WITHFP-NEXT: ret +; +; RV64-WITHFP-LABEL: va2_va_arg: +; RV64-WITHFP: # %bb.0: +; RV64-WITHFP-NEXT: addi sp, sp, -96 +; RV64-WITHFP-NEXT: sd ra, 24(sp) # 8-byte Folded Spill +; RV64-WITHFP-NEXT: sd s0, 16(sp) # 8-byte Folded Spill +; RV64-WITHFP-NEXT: addi s0, sp, 32 +; RV64-WITHFP-NEXT: sd a1, 8(s0) +; RV64-WITHFP-NEXT: sd a2, 16(s0) +; RV64-WITHFP-NEXT: sd a3, 24(s0) +; RV64-WITHFP-NEXT: sd a4, 32(s0) +; RV64-WITHFP-NEXT: sd a5, 40(s0) +; RV64-WITHFP-NEXT: sd a6, 48(s0) +; RV64-WITHFP-NEXT: sd a7, 56(s0) +; RV64-WITHFP-NEXT: addi a0, s0, 8 +; RV64-WITHFP-NEXT: sd a0, -24(s0) +; RV64-WITHFP-NEXT: ld a0, -24(s0) +; RV64-WITHFP-NEXT: addi a0, a0, 3 +; RV64-WITHFP-NEXT: andi a0, a0, -4 +; RV64-WITHFP-NEXT: addi a1, a0, 4 +; RV64-WITHFP-NEXT: sd a1, -24(s0) +; RV64-WITHFP-NEXT: lw a0, 0(a0) +; RV64-WITHFP-NEXT: slli a0, a0, 32 +; RV64-WITHFP-NEXT: srli a0, a0, 32 +; RV64-WITHFP-NEXT: ld ra, 24(sp) # 8-byte Folded Reload +; RV64-WITHFP-NEXT: ld s0, 16(sp) # 8-byte Folded Reload +; RV64-WITHFP-NEXT: addi sp, sp, 96 +; RV64-WITHFP-NEXT: ret %va = alloca ptr call void @llvm.va_start(ptr %va) %1 = va_arg ptr %va, i32 @@ -487,6 +816,32 @@ define void @va2_caller() nounwind { ; RV64-NEXT: ld ra, 8(sp) # 8-byte Folded Reload ; RV64-NEXT: addi sp, sp, 16 ; RV64-NEXT: ret +; +; RV32-WITHFP-LABEL: va2_caller: +; RV32-WITHFP: # %bb.0: +; RV32-WITHFP-NEXT: addi sp, sp, -16 +; RV32-WITHFP-NEXT: sw ra, 12(sp) # 4-byte Folded Spill +; RV32-WITHFP-NEXT: sw s0, 8(sp) # 4-byte Folded Spill +; RV32-WITHFP-NEXT: addi s0, sp, 16 +; RV32-WITHFP-NEXT: li a1, 1 +; RV32-WITHFP-NEXT: call va2 +; RV32-WITHFP-NEXT: lw ra, 12(sp) # 4-byte Folded Reload +; RV32-WITHFP-NEXT: lw s0, 8(sp) # 4-byte Folded Reload +; RV32-WITHFP-NEXT: addi sp, sp, 16 +; RV32-WITHFP-NEXT: ret +; +; RV64-WITHFP-LABEL: va2_caller: +; RV64-WITHFP: # %bb.0: +; RV64-WITHFP-NEXT: addi sp, sp, -16 +; RV64-WITHFP-NEXT: sd ra, 8(sp) # 8-byte Folded Spill +; RV64-WITHFP-NEXT: sd s0, 0(sp) # 8-byte Folded Spill +; RV64-WITHFP-NEXT: addi s0, sp, 16 +; RV64-WITHFP-NEXT: li a1, 1 +; RV64-WITHFP-NEXT: call va2 +; RV64-WITHFP-NEXT: ld ra, 8(sp) # 8-byte Folded Reload +; RV64-WITHFP-NEXT: ld s0, 0(sp) # 8-byte Folded Reload +; RV64-WITHFP-NEXT: addi sp, sp, 16 +; RV64-WITHFP-NEXT: ret %1 = call i64 (ptr, ...) @va2(ptr undef, i32 1) ret void } @@ -617,6 +972,61 @@ define i64 @va3(i32 %a, i64 %b, ...) nounwind { ; RV64-NEXT: add a0, a1, a0 ; RV64-NEXT: addi sp, sp, 64 ; RV64-NEXT: ret +; +; RV32-WITHFP-LABEL: va3: +; RV32-WITHFP: # %bb.0: +; RV32-WITHFP-NEXT: addi sp, sp, -48 +; RV32-WITHFP-NEXT: sw ra, 20(sp) # 4-byte Folded Spill +; RV32-WITHFP-NEXT: sw s0, 16(sp) # 4-byte Folded Spill +; RV32-WITHFP-NEXT: addi s0, sp, 24 +; RV32-WITHFP-NEXT: sw a3, 4(s0) +; RV32-WITHFP-NEXT: sw a4, 8(s0) +; RV32-WITHFP-NEXT: addi a0, s0, 4 +; RV32-WITHFP-NEXT: sw a0, -12(s0) +; RV32-WITHFP-NEXT: lw a0, -12(s0) +; RV32-WITHFP-NEXT: sw a5, 12(s0) +; RV32-WITHFP-NEXT: sw a6, 16(s0) +; RV32-WITHFP-NEXT: sw a7, 20(s0) +; RV32-WITHFP-NEXT: addi a0, a0, 7 +; RV32-WITHFP-NEXT: andi a3, a0, -8 +; RV32-WITHFP-NEXT: addi a0, a0, 8 +; RV32-WITHFP-NEXT: sw a0, -12(s0) +; RV32-WITHFP-NEXT: lw a4, 0(a3) +; RV32-WITHFP-NEXT: lw a3, 4(a3) +; RV32-WITHFP-NEXT: add a0, a1, a4 +; RV32-WITHFP-NEXT: sltu a1, a0, a4 +; RV32-WITHFP-NEXT: add a2, a2, a3 +; RV32-WITHFP-NEXT: add a1, a2, a1 +; RV32-WITHFP-NEXT: lw ra, 20(sp) # 4-byte Folded Reload +; RV32-WITHFP-NEXT: lw s0, 16(sp) # 4-byte Folded Reload +; RV32-WITHFP-NEXT: addi sp, sp, 48 +; RV32-WITHFP-NEXT: ret +; +; RV64-WITHFP-LABEL: va3: +; RV64-WITHFP: # %bb.0: +; RV64-WITHFP-NEXT: addi sp, sp, -80 +; RV64-WITHFP-NEXT: sd ra, 24(sp) # 8-byte Folded Spill +; RV64-WITHFP-NEXT: sd s0, 16(sp) # 8-byte Folded Spill +; RV64-WITHFP-NEXT: addi s0, sp, 32 +; RV64-WITHFP-NEXT: sd a2, 0(s0) +; RV64-WITHFP-NEXT: sd a3, 8(s0) +; RV64-WITHFP-NEXT: sd a4, 16(s0) +; RV64-WITHFP-NEXT: mv a0, s0 +; RV64-WITHFP-NEXT: sd a0, -24(s0) +; RV64-WITHFP-NEXT: ld a0, -24(s0) +; RV64-WITHFP-NEXT: sd a5, 24(s0) +; RV64-WITHFP-NEXT: sd a6, 32(s0) +; RV64-WITHFP-NEXT: sd a7, 40(s0) +; RV64-WITHFP-NEXT: addi a2, a0, 7 +; RV64-WITHFP-NEXT: andi a2, a2, -8 +; RV64-WITHFP-NEXT: addi a0, a0, 15 +; RV64-WITHFP-NEXT: sd a0, -24(s0) +; RV64-WITHFP-NEXT: ld a0, 0(a2) +; RV64-WITHFP-NEXT: add a0, a1, a0 +; RV64-WITHFP-NEXT: ld ra, 24(sp) # 8-byte Folded Reload +; RV64-WITHFP-NEXT: ld s0, 16(sp) # 8-byte Folded Reload +; RV64-WITHFP-NEXT: addi sp, sp, 80 +; RV64-WITHFP-NEXT: ret %va = alloca ptr call void @llvm.va_start(ptr %va) %argp.cur = load ptr, ptr %va @@ -682,6 +1092,61 @@ define i64 @va3_va_arg(i32 %a, i64 %b, ...) nounwind { ; RV64-NEXT: add a0, a1, a0 ; RV64-NEXT: addi sp, sp, 64 ; RV64-NEXT: ret +; +; RV32-WITHFP-LABEL: va3_va_arg: +; RV32-WITHFP: # %bb.0: +; RV32-WITHFP-NEXT: addi sp, sp, -48 +; RV32-WITHFP-NEXT: sw ra, 20(sp) # 4-byte Folded Spill +; RV32-WITHFP-NEXT: sw s0, 16(sp) # 4-byte Folded Spill +; RV32-WITHFP-NEXT: addi s0, sp, 24 +; RV32-WITHFP-NEXT: sw a3, 4(s0) +; RV32-WITHFP-NEXT: sw a4, 8(s0) +; RV32-WITHFP-NEXT: sw a5, 12(s0) +; RV32-WITHFP-NEXT: sw a6, 16(s0) +; RV32-WITHFP-NEXT: sw a7, 20(s0) +; RV32-WITHFP-NEXT: addi a0, s0, 4 +; RV32-WITHFP-NEXT: sw a0, -12(s0) +; RV32-WITHFP-NEXT: lw a0, -12(s0) +; RV32-WITHFP-NEXT: addi a0, a0, 3 +; RV32-WITHFP-NEXT: andi a0, a0, -4 +; RV32-WITHFP-NEXT: addi a3, a0, 4 +; RV32-WITHFP-NEXT: sw a3, -12(s0) +; RV32-WITHFP-NEXT: lw a3, 0(a0) +; RV32-WITHFP-NEXT: add a0, a1, a3 +; RV32-WITHFP-NEXT: sltu a1, a0, a3 +; RV32-WITHFP-NEXT: add a1, a2, a1 +; RV32-WITHFP-NEXT: lw ra, 20(sp) # 4-byte Folded Reload +; RV32-WITHFP-NEXT: lw s0, 16(sp) # 4-byte Folded Reload +; RV32-WITHFP-NEXT: addi sp, sp, 48 +; RV32-WITHFP-NEXT: ret +; +; RV64-WITHFP-LABEL: va3_va_arg: +; RV64-WITHFP: # %bb.0: +; RV64-WITHFP-NEXT: addi sp, sp, -80 +; RV64-WITHFP-NEXT: sd ra, 24(sp) # 8-byte Folded Spill +; RV64-WITHFP-NEXT: sd s0, 16(sp) # 8-byte Folded Spill +; RV64-WITHFP-NEXT: addi s0, sp, 32 +; RV64-WITHFP-NEXT: sd a2, 0(s0) +; RV64-WITHFP-NEXT: sd a3, 8(s0) +; RV64-WITHFP-NEXT: sd a4, 16(s0) +; RV64-WITHFP-NEXT: sd a5, 24(s0) +; RV64-WITHFP-NEXT: sd a6, 32(s0) +; RV64-WITHFP-NEXT: sd a7, 40(s0) +; RV64-WITHFP-NEXT: mv a0, s0 +; RV64-WITHFP-NEXT: sd a0, -24(s0) +; RV64-WITHFP-NEXT: ld a0, -24(s0) +; RV64-WITHFP-NEXT: addi a0, a0, 3 +; RV64-WITHFP-NEXT: andi a0, a0, -4 +; RV64-WITHFP-NEXT: addi a2, a0, 4 +; RV64-WITHFP-NEXT: sd a2, -24(s0) +; RV64-WITHFP-NEXT: lw a0, 0(a0) +; RV64-WITHFP-NEXT: slli a0, a0, 32 +; RV64-WITHFP-NEXT: srli a0, a0, 32 +; RV64-WITHFP-NEXT: add a0, a1, a0 +; RV64-WITHFP-NEXT: ld ra, 24(sp) # 8-byte Folded Reload +; RV64-WITHFP-NEXT: ld s0, 16(sp) # 8-byte Folded Reload +; RV64-WITHFP-NEXT: addi sp, sp, 80 +; RV64-WITHFP-NEXT: ret %va = alloca ptr call void @llvm.va_start(ptr %va) %1 = va_arg ptr %va, i32 @@ -718,6 +1183,39 @@ define void @va3_caller() nounwind { ; RV64-NEXT: ld ra, 8(sp) # 8-byte Folded Reload ; RV64-NEXT: addi sp, sp, 16 ; RV64-NEXT: ret +; +; RV32-WITHFP-LABEL: va3_caller: +; RV32-WITHFP: # %bb.0: +; RV32-WITHFP-NEXT: addi sp, sp, -16 +; RV32-WITHFP-NEXT: sw ra, 12(sp) # 4-byte Folded Spill +; RV32-WITHFP-NEXT: sw s0, 8(sp) # 4-byte Folded Spill +; RV32-WITHFP-NEXT: addi s0, sp, 16 +; RV32-WITHFP-NEXT: lui a0, 5 +; RV32-WITHFP-NEXT: addi a3, a0, -480 +; RV32-WITHFP-NEXT: li a0, 2 +; RV32-WITHFP-NEXT: li a1, 1111 +; RV32-WITHFP-NEXT: li a2, 0 +; RV32-WITHFP-NEXT: call va3 +; RV32-WITHFP-NEXT: lw ra, 12(sp) # 4-byte Folded Reload +; RV32-WITHFP-NEXT: lw s0, 8(sp) # 4-byte Folded Reload +; RV32-WITHFP-NEXT: addi sp, sp, 16 +; RV32-WITHFP-NEXT: ret +; +; RV64-WITHFP-LABEL: va3_caller: +; RV64-WITHFP: # %bb.0: +; RV64-WITHFP-NEXT: addi sp, sp, -16 +; RV64-WITHFP-NEXT: sd ra, 8(sp) # 8-byte Folded Spill +; RV64-WITHFP-NEXT: sd s0, 0(sp) # 8-byte Folded Spill +; RV64-WITHFP-NEXT: addi s0, sp, 16 +; RV64-WITHFP-NEXT: lui a0, 5 +; RV64-WITHFP-NEXT: addiw a2, a0, -480 +; RV64-WITHFP-NEXT: li a0, 2 +; RV64-WITHFP-NEXT: li a1, 1111 +; RV64-WITHFP-NEXT: call va3 +; RV64-WITHFP-NEXT: ld ra, 8(sp) # 8-byte Folded Reload +; RV64-WITHFP-NEXT: ld s0, 0(sp) # 8-byte Folded Reload +; RV64-WITHFP-NEXT: addi sp, sp, 16 +; RV64-WITHFP-NEXT: ret %1 = call i64 (i32, i64, ...) @va3(i32 2, i64 1111, i32 20000) ret void } @@ -745,9 +1243,8 @@ define i32 @va4_va_copy(i32 %argno, ...) nounwind { ; RV32-NEXT: addi a1, a0, 4 ; RV32-NEXT: sw a1, 4(sp) ; RV32-NEXT: lw a1, 4(sp) -; RV32-NEXT: mv a2, sp ; RV32-NEXT: lw s0, 0(a0) -; RV32-NEXT: sw a2, 0(a1) +; RV32-NEXT: sw a1, 0(sp) ; RV32-NEXT: lw a0, 0(sp) ; RV32-NEXT: call notdead ; RV32-NEXT: lw a0, 4(sp) @@ -796,9 +1293,8 @@ define i32 @va4_va_copy(i32 %argno, ...) nounwind { ; RV64-NEXT: addi a1, a0, 4 ; RV64-NEXT: sd a1, 8(sp) ; RV64-NEXT: ld a1, 8(sp) -; RV64-NEXT: mv a2, sp ; RV64-NEXT: lw s0, 0(a0) -; RV64-NEXT: sd a2, 0(a1) +; RV64-NEXT: sd a1, 0(sp) ; RV64-NEXT: lw a0, 4(sp) ; RV64-NEXT: lwu a1, 0(sp) ; RV64-NEXT: slli a0, a0, 32 @@ -829,6 +1325,115 @@ define i32 @va4_va_copy(i32 %argno, ...) nounwind { ; RV64-NEXT: ld s0, 16(sp) # 8-byte Folded Reload ; RV64-NEXT: addi sp, sp, 96 ; RV64-NEXT: ret +; +; RV32-WITHFP-LABEL: va4_va_copy: +; RV32-WITHFP: # %bb.0: +; RV32-WITHFP-NEXT: addi sp, sp, -64 +; RV32-WITHFP-NEXT: sw ra, 28(sp) # 4-byte Folded Spill +; RV32-WITHFP-NEXT: sw s0, 24(sp) # 4-byte Folded Spill +; RV32-WITHFP-NEXT: sw s1, 20(sp) # 4-byte Folded Spill +; RV32-WITHFP-NEXT: addi s0, sp, 32 +; RV32-WITHFP-NEXT: sw a1, 4(s0) +; RV32-WITHFP-NEXT: sw a2, 8(s0) +; RV32-WITHFP-NEXT: sw a3, 12(s0) +; RV32-WITHFP-NEXT: sw a4, 16(s0) +; RV32-WITHFP-NEXT: sw a5, 20(s0) +; RV32-WITHFP-NEXT: sw a6, 24(s0) +; RV32-WITHFP-NEXT: sw a7, 28(s0) +; RV32-WITHFP-NEXT: addi a0, s0, 4 +; RV32-WITHFP-NEXT: sw a0, -16(s0) +; RV32-WITHFP-NEXT: lw a0, -16(s0) +; RV32-WITHFP-NEXT: addi a0, a0, 3 +; RV32-WITHFP-NEXT: andi a0, a0, -4 +; RV32-WITHFP-NEXT: addi a1, a0, 4 +; RV32-WITHFP-NEXT: sw a1, -16(s0) +; RV32-WITHFP-NEXT: lw a1, -16(s0) +; RV32-WITHFP-NEXT: lw s1, 0(a0) +; RV32-WITHFP-NEXT: sw a1, -20(s0) +; RV32-WITHFP-NEXT: lw a0, -20(s0) +; RV32-WITHFP-NEXT: call notdead +; RV32-WITHFP-NEXT: lw a0, -16(s0) +; RV32-WITHFP-NEXT: addi a0, a0, 3 +; RV32-WITHFP-NEXT: andi a0, a0, -4 +; RV32-WITHFP-NEXT: addi a1, a0, 4 +; RV32-WITHFP-NEXT: sw a1, -16(s0) +; RV32-WITHFP-NEXT: lw a1, -16(s0) +; RV32-WITHFP-NEXT: lw a0, 0(a0) +; RV32-WITHFP-NEXT: addi a1, a1, 3 +; RV32-WITHFP-NEXT: andi a1, a1, -4 +; RV32-WITHFP-NEXT: addi a2, a1, 4 +; RV32-WITHFP-NEXT: sw a2, -16(s0) +; RV32-WITHFP-NEXT: lw a2, -16(s0) +; RV32-WITHFP-NEXT: lw a1, 0(a1) +; RV32-WITHFP-NEXT: addi a2, a2, 3 +; RV32-WITHFP-NEXT: andi a2, a2, -4 +; RV32-WITHFP-NEXT: addi a3, a2, 4 +; RV32-WITHFP-NEXT: sw a3, -16(s0) +; RV32-WITHFP-NEXT: lw a2, 0(a2) +; RV32-WITHFP-NEXT: add a0, a0, s1 +; RV32-WITHFP-NEXT: add a1, a1, a2 +; RV32-WITHFP-NEXT: add a0, a0, a1 +; RV32-WITHFP-NEXT: lw ra, 28(sp) # 4-byte Folded Reload +; RV32-WITHFP-NEXT: lw s0, 24(sp) # 4-byte Folded Reload +; RV32-WITHFP-NEXT: lw s1, 20(sp) # 4-byte Folded Reload +; RV32-WITHFP-NEXT: addi sp, sp, 64 +; RV32-WITHFP-NEXT: ret +; +; RV64-WITHFP-LABEL: va4_va_copy: +; RV64-WITHFP: # %bb.0: +; RV64-WITHFP-NEXT: addi sp, sp, -112 +; RV64-WITHFP-NEXT: sd ra, 40(sp) # 8-byte Folded Spill +; RV64-WITHFP-NEXT: sd s0, 32(sp) # 8-byte Folded Spill +; RV64-WITHFP-NEXT: sd s1, 24(sp) # 8-byte Folded Spill +; RV64-WITHFP-NEXT: addi s0, sp, 48 +; RV64-WITHFP-NEXT: sd a1, 8(s0) +; RV64-WITHFP-NEXT: sd a2, 16(s0) +; RV64-WITHFP-NEXT: sd a3, 24(s0) +; RV64-WITHFP-NEXT: sd a4, 32(s0) +; RV64-WITHFP-NEXT: sd a5, 40(s0) +; RV64-WITHFP-NEXT: sd a6, 48(s0) +; RV64-WITHFP-NEXT: sd a7, 56(s0) +; RV64-WITHFP-NEXT: addi a0, s0, 8 +; RV64-WITHFP-NEXT: sd a0, -32(s0) +; RV64-WITHFP-NEXT: ld a0, -32(s0) +; RV64-WITHFP-NEXT: addi a0, a0, 3 +; RV64-WITHFP-NEXT: andi a0, a0, -4 +; RV64-WITHFP-NEXT: addi a1, a0, 4 +; RV64-WITHFP-NEXT: sd a1, -32(s0) +; RV64-WITHFP-NEXT: ld a1, -32(s0) +; RV64-WITHFP-NEXT: lw s1, 0(a0) +; RV64-WITHFP-NEXT: sd a1, -40(s0) +; RV64-WITHFP-NEXT: lw a0, -36(s0) +; RV64-WITHFP-NEXT: lwu a1, -40(s0) +; RV64-WITHFP-NEXT: slli a0, a0, 32 +; RV64-WITHFP-NEXT: or a0, a0, a1 +; RV64-WITHFP-NEXT: call notdead +; RV64-WITHFP-NEXT: ld a0, -32(s0) +; RV64-WITHFP-NEXT: addi a0, a0, 3 +; RV64-WITHFP-NEXT: andi a0, a0, -4 +; RV64-WITHFP-NEXT: addi a1, a0, 4 +; RV64-WITHFP-NEXT: sd a1, -32(s0) +; RV64-WITHFP-NEXT: ld a1, -32(s0) +; RV64-WITHFP-NEXT: lw a0, 0(a0) +; RV64-WITHFP-NEXT: addi a1, a1, 3 +; RV64-WITHFP-NEXT: andi a1, a1, -4 +; RV64-WITHFP-NEXT: addi a2, a1, 4 +; RV64-WITHFP-NEXT: sd a2, -32(s0) +; RV64-WITHFP-NEXT: ld a2, -32(s0) +; RV64-WITHFP-NEXT: lw a1, 0(a1) +; RV64-WITHFP-NEXT: addi a2, a2, 3 +; RV64-WITHFP-NEXT: andi a2, a2, -4 +; RV64-WITHFP-NEXT: addi a3, a2, 4 +; RV64-WITHFP-NEXT: sd a3, -32(s0) +; RV64-WITHFP-NEXT: lw a2, 0(a2) +; RV64-WITHFP-NEXT: add a0, a0, s1 +; RV64-WITHFP-NEXT: add a1, a1, a2 +; RV64-WITHFP-NEXT: addw a0, a0, a1 +; RV64-WITHFP-NEXT: ld ra, 40(sp) # 8-byte Folded Reload +; RV64-WITHFP-NEXT: ld s0, 32(sp) # 8-byte Folded Reload +; RV64-WITHFP-NEXT: ld s1, 24(sp) # 8-byte Folded Reload +; RV64-WITHFP-NEXT: addi sp, sp, 112 +; RV64-WITHFP-NEXT: ret %vargs = alloca ptr %wargs = alloca ptr call void @llvm.va_start(ptr %vargs) @@ -899,6 +1504,60 @@ define i32 @va6_no_fixed_args(...) nounwind { ; RV64-NEXT: lw a0, 0(a0) ; RV64-NEXT: addi sp, sp, 80 ; RV64-NEXT: ret +; +; RV32-WITHFP-LABEL: va6_no_fixed_args: +; RV32-WITHFP: # %bb.0: +; RV32-WITHFP-NEXT: addi sp, sp, -48 +; RV32-WITHFP-NEXT: sw ra, 12(sp) # 4-byte Folded Spill +; RV32-WITHFP-NEXT: sw s0, 8(sp) # 4-byte Folded Spill +; RV32-WITHFP-NEXT: addi s0, sp, 16 +; RV32-WITHFP-NEXT: sw a0, 0(s0) +; RV32-WITHFP-NEXT: sw a1, 4(s0) +; RV32-WITHFP-NEXT: sw a2, 8(s0) +; RV32-WITHFP-NEXT: sw a3, 12(s0) +; RV32-WITHFP-NEXT: sw a4, 16(s0) +; RV32-WITHFP-NEXT: sw a5, 20(s0) +; RV32-WITHFP-NEXT: sw a6, 24(s0) +; RV32-WITHFP-NEXT: sw a7, 28(s0) +; RV32-WITHFP-NEXT: mv a0, s0 +; RV32-WITHFP-NEXT: sw a0, -12(s0) +; RV32-WITHFP-NEXT: lw a0, -12(s0) +; RV32-WITHFP-NEXT: addi a0, a0, 3 +; RV32-WITHFP-NEXT: andi a0, a0, -4 +; RV32-WITHFP-NEXT: addi a1, a0, 4 +; RV32-WITHFP-NEXT: sw a1, -12(s0) +; RV32-WITHFP-NEXT: lw a0, 0(a0) +; RV32-WITHFP-NEXT: lw ra, 12(sp) # 4-byte Folded Reload +; RV32-WITHFP-NEXT: lw s0, 8(sp) # 4-byte Folded Reload +; RV32-WITHFP-NEXT: addi sp, sp, 48 +; RV32-WITHFP-NEXT: ret +; +; RV64-WITHFP-LABEL: va6_no_fixed_args: +; RV64-WITHFP: # %bb.0: +; RV64-WITHFP-NEXT: addi sp, sp, -96 +; RV64-WITHFP-NEXT: sd ra, 24(sp) # 8-byte Folded Spill +; RV64-WITHFP-NEXT: sd s0, 16(sp) # 8-byte Folded Spill +; RV64-WITHFP-NEXT: addi s0, sp, 32 +; RV64-WITHFP-NEXT: sd a0, 0(s0) +; RV64-WITHFP-NEXT: sd a1, 8(s0) +; RV64-WITHFP-NEXT: sd a2, 16(s0) +; RV64-WITHFP-NEXT: sd a3, 24(s0) +; RV64-WITHFP-NEXT: sd a4, 32(s0) +; RV64-WITHFP-NEXT: sd a5, 40(s0) +; RV64-WITHFP-NEXT: sd a6, 48(s0) +; RV64-WITHFP-NEXT: sd a7, 56(s0) +; RV64-WITHFP-NEXT: mv a0, s0 +; RV64-WITHFP-NEXT: sd a0, -24(s0) +; RV64-WITHFP-NEXT: ld a0, -24(s0) +; RV64-WITHFP-NEXT: addi a0, a0, 3 +; RV64-WITHFP-NEXT: andi a0, a0, -4 +; RV64-WITHFP-NEXT: addi a1, a0, 4 +; RV64-WITHFP-NEXT: sd a1, -24(s0) +; RV64-WITHFP-NEXT: lw a0, 0(a0) +; RV64-WITHFP-NEXT: ld ra, 24(sp) # 8-byte Folded Reload +; RV64-WITHFP-NEXT: ld s0, 16(sp) # 8-byte Folded Reload +; RV64-WITHFP-NEXT: addi sp, sp, 96 +; RV64-WITHFP-NEXT: ret %va = alloca ptr call void @llvm.va_start(ptr %va) %1 = va_arg ptr %va, i32 @@ -993,6 +1652,85 @@ define i32 @va_large_stack(ptr %fmt, ...) { ; RV64-NEXT: addiw a1, a1, 336 ; RV64-NEXT: add sp, sp, a1 ; RV64-NEXT: ret +; +; RV32-WITHFP-LABEL: va_large_stack: +; RV32-WITHFP: # %bb.0: +; RV32-WITHFP-NEXT: addi sp, sp, -2032 +; RV32-WITHFP-NEXT: .cfi_def_cfa_offset 2032 +; RV32-WITHFP-NEXT: sw ra, 1996(sp) # 4-byte Folded Spill +; RV32-WITHFP-NEXT: sw s0, 1992(sp) # 4-byte Folded Spill +; RV32-WITHFP-NEXT: .cfi_offset ra, -36 +; RV32-WITHFP-NEXT: .cfi_offset s0, -40 +; RV32-WITHFP-NEXT: addi s0, sp, 2000 +; RV32-WITHFP-NEXT: .cfi_def_cfa s0, 32 +; RV32-WITHFP-NEXT: lui a0, 24414 +; RV32-WITHFP-NEXT: addi a0, a0, -1728 +; RV32-WITHFP-NEXT: sub sp, sp, a0 +; RV32-WITHFP-NEXT: lui a0, 24414 +; RV32-WITHFP-NEXT: addi a0, a0, 272 +; RV32-WITHFP-NEXT: sub a0, s0, a0 +; RV32-WITHFP-NEXT: sw a1, 4(s0) +; RV32-WITHFP-NEXT: sw a2, 8(s0) +; RV32-WITHFP-NEXT: sw a3, 12(s0) +; RV32-WITHFP-NEXT: sw a4, 16(s0) +; RV32-WITHFP-NEXT: addi a1, s0, 4 +; RV32-WITHFP-NEXT: sw a1, 0(a0) +; RV32-WITHFP-NEXT: lw a1, 0(a0) +; RV32-WITHFP-NEXT: sw a5, 20(s0) +; RV32-WITHFP-NEXT: sw a6, 24(s0) +; RV32-WITHFP-NEXT: sw a7, 28(s0) +; RV32-WITHFP-NEXT: addi a2, a1, 4 +; RV32-WITHFP-NEXT: sw a2, 0(a0) +; RV32-WITHFP-NEXT: lw a0, 0(a1) +; RV32-WITHFP-NEXT: lui a1, 24414 +; RV32-WITHFP-NEXT: addi a1, a1, -1728 +; RV32-WITHFP-NEXT: add sp, sp, a1 +; RV32-WITHFP-NEXT: lw ra, 1996(sp) # 4-byte Folded Reload +; RV32-WITHFP-NEXT: lw s0, 1992(sp) # 4-byte Folded Reload +; RV32-WITHFP-NEXT: addi sp, sp, 2032 +; RV32-WITHFP-NEXT: ret +; +; RV64-WITHFP-LABEL: va_large_stack: +; RV64-WITHFP: # %bb.0: +; RV64-WITHFP-NEXT: addi sp, sp, -2032 +; RV64-WITHFP-NEXT: .cfi_def_cfa_offset 2032 +; RV64-WITHFP-NEXT: sd ra, 1960(sp) # 8-byte Folded Spill +; RV64-WITHFP-NEXT: sd s0, 1952(sp) # 8-byte Folded Spill +; RV64-WITHFP-NEXT: .cfi_offset ra, -72 +; RV64-WITHFP-NEXT: .cfi_offset s0, -80 +; RV64-WITHFP-NEXT: addi s0, sp, 1968 +; RV64-WITHFP-NEXT: .cfi_def_cfa s0, 64 +; RV64-WITHFP-NEXT: lui a0, 24414 +; RV64-WITHFP-NEXT: addiw a0, a0, -1680 +; RV64-WITHFP-NEXT: sub sp, sp, a0 +; RV64-WITHFP-NEXT: lui a0, 24414 +; RV64-WITHFP-NEXT: addiw a0, a0, 288 +; RV64-WITHFP-NEXT: sub a0, s0, a0 +; RV64-WITHFP-NEXT: sd a1, 8(s0) +; RV64-WITHFP-NEXT: sd a2, 16(s0) +; RV64-WITHFP-NEXT: sd a3, 24(s0) +; RV64-WITHFP-NEXT: sd a4, 32(s0) +; RV64-WITHFP-NEXT: sd a5, 40(s0) +; RV64-WITHFP-NEXT: addi a1, s0, 8 +; RV64-WITHFP-NEXT: sd a1, 0(a0) +; RV64-WITHFP-NEXT: lw a1, 4(a0) +; RV64-WITHFP-NEXT: lwu a2, 0(a0) +; RV64-WITHFP-NEXT: sd a6, 48(s0) +; RV64-WITHFP-NEXT: sd a7, 56(s0) +; RV64-WITHFP-NEXT: slli a1, a1, 32 +; RV64-WITHFP-NEXT: or a1, a1, a2 +; RV64-WITHFP-NEXT: addi a2, a1, 4 +; RV64-WITHFP-NEXT: srli a3, a2, 32 +; RV64-WITHFP-NEXT: sw a2, 0(a0) +; RV64-WITHFP-NEXT: sw a3, 4(a0) +; RV64-WITHFP-NEXT: lw a0, 0(a1) +; RV64-WITHFP-NEXT: lui a1, 24414 +; RV64-WITHFP-NEXT: addiw a1, a1, -1680 +; RV64-WITHFP-NEXT: add sp, sp, a1 +; RV64-WITHFP-NEXT: ld ra, 1960(sp) # 8-byte Folded Reload +; RV64-WITHFP-NEXT: ld s0, 1952(sp) # 8-byte Folded Reload +; RV64-WITHFP-NEXT: addi sp, sp, 2032 +; RV64-WITHFP-NEXT: ret %large = alloca [ 100000000 x i8 ] %va = alloca ptr call void @llvm.va_start(ptr %va) @@ -1004,5 +1742,193 @@ define i32 @va_large_stack(ptr %fmt, ...) { ret i32 %1 } +define i32 @va_vprintf(ptr %fmt, ptr %arg_start) { +; RV32-LABEL: va_vprintf: +; RV32: # %bb.0: +; RV32-NEXT: addi sp, sp, -16 +; RV32-NEXT: .cfi_def_cfa_offset 16 +; RV32-NEXT: sw a1, 12(sp) +; RV32-NEXT: lw a0, 12(sp) +; RV32-NEXT: sw a0, 8(sp) +; RV32-NEXT: lw a0, 8(sp) +; RV32-NEXT: addi a0, a0, 3 +; RV32-NEXT: andi a0, a0, -4 +; RV32-NEXT: addi a1, a0, 4 +; RV32-NEXT: sw a1, 8(sp) +; RV32-NEXT: lw a0, 0(a0) +; RV32-NEXT: addi sp, sp, 16 +; RV32-NEXT: ret +; +; RV64-LABEL: va_vprintf: +; RV64: # %bb.0: +; RV64-NEXT: addi sp, sp, -16 +; RV64-NEXT: .cfi_def_cfa_offset 16 +; RV64-NEXT: sd a1, 8(sp) +; RV64-NEXT: ld a0, 8(sp) +; RV64-NEXT: sd a0, 0(sp) +; RV64-NEXT: ld a0, 0(sp) +; RV64-NEXT: addi a0, a0, 3 +; RV64-NEXT: andi a0, a0, -4 +; RV64-NEXT: addi a1, a0, 4 +; RV64-NEXT: sd a1, 0(sp) +; RV64-NEXT: lw a0, 0(a0) +; RV64-NEXT: addi sp, sp, 16 +; RV64-NEXT: ret +; +; RV32-WITHFP-LABEL: va_vprintf: +; RV32-WITHFP: # %bb.0: +; RV32-WITHFP-NEXT: addi sp, sp, -16 +; RV32-WITHFP-NEXT: .cfi_def_cfa_offset 16 +; RV32-WITHFP-NEXT: sw ra, 12(sp) # 4-byte Folded Spill +; RV32-WITHFP-NEXT: sw s0, 8(sp) # 4-byte Folded Spill +; RV32-WITHFP-NEXT: .cfi_offset ra, -4 +; RV32-WITHFP-NEXT: .cfi_offset s0, -8 +; RV32-WITHFP-NEXT: addi s0, sp, 16 +; RV32-WITHFP-NEXT: .cfi_def_cfa s0, 0 +; RV32-WITHFP-NEXT: sw a1, -12(s0) +; RV32-WITHFP-NEXT: lw a0, -12(s0) +; RV32-WITHFP-NEXT: sw a0, -16(s0) +; RV32-WITHFP-NEXT: lw a0, -16(s0) +; RV32-WITHFP-NEXT: addi a0, a0, 3 +; RV32-WITHFP-NEXT: andi a0, a0, -4 +; RV32-WITHFP-NEXT: addi a1, a0, 4 +; RV32-WITHFP-NEXT: sw a1, -16(s0) +; RV32-WITHFP-NEXT: lw a0, 0(a0) +; RV32-WITHFP-NEXT: lw ra, 12(sp) # 4-byte Folded Reload +; RV32-WITHFP-NEXT: lw s0, 8(sp) # 4-byte Folded Reload +; RV32-WITHFP-NEXT: addi sp, sp, 16 +; RV32-WITHFP-NEXT: ret +; +; RV64-WITHFP-LABEL: va_vprintf: +; RV64-WITHFP: # %bb.0: +; RV64-WITHFP-NEXT: addi sp, sp, -32 +; RV64-WITHFP-NEXT: .cfi_def_cfa_offset 32 +; RV64-WITHFP-NEXT: sd ra, 24(sp) # 8-byte Folded Spill +; RV64-WITHFP-NEXT: sd s0, 16(sp) # 8-byte Folded Spill +; RV64-WITHFP-NEXT: .cfi_offset ra, -8 +; RV64-WITHFP-NEXT: .cfi_offset s0, -16 +; RV64-WITHFP-NEXT: addi s0, sp, 32 +; RV64-WITHFP-NEXT: .cfi_def_cfa s0, 0 +; RV64-WITHFP-NEXT: sd a1, -24(s0) +; RV64-WITHFP-NEXT: ld a0, -24(s0) +; RV64-WITHFP-NEXT: sd a0, -32(s0) +; RV64-WITHFP-NEXT: ld a0, -32(s0) +; RV64-WITHFP-NEXT: addi a0, a0, 3 +; RV64-WITHFP-NEXT: andi a0, a0, -4 +; RV64-WITHFP-NEXT: addi a1, a0, 4 +; RV64-WITHFP-NEXT: sd a1, -32(s0) +; RV64-WITHFP-NEXT: lw a0, 0(a0) +; RV64-WITHFP-NEXT: ld ra, 24(sp) # 8-byte Folded Reload +; RV64-WITHFP-NEXT: ld s0, 16(sp) # 8-byte Folded Reload +; RV64-WITHFP-NEXT: addi sp, sp, 32 +; RV64-WITHFP-NEXT: ret + %args = alloca ptr + %args_cp = alloca ptr + store ptr %arg_start, ptr %args + call void @llvm.va_copy(ptr %args_cp, ptr %args) + %width = va_arg ptr %args_cp, i32 + call void @llvm.va_end(ptr %args_cp) + ret i32 %width +} - +define i32 @va_printf(ptr %fmt, ...) { +; RV32-LABEL: va_printf: +; RV32: # %bb.0: +; RV32-NEXT: addi sp, sp, -48 +; RV32-NEXT: .cfi_def_cfa_offset 48 +; RV32-NEXT: sw ra, 12(sp) # 4-byte Folded Spill +; RV32-NEXT: .cfi_offset ra, -36 +; RV32-NEXT: sw a1, 20(sp) +; RV32-NEXT: sw a2, 24(sp) +; RV32-NEXT: sw a3, 28(sp) +; RV32-NEXT: sw a4, 32(sp) +; RV32-NEXT: addi a1, sp, 20 +; RV32-NEXT: sw a1, 8(sp) +; RV32-NEXT: lw a1, 8(sp) +; RV32-NEXT: sw a5, 36(sp) +; RV32-NEXT: sw a6, 40(sp) +; RV32-NEXT: sw a7, 44(sp) +; RV32-NEXT: call va_vprintf +; RV32-NEXT: lw ra, 12(sp) # 4-byte Folded Reload +; RV32-NEXT: addi sp, sp, 48 +; RV32-NEXT: ret +; +; RV64-LABEL: va_printf: +; RV64: # %bb.0: +; RV64-NEXT: addi sp, sp, -80 +; RV64-NEXT: .cfi_def_cfa_offset 80 +; RV64-NEXT: sd ra, 8(sp) # 8-byte Folded Spill +; RV64-NEXT: .cfi_offset ra, -72 +; RV64-NEXT: sd a1, 24(sp) +; RV64-NEXT: sd a2, 32(sp) +; RV64-NEXT: sd a3, 40(sp) +; RV64-NEXT: sd a4, 48(sp) +; RV64-NEXT: addi a1, sp, 24 +; RV64-NEXT: sd a1, 0(sp) +; RV64-NEXT: ld a1, 0(sp) +; RV64-NEXT: sd a5, 56(sp) +; RV64-NEXT: sd a6, 64(sp) +; RV64-NEXT: sd a7, 72(sp) +; RV64-NEXT: call va_vprintf +; RV64-NEXT: ld ra, 8(sp) # 8-byte Folded Reload +; RV64-NEXT: addi sp, sp, 80 +; RV64-NEXT: ret +; +; RV32-WITHFP-LABEL: va_printf: +; RV32-WITHFP: # %bb.0: +; RV32-WITHFP-NEXT: addi sp, sp, -48 +; RV32-WITHFP-NEXT: .cfi_def_cfa_offset 48 +; RV32-WITHFP-NEXT: sw ra, 12(sp) # 4-byte Folded Spill +; RV32-WITHFP-NEXT: sw s0, 8(sp) # 4-byte Folded Spill +; RV32-WITHFP-NEXT: .cfi_offset ra, -36 +; RV32-WITHFP-NEXT: .cfi_offset s0, -40 +; RV32-WITHFP-NEXT: addi s0, sp, 16 +; RV32-WITHFP-NEXT: .cfi_def_cfa s0, 32 +; RV32-WITHFP-NEXT: sw a1, 4(s0) +; RV32-WITHFP-NEXT: sw a2, 8(s0) +; RV32-WITHFP-NEXT: sw a3, 12(s0) +; RV32-WITHFP-NEXT: sw a4, 16(s0) +; RV32-WITHFP-NEXT: addi a1, s0, 4 +; RV32-WITHFP-NEXT: sw a1, -12(s0) +; RV32-WITHFP-NEXT: lw a1, -12(s0) +; RV32-WITHFP-NEXT: sw a5, 20(s0) +; RV32-WITHFP-NEXT: sw a6, 24(s0) +; RV32-WITHFP-NEXT: sw a7, 28(s0) +; RV32-WITHFP-NEXT: call va_vprintf +; RV32-WITHFP-NEXT: lw ra, 12(sp) # 4-byte Folded Reload +; RV32-WITHFP-NEXT: lw s0, 8(sp) # 4-byte Folded Reload +; RV32-WITHFP-NEXT: addi sp, sp, 48 +; RV32-WITHFP-NEXT: ret +; +; RV64-WITHFP-LABEL: va_printf: +; RV64-WITHFP: # %bb.0: +; RV64-WITHFP-NEXT: addi sp, sp, -96 +; RV64-WITHFP-NEXT: .cfi_def_cfa_offset 96 +; RV64-WITHFP-NEXT: sd ra, 24(sp) # 8-byte Folded Spill +; RV64-WITHFP-NEXT: sd s0, 16(sp) # 8-byte Folded Spill +; RV64-WITHFP-NEXT: .cfi_offset ra, -72 +; RV64-WITHFP-NEXT: .cfi_offset s0, -80 +; RV64-WITHFP-NEXT: addi s0, sp, 32 +; RV64-WITHFP-NEXT: .cfi_def_cfa s0, 64 +; RV64-WITHFP-NEXT: sd a1, 8(s0) +; RV64-WITHFP-NEXT: sd a2, 16(s0) +; RV64-WITHFP-NEXT: sd a3, 24(s0) +; RV64-WITHFP-NEXT: sd a4, 32(s0) +; RV64-WITHFP-NEXT: addi a1, s0, 8 +; RV64-WITHFP-NEXT: sd a1, -24(s0) +; RV64-WITHFP-NEXT: ld a1, -24(s0) +; RV64-WITHFP-NEXT: sd a5, 40(s0) +; RV64-WITHFP-NEXT: sd a6, 48(s0) +; RV64-WITHFP-NEXT: sd a7, 56(s0) +; RV64-WITHFP-NEXT: call va_vprintf +; RV64-WITHFP-NEXT: ld ra, 24(sp) # 8-byte Folded Reload +; RV64-WITHFP-NEXT: ld s0, 16(sp) # 8-byte Folded Reload +; RV64-WITHFP-NEXT: addi sp, sp, 96 +; RV64-WITHFP-NEXT: ret + %args = alloca ptr + call void @llvm.va_start(ptr %args) + %arg_start = load ptr, ptr %args + %ret_val = call i32 @va_vprintf(ptr %fmt, ptr %arg_start) + call void @llvm.va_end(ptr %args) + ret i32 %ret_val +} -- GitLab From 8963a476ccb7ef2944eedaf8813458561e29b465 Mon Sep 17 00:00:00 2001 From: Shan Huang <52285902006@stu.ecnu.edu.cn> Date: Thu, 28 Mar 2024 18:24:18 +0800 Subject: [PATCH 035/788] Fix #86269: remove unused variable (#86927) Remove the unused variable `BI` introduced in #86269. --- llvm/lib/Transforms/Scalar/TailRecursionElimination.cpp | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/llvm/lib/Transforms/Scalar/TailRecursionElimination.cpp b/llvm/lib/Transforms/Scalar/TailRecursionElimination.cpp index 34d39f3fe6dc..bc4b6de2f07f 100644 --- a/llvm/lib/Transforms/Scalar/TailRecursionElimination.cpp +++ b/llvm/lib/Transforms/Scalar/TailRecursionElimination.cpp @@ -509,10 +509,10 @@ void TailRecursionEliminator::createTailRecurseLoopHeader(CallInst *CI) { BasicBlock *NewEntry = BasicBlock::Create(F.getContext(), "", &F, HeaderBB); NewEntry->takeName(HeaderBB); HeaderBB->setName("tailrecurse"); - BranchInst *BI = BranchInst::Create(HeaderBB, NewEntry); + BranchInst::Create(HeaderBB, NewEntry); // If the new branch preserves the debug location of CI, it could result in // misleading stepping, if CI is located in a conditional branch. - // So, here we don't give any debug location to BI. + // So, here we don't give any debug location to the new branch. // Move all fixed sized allocas from HeaderBB to NewEntry. for (BasicBlock::iterator OEBI = HeaderBB->begin(), E = HeaderBB->end(), -- GitLab From 8a7f021f9e183c95f3eb17a27cbb219e204f3b25 Mon Sep 17 00:00:00 2001 From: "J. Ryan Stinnett" Date: Thu, 28 Mar 2024 10:37:31 +0000 Subject: [PATCH 036/788] [GitHub] Fix typos in automation (#86886) --- llvm/utils/git/github-automation.py | 14 +++++++------- 1 file changed, 7 insertions(+), 7 deletions(-) diff --git a/llvm/utils/git/github-automation.py b/llvm/utils/git/github-automation.py index 42a658cefac3..1b5141e42594 100755 --- a/llvm/utils/git/github-automation.py +++ b/llvm/utils/git/github-automation.py @@ -36,7 +36,7 @@ If you have any further questions about this issue, don't hesitate to ask via a """ -def _get_curent_team(team_name, teams) -> Optional[github.Team.Team]: +def _get_current_team(team_name, teams) -> Optional[github.Team.Team]: for team in teams: if team_name == team.name.lower(): return team @@ -70,7 +70,7 @@ class IssueSubscriber: self._team_name = "issue-subscribers-{}".format(label_name).lower() def run(self) -> bool: - team = _get_curent_team(self.team_name, self.org.get_teams()) + team = _get_current_team(self.team_name, self.org.get_teams()) if not team: print(f"couldn't find team named {self.team_name}") return False @@ -125,7 +125,7 @@ class PRSubscriber: def run(self) -> bool: patch = None - team = _get_curent_team(self.team_name, self.org.get_teams()) + team = _get_current_team(self.team_name, self.org.get_teams()) if not team: print(f"couldn't find team named {self.team_name}") return False @@ -201,7 +201,7 @@ Author: {self.pr.user.name} ({self.pr.user.login}) ) return True - def _get_curent_team(self) -> Optional[github.Team.Team]: + def _get_current_team(self) -> Optional[github.Team.Team]: for team in self.org.get_teams(): if self.team_name == team.name.lower(): return team @@ -281,7 +281,7 @@ class PRBuildbotInformation: @{self.author} Congratulations on having your first Pull Request (PR) merged into the LLVM Project! Your changes will be combined with recent changes from other authors, then tested -by our [build bots](https://lab.llvm.org/buildbot/). If there is a problem with a build, you may recieve a report in an email or a comment on this PR. +by our [build bots](https://lab.llvm.org/buildbot/). If there is a problem with a build, you may receive a report in an email or a comment on this PR. Please check whether problems have been caused by your change specifically, as the builds can include changes from many authors. It is not uncommon for your @@ -639,7 +639,7 @@ class ReleaseWorkflow: parser = argparse.ArgumentParser() parser.add_argument( - "--token", type=str, required=True, help="GitHub authentiation token" + "--token", type=str, required=True, help="GitHub authentication token" ) parser.add_argument( "--repo", @@ -669,7 +669,7 @@ release_workflow_parser.add_argument( "--llvm-project-dir", type=str, default=".", - help="directory containing the llvm-project checout", + help="directory containing the llvm-project checkout", ) release_workflow_parser.add_argument( "--issue-number", type=int, required=True, help="The issue number to update" -- GitLab From 79ba323bdd0843275019e16b6e9b35133677c514 Mon Sep 17 00:00:00 2001 From: Shan Huang <52285902006@stu.ecnu.edu.cn> Date: Thu, 28 Mar 2024 18:43:03 +0800 Subject: [PATCH 037/788] [Debuginfo][GVNHoist] Fix #86227: update the debug location of the hoisted GEP (#86236) This PR fixes #86227. --- llvm/lib/Transforms/Scalar/GVNHoist.cpp | 8 +++ .../Transforms/GVNHoist/hoist-merge-geps.ll | 63 +++++++++++++++++++ 2 files changed, 71 insertions(+) create mode 100644 llvm/test/Transforms/GVNHoist/hoist-merge-geps.ll diff --git a/llvm/lib/Transforms/Scalar/GVNHoist.cpp b/llvm/lib/Transforms/Scalar/GVNHoist.cpp index b564f00eb9d1..261c1259c9c9 100644 --- a/llvm/lib/Transforms/Scalar/GVNHoist.cpp +++ b/llvm/lib/Transforms/Scalar/GVNHoist.cpp @@ -951,6 +951,14 @@ void GVNHoist::makeGepsAvailable(Instruction *Repl, BasicBlock *HoistPt, OtherGep = cast( cast(OtherInst)->getPointerOperand()); ClonedGep->andIRFlags(OtherGep); + + // Merge debug locations of GEPs, because the hoisted GEP replaces those + // in branches. When cloning, ClonedGep preserves the debug location of + // Gepd, so Gep is skipped to avoid merging it twice. + if (OtherGep != Gep) { + ClonedGep->applyMergedLocation(ClonedGep->getDebugLoc(), + OtherGep->getDebugLoc()); + } } // Replace uses of Gep with ClonedGep in Repl. diff --git a/llvm/test/Transforms/GVNHoist/hoist-merge-geps.ll b/llvm/test/Transforms/GVNHoist/hoist-merge-geps.ll new file mode 100644 index 000000000000..b3b5916c7f26 --- /dev/null +++ b/llvm/test/Transforms/GVNHoist/hoist-merge-geps.ll @@ -0,0 +1,63 @@ +; RUN: opt -S -passes=gvn-hoist < %s | FileCheck %s + +define dso_local void @func(i32 noundef %a, ptr noundef %b) !dbg !10 { +; Check the merged debug location of hoisted GEP +; CHECK: entry +; CHECK: %{{[a-zA-Z0-9_]*}} = getelementptr {{.*}} !dbg [[MERGED_DL:![0-9]+]] +; CHECK: [[MERGED_DL]] = !DILocation(line: 0, scope: !{{[0-9]+}}) +entry: + tail call void @llvm.dbg.value(metadata i32 %a, metadata !16, metadata !DIExpression()), !dbg !17 + tail call void @llvm.dbg.value(metadata ptr %b, metadata !18, metadata !DIExpression()), !dbg !17 + %tobool = icmp ne i32 %a, 0, !dbg !19 + br i1 %tobool, label %if.then, label %if.else, !dbg !21 + +if.then: ; preds = %entry + %arrayidx = getelementptr inbounds i32, ptr %b, i64 1, !dbg !22 + store i32 1, ptr %arrayidx, align 4, !dbg !24 + br label %if.end, !dbg !25 + +if.else: ; preds = %entry + %arrayidx1 = getelementptr inbounds i32, ptr %b, i64 1, !dbg !26 + store i32 1, ptr %arrayidx1, align 4, !dbg !28 + br label %if.end + +if.end: ; preds = %if.else, %if.then + ret void, !dbg !29 +} + +declare void @llvm.dbg.declare(metadata, metadata, metadata) + +declare void @llvm.dbg.value(metadata, metadata, metadata) + +!llvm.dbg.cu = !{!0} +!llvm.module.flags = !{!2, !3, !4, !5, !6, !7, !8} + +!0 = distinct !DICompileUnit(language: DW_LANG_C11, file: !1, producer: "clang version 19.0.0", isOptimized: false, runtimeVersion: 0, emissionKind: FullDebug, splitDebugInlining: false, nameTableKind: None) +!1 = !DIFile(filename: "main.c", directory: "/root/llvm-test/GVNHoist") +!2 = !{i32 7, !"Dwarf Version", i32 5} +!3 = !{i32 2, !"Debug Info Version", i32 3} +!4 = !{i32 1, !"wchar_size", i32 4} +!5 = !{i32 8, !"PIC Level", i32 2} +!6 = !{i32 7, !"PIE Level", i32 2} +!7 = !{i32 7, !"uwtable", i32 2} +!8 = !{i32 7, !"frame-pointer", i32 2} +!10 = distinct !DISubprogram(name: "func", scope: !1, file: !1, line: 1, type: !11, scopeLine: 1, flags: DIFlagPrototyped, spFlags: DISPFlagDefinition, unit: !0, retainedNodes: !15) +!11 = !DISubroutineType(types: !12) +!12 = !{null, !13, !14} +!13 = !DIBasicType(name: "int", size: 32, encoding: DW_ATE_signed) +!14 = !DIDerivedType(tag: DW_TAG_pointer_type, baseType: !13, size: 64) +!15 = !{} +!16 = !DILocalVariable(name: "a", arg: 1, scope: !10, file: !1, line: 1, type: !13) +!17 = !DILocation(line: 0, scope: !10) +!18 = !DILocalVariable(name: "b", arg: 2, scope: !10, file: !1, line: 1, type: !14) +!19 = !DILocation(line: 2, column: 9, scope: !20) +!20 = distinct !DILexicalBlock(scope: !10, file: !1, line: 2, column: 9) +!21 = !DILocation(line: 2, column: 9, scope: !10) +!22 = !DILocation(line: 3, column: 9, scope: !23) +!23 = distinct !DILexicalBlock(scope: !20, file: !1, line: 2, column: 12) +!24 = !DILocation(line: 3, column: 14, scope: !23) +!25 = !DILocation(line: 4, column: 5, scope: !23) +!26 = !DILocation(line: 5, column: 9, scope: !27) +!27 = distinct !DILexicalBlock(scope: !20, file: !1, line: 4, column: 12) +!28 = !DILocation(line: 5, column: 14, scope: !27) +!29 = !DILocation(line: 7, column: 1, scope: !10) -- GitLab From 36b4b9d988ff1e82758fd5a462120086d21989e7 Mon Sep 17 00:00:00 2001 From: Freddy Ye Date: Thu, 28 Mar 2024 18:54:32 +0800 Subject: [PATCH 038/788] [X86] Support immediate folding for CCMP/CTEST (#86616) E.g. %0:gr32 = MOV32ri 81 CTEST32rr %0, %1, 2, 10, implicit-def $eflags, implicit $eflags => CTEST32ri %1, 81, 2, 10, implicit-def $eflags, implicit $eflags --- llvm/lib/Target/X86/X86InstrInfo.cpp | 9 ++- llvm/test/CodeGen/X86/apx/foldimmediate.mir | 70 +++++++++++++++++++++ 2 files changed, 77 insertions(+), 2 deletions(-) create mode 100644 llvm/test/CodeGen/X86/apx/foldimmediate.mir diff --git a/llvm/lib/Target/X86/X86InstrInfo.cpp b/llvm/lib/Target/X86/X86InstrInfo.cpp index eb42a4b2119d..f24334312c11 100644 --- a/llvm/lib/Target/X86/X86InstrInfo.cpp +++ b/llvm/lib/Target/X86/X86InstrInfo.cpp @@ -5595,9 +5595,13 @@ static unsigned convertALUrr2ALUri(unsigned Opc) { case X86::FROM: \ return X86::TO; FROM_TO(TEST64rr, TEST64ri32) + FROM_TO(CTEST64rr, CTEST64ri32) FROM_TO(CMP64rr, CMP64ri32) + FROM_TO(CCMP64rr, CCMP64ri32) FROM_TO(TEST32rr, TEST32ri) + FROM_TO(CTEST32rr, CTEST32ri) FROM_TO(CMP32rr, CMP32ri) + FROM_TO(CCMP32rr, CCMP32ri) #undef FROM_TO } } @@ -5697,7 +5701,8 @@ bool X86InstrInfo::foldImmediateImpl(MachineInstr &UseMI, MachineInstr *DefMI, UseMI.findRegisterUseOperandIdx(Reg) != 2) return false; // For CMP instructions the immediate can only be at index 1. - if ((NewOpc == X86::CMP64ri32 || NewOpc == X86::CMP32ri) && + if (((NewOpc == X86::CMP64ri32 || NewOpc == X86::CMP32ri) || + (NewOpc == X86::CCMP64ri32 || NewOpc == X86::CCMP32ri)) && UseMI.findRegisterUseOperandIdx(Reg) != 1) return false; @@ -5742,7 +5747,7 @@ bool X86InstrInfo::foldImmediateImpl(MachineInstr &UseMI, MachineInstr *DefMI, unsigned Op1 = 1, Op2 = CommuteAnyOperandIndex; unsigned ImmOpNum = 2; if (!UseMI.getOperand(0).isDef()) { - Op1 = 0; // TEST, CMP + Op1 = 0; // TEST, CMP, CTEST, CCMP ImmOpNum = 1; } if (Opc == TargetOpcode::COPY) diff --git a/llvm/test/CodeGen/X86/apx/foldimmediate.mir b/llvm/test/CodeGen/X86/apx/foldimmediate.mir new file mode 100644 index 000000000000..310fc64841f7 --- /dev/null +++ b/llvm/test/CodeGen/X86/apx/foldimmediate.mir @@ -0,0 +1,70 @@ +# NOTE: Assertions have been autogenerated by utils/update_mir_test_checks.py UTC_ARGS: --version 3 +# RUN: llc -mtriple=x86_64-- -run-pass=peephole-opt %s -o - | FileCheck %s +--- | + define void @foldImmediate() { ret void } +... +--- +# Check that immediates can be folded into ALU instructions. +name: foldImmediate +registers: + - { id: 0, class: gr32 } + - { id: 1, class: gr32 } + - { id: 2, class: gr32 } + - { id: 3, class: gr32 } + - { id: 4, class: gr32 } + - { id: 5, class: gr32 } + - { id: 6, class: gr32 } + - { id: 7, class: gr64 } + - { id: 8, class: gr64 } + - { id: 9, class: gr64 } + - { id: 10, class: gr64 } + - { id: 11, class: gr64 } + - { id: 12, class: gr64 } + - { id: 13, class: gr64 } + - { id: 14, class: gr64 } + - { id: 15, class: gr64 } + - { id: 16, class: gr32 } + - { id: 17, class: gr64 } + - { id: 18, class: gr32 } + +body: | + bb.0: + liveins: $rdi, $rsi + + ; CHECK-LABEL: name: foldImmediate + ; CHECK: liveins: $rdi, $rsi + ; CHECK-NEXT: {{ $}} + ; CHECK-NEXT: [[MOV32ri:%[0-9]+]]:gr32 = MOV32ri 81 + ; CHECK-NEXT: [[COPY:%[0-9]+]]:gr32 = COPY $edi + ; CHECK-NEXT: CTEST32ri [[COPY]], 81, 2, 10, implicit-def $eflags, implicit $eflags + ; CHECK-NEXT: NOOP implicit $eflags + ; CHECK-NEXT: CCMP32ri [[COPY]], 81, 2, 10, implicit-def $eflags, implicit $eflags + ; CHECK-NEXT: NOOP implicit $eflags + ; CHECK-NEXT: [[SUBREG_TO_REG:%[0-9]+]]:gr64 = SUBREG_TO_REG 0, killed [[MOV32ri]], %subreg.sub_32bit + ; CHECK-NEXT: [[COPY1:%[0-9]+]]:gr64 = COPY $rsi + ; CHECK-NEXT: CTEST64ri32 [[COPY1]], 81, 2, 10, implicit-def $eflags, implicit $eflags + ; CHECK-NEXT: NOOP implicit $eflags + ; CHECK-NEXT: CCMP64ri32 [[COPY1]], 81, 2, 10, implicit-def $eflags, implicit $eflags + ; CHECK-NEXT: NOOP implicit $eflags + ; CHECK-NEXT: CCMP64rr [[SUBREG_TO_REG]], [[COPY1]], 2, 10, implicit-def $eflags, implicit $eflags + ; CHECK-NEXT: NOOP implicit $eflags + %0 = MOV32ri 81 + %1 = COPY $edi + + CTEST32rr %0, %1, 2, 10, implicit-def $eflags, implicit $eflags + NOOP implicit $eflags + + CCMP32rr %1, %0, 2, 10, implicit-def $eflags, implicit $eflags + NOOP implicit $eflags + + %7 = SUBREG_TO_REG 0, killed %0:gr32, %subreg.sub_32bit + %8 = COPY $rsi + + CTEST64rr %8, %7, 2, 10, implicit-def $eflags, implicit $eflags + NOOP implicit $eflags + + CCMP64rr %8, %7, 2, 10, implicit-def $eflags, implicit $eflags + NOOP implicit $eflags + CCMP64rr %7, %8, 2, 10, implicit-def $eflags, implicit $eflags + NOOP implicit $eflags +... -- GitLab From 28b196e7fc4919a062ed20177d113cd0ae9b1f75 Mon Sep 17 00:00:00 2001 From: Dmitri Gribenko Date: Thu, 28 Mar 2024 10:41:02 +0100 Subject: [PATCH 039/788] [llvm] Write temporary test files into %t ... instead of the source tree --- lld/test/ELF/lto/libcall-archive.ll | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/lld/test/ELF/lto/libcall-archive.ll b/lld/test/ELF/lto/libcall-archive.ll index 84ddc1f55587..0f3d9c37d729 100644 --- a/lld/test/ELF/lto/libcall-archive.ll +++ b/lld/test/ELF/lto/libcall-archive.ll @@ -4,8 +4,8 @@ ; RUN: llvm-as -o %t2.o %S/Inputs/libcall-archive.ll ; RUN: llvm-mc -filetype=obj -triple=x86_64-unknown-linux -o %t3.o %S/Inputs/libcall-archive.s ; RUN: llvm-ar rcs %t.a %t2.o %t3.o -; RUN: ld.lld --why-extract=why.txt -o %t %t.o %t.a -; RUN: FileCheck %s --input-file=why.txt --check-prefix=CHECK-WHY +; RUN: ld.lld --why-extract=%t.why.txt -o %t %t.o %t.a +; RUN: FileCheck %s --input-file=%t.why.txt --check-prefix=CHECK-WHY ; RUN: llvm-nm %t | FileCheck %s ; RUN: ld.lld -o %t2 %t.o --start-lib %t2.o %t3.o --end-lib ; RUN: llvm-nm %t2 | FileCheck %s -- GitLab From b999e631c03640f7d1d93b5319da496ed4e0df55 Mon Sep 17 00:00:00 2001 From: Ulrich Weigand Date: Thu, 28 Mar 2024 12:15:39 +0100 Subject: [PATCH 040/788] [OpenMP] Fix node destruction race in __kmpc_omp_taskwait_deps_51 (#86130) The __kmpc_omp_taskwait_deps_51 allocates a kmp_depnode_t node on its stack, and there is currently a race condition where another thread might still be accessing that node after the function has returned and its stack frame was released. While the function does wait until the node's npredecessors count has reached zero before exiting, there is still a window where the function that last decremented the npredecessors count assumes the node is still accessible. For heap-allocated kmp_depnode_t nodes, this normally works via a separate ndeps count that only reaches zero at the point where no accesses to the node are expected at all; in fact, at this point the heap allocation will be freed. For this case of a stack-allocated kmp_depnode_t node, it therefore makes sense to similarly respect the ndeps count; we need to wait until this reaches 1 (not 0, because it is not heap-allocated so there's always one extra count to prevent it from being freed), before we can safely deallocate our stack frame. As this is expected to be a short race window of only a few instructions, it should be fine to just use a busy wait loop checking the ndeps count. Fixes: https://github.com/llvm/llvm-project/issues/85963 --- openmp/runtime/src/kmp_taskdeps.cpp | 6 ++++++ 1 file changed, 6 insertions(+) diff --git a/openmp/runtime/src/kmp_taskdeps.cpp b/openmp/runtime/src/kmp_taskdeps.cpp index f7529481393f..e575ad8b08a5 100644 --- a/openmp/runtime/src/kmp_taskdeps.cpp +++ b/openmp/runtime/src/kmp_taskdeps.cpp @@ -1030,6 +1030,12 @@ void __kmpc_omp_taskwait_deps_51(ident_t *loc_ref, kmp_int32 gtid, __kmp_task_stealing_constraint); } + // Wait until the last __kmp_release_deps is finished before we free the + // current stack frame holding the "node" variable; once its nrefs count + // reaches 1, we're sure nobody else can try to reference it again. + while (node.dn.nrefs > 1) + KMP_YIELD(TRUE); + #if OMPT_SUPPORT __ompt_taskwait_dep_finish(current_task, taskwait_task_data); #endif /* OMPT_SUPPORT */ -- GitLab From c13556c0b0aaeb9794d3e2864c8dd9880661f909 Mon Sep 17 00:00:00 2001 From: Matt Arsenault Date: Thu, 28 Mar 2024 14:27:14 +0300 Subject: [PATCH 041/788] AMDGPU: Document more backend recognized attributes (#80239) --- llvm/docs/AMDGPUUsage.rst | 36 ++++++++++++++++++++++++++++++++++++ 1 file changed, 36 insertions(+) diff --git a/llvm/docs/AMDGPUUsage.rst b/llvm/docs/AMDGPUUsage.rst index 6e6d6b157148..22c1d1f186ea 100644 --- a/llvm/docs/AMDGPUUsage.rst +++ b/llvm/docs/AMDGPUUsage.rst @@ -1449,6 +1449,42 @@ The AMDGPU backend supports the following LLVM IR attributes. the frame. This is an internal detail of how LDS variables are lowered, language front ends should not set this attribute. + "amdgpu-gds-size" Bytes expected to be allocated at the start of GDS memory at entry. + + "amdgpu-git-ptr-high" The hard-wired high half of the address of the global information table + for AMDPAL OS type. 0xffffffff represents no hard-wired high half, since + current hardware only allows a 16 bit value. + + "amdgpu-32bit-address-high-bits" Assumed high 32-bits for 32-bit address spaces which are really truncated + 64-bit addresses (i.e., addrspace(6)) + + "amdgpu-color-export" Indicates shader exports color information if set to 1. + Defaults to 1 for :ref:`amdgpu_ps `, and 0 for other calling + conventions. Determines the necessity and type of null exports when a shader + terminates early by killing lanes. + + "amdgpu-depth-export" Indicates shader exports depth information if set to 1. Determines the + necessity and type of null exports when a shader terminates early by killing + lanes. A depth-only shader will export to depth channel when no null export + target is available (GFX11+). + + "InitialPSInputAddr" Set the initial value of the `spi_ps_input_addr` register for + :ref:`amdgpu_ps ` shaders. Any bits enabled by this value will + be enabled in the final register value. + + "amdgpu-wave-priority-threshold" VALU instruction count threshold for adjusting wave priority. If exceeded, + temporarily raise the wave priority at the start of the shader function + until its last VMEM instructions to allow younger waves to issue their VMEM + instructions as well. + + "amdgpu-memory-bound" Set internally by backend + + "amdgpu-wave-limiter" Set internally by backend + + "amdgpu-unroll-threshold" Set base cost threshold preference for loop unrolling within this function, + default is 300. Actual threshold may be varied by per-loop metadata or + reduced by heuristics. + "amdgpu-max-num-workgroups"="x,y,z" Specify the maximum number of work groups for the kernel dispatch in the X, Y, and Z dimensions. Generated by the ``amdgpu_max_num_work_groups`` CLANG attribute [CLANG-ATTR]_. Clang only emits this attribute when all -- GitLab From c9db031c48852af491747dab86ef6f19195eb20d Mon Sep 17 00:00:00 2001 From: Andrew Ng Date: Thu, 28 Mar 2024 11:41:49 +0000 Subject: [PATCH 042/788] [Support] Fix color handling in formatted_raw_ostream (#86700) The color methods in formatted_raw_ostream were forwarding directly to the underlying stream without considering existing buffered output. This would cause incorrect colored output for buffered uses of formatted_raw_ostream. Fix this issue by applying the color to the formatted_raw_ostream itself and temporarily disabling scanning of any color related output so as not to affect the position tracking. This fix means that workarounds that forced formatted_raw_ostream buffering to be disabled can be removed. In the case of llvm-objdump, this can improve disassembly performance when redirecting to a file by more than an order of magnitude on both Windows and Linux. This improvement restores the disassembly performance when redirecting to a file to a level similar to before color support was added. --- llvm/include/llvm/Support/FormattedStream.h | 51 ++++++++++++++++++--- llvm/lib/Support/FormattedStream.cpp | 3 ++ llvm/tools/llvm-mc/llvm-mc.cpp | 5 -- llvm/tools/llvm-objdump/llvm-objdump.cpp | 7 --- 4 files changed, 47 insertions(+), 19 deletions(-) diff --git a/llvm/include/llvm/Support/FormattedStream.h b/llvm/include/llvm/Support/FormattedStream.h index 5f937cfa7984..850a18dbb941 100644 --- a/llvm/include/llvm/Support/FormattedStream.h +++ b/llvm/include/llvm/Support/FormattedStream.h @@ -52,6 +52,10 @@ class formatted_raw_ostream : public raw_ostream { /// have the rest of it. SmallString<4> PartialUTF8Char; + /// DisableScan - Temporarily disable scanning of output. Used to ignore color + /// codes. + bool DisableScan; + void write_impl(const char *Ptr, size_t Size) override; /// current_pos - Return the current position within the stream, @@ -89,9 +93,33 @@ class formatted_raw_ostream : public raw_ostream { SetUnbuffered(); TheStream->SetUnbuffered(); + enable_colors(TheStream->colors_enabled()); + Scanned = nullptr; } + void PreDisableScan() { + assert(!DisableScan); + ComputePosition(getBufferStart(), GetNumBytesInBuffer()); + assert(PartialUTF8Char.empty()); + DisableScan = true; + } + + void PostDisableScan() { + assert(DisableScan); + DisableScan = false; + Scanned = getBufferStart() + GetNumBytesInBuffer(); + } + + struct DisableScanScope { + formatted_raw_ostream *S; + + DisableScanScope(formatted_raw_ostream *FRO) : S(FRO) { + S->PreDisableScan(); + } + ~DisableScanScope() { S->PostDisableScan(); } + }; + public: /// formatted_raw_ostream - Open the specified file for /// writing. If an error occurs, information about the error is @@ -104,12 +132,12 @@ public: /// underneath it. /// formatted_raw_ostream(raw_ostream &Stream) - : TheStream(nullptr), Position(0, 0) { + : TheStream(nullptr), Position(0, 0), DisableScan(false) { setStream(Stream); } - explicit formatted_raw_ostream() : TheStream(nullptr), Position(0, 0) { - Scanned = nullptr; - } + explicit formatted_raw_ostream() + : TheStream(nullptr), Position(0, 0), Scanned(nullptr), + DisableScan(false) {} ~formatted_raw_ostream() override { flush(); @@ -136,17 +164,26 @@ public: } raw_ostream &resetColor() override { - TheStream->resetColor(); + if (colors_enabled()) { + DisableScanScope S(this); + raw_ostream::resetColor(); + } return *this; } raw_ostream &reverseColor() override { - TheStream->reverseColor(); + if (colors_enabled()) { + DisableScanScope S(this); + raw_ostream::reverseColor(); + } return *this; } raw_ostream &changeColor(enum Colors Color, bool Bold, bool BG) override { - TheStream->changeColor(Color, Bold, BG); + if (colors_enabled()) { + DisableScanScope S(this); + raw_ostream::changeColor(Color, Bold, BG); + } return *this; } diff --git a/llvm/lib/Support/FormattedStream.cpp b/llvm/lib/Support/FormattedStream.cpp index c0d284350995..c50530e76efc 100644 --- a/llvm/lib/Support/FormattedStream.cpp +++ b/llvm/lib/Support/FormattedStream.cpp @@ -94,6 +94,9 @@ void formatted_raw_ostream::UpdatePosition(const char *Ptr, size_t Size) { /// ComputePosition - Examine the current output and update line and column /// counts. void formatted_raw_ostream::ComputePosition(const char *Ptr, size_t Size) { + if (DisableScan) + return; + // If our previous scan pointer is inside the buffer, assume we already // scanned those bytes. This depends on raw_ostream to not change our buffer // in unexpected ways. diff --git a/llvm/tools/llvm-mc/llvm-mc.cpp b/llvm/tools/llvm-mc/llvm-mc.cpp index 8eb53e440459..807071a7b9a1 100644 --- a/llvm/tools/llvm-mc/llvm-mc.cpp +++ b/llvm/tools/llvm-mc/llvm-mc.cpp @@ -541,11 +541,6 @@ int main(int argc, char **argv) { std::unique_ptr MAB( TheTarget->createMCAsmBackend(*STI, *MRI, MCOptions)); auto FOut = std::make_unique(*OS); - // FIXME: Workaround for bug in formatted_raw_ostream. Color escape codes - // are (incorrectly) written directly to the unbuffered raw_ostream wrapped - // by the formatted_raw_ostream. - if (Action == AC_CDisassemble) - FOut->SetUnbuffered(); Str.reset( TheTarget->createAsmStreamer(Ctx, std::move(FOut), /*asmverbose*/ true, /*useDwarfDirectory*/ true, IP, diff --git a/llvm/tools/llvm-objdump/llvm-objdump.cpp b/llvm/tools/llvm-objdump/llvm-objdump.cpp index 78cf67b1e630..9b65ea5a99e4 100644 --- a/llvm/tools/llvm-objdump/llvm-objdump.cpp +++ b/llvm/tools/llvm-objdump/llvm-objdump.cpp @@ -2115,13 +2115,6 @@ disassembleObject(ObjectFile &Obj, const ObjectFile &DbgObj, formatted_raw_ostream FOS(outs()); - // FIXME: Workaround for bug in formatted_raw_ostream. Color escape codes - // are (incorrectly) written directly to the unbuffered raw_ostream - // wrapped by the formatted_raw_ostream. - if (DisassemblyColor == ColorOutput::Enable || - DisassemblyColor == ColorOutput::Auto) - FOS.SetUnbuffered(); - std::unordered_map AllLabels; std::unordered_map> BBAddrMapLabels; if (SymbolizeOperands) { -- GitLab From a495cfbf7d544ed2624e8a54f14129fa7824eee4 Mon Sep 17 00:00:00 2001 From: Marc Auberer Date: Thu, 28 Mar 2024 12:42:02 +0100 Subject: [PATCH 043/788] [IR][NFC] Cleanup CmpInst signatures / code docs (#86441) Change param names to recommended upper case format for static methods in CmpInst for consistency Implement suggestion from @dtcxzyw. cc @dtcxzyw @tschuett --- llvm/include/llvm/IR/InstrTypes.h | 14 +++++++------- 1 file changed, 7 insertions(+), 7 deletions(-) diff --git a/llvm/include/llvm/IR/InstrTypes.h b/llvm/include/llvm/IR/InstrTypes.h index 3a30e935849b..e4e5fa15c399 100644 --- a/llvm/include/llvm/IR/InstrTypes.h +++ b/llvm/include/llvm/IR/InstrTypes.h @@ -1032,7 +1032,7 @@ public: /// the two operands. Insert the instruction into a BasicBlock right before /// the specified instruction. /// Create a CmpInst - static CmpInst *Create(OtherOps Op, Predicate predicate, Value *S1, Value *S2, + static CmpInst *Create(OtherOps Op, Predicate Pred, Value *S1, Value *S2, const Twine &Name, BasicBlock::iterator InsertBefore); /// Construct a compare instruction, given the opcode, the predicate and @@ -1040,23 +1040,23 @@ public: /// instruction into a BasicBlock right before the specified instruction. /// The specified Instruction is allowed to be a dereferenced end iterator. /// Create a CmpInst - static CmpInst *Create(OtherOps Op, - Predicate predicate, Value *S1, - Value *S2, const Twine &Name = "", + static CmpInst *Create(OtherOps Op, Predicate Pred, Value *S1, Value *S2, + const Twine &Name = "", Instruction *InsertBefore = nullptr); /// Construct a compare instruction, given the opcode, the predicate and the /// two operands. Also automatically insert this instruction to the end of /// the BasicBlock specified. /// Create a CmpInst - static CmpInst *Create(OtherOps Op, Predicate predicate, Value *S1, - Value *S2, const Twine &Name, BasicBlock *InsertAtEnd); + static CmpInst *Create(OtherOps Op, Predicate Pred, Value *S1, Value *S2, + const Twine &Name, BasicBlock *InsertAtEnd); /// Construct a compare instruction, given the opcode, the predicate, /// the two operands and the instruction to copy the flags from. Optionally /// (if InstBefore is specified) insert the instruction into a BasicBlock /// right before the specified instruction. The specified Instruction is - /// allowed to be a dereferenced end iterator. Create a CmpInst + /// allowed to be a dereferenced end iterator. + /// Create a CmpInst static CmpInst *CreateWithCopiedFlags(OtherOps Op, Predicate Pred, Value *S1, Value *S2, const Instruction *FlagsSource, -- GitLab From 9d61f7ea660bc4087763e679a7f2b87c50cca108 Mon Sep 17 00:00:00 2001 From: Marc Auberer Date: Thu, 28 Mar 2024 12:42:44 +0100 Subject: [PATCH 044/788] [flang] Remove duplicate call to va_end() (#86865) Fixes #86825 --- flang/runtime/io-error.cpp | 3 --- 1 file changed, 3 deletions(-) diff --git a/flang/runtime/io-error.cpp b/flang/runtime/io-error.cpp index 02f237f05bea..b006b82f6224 100644 --- a/flang/runtime/io-error.cpp +++ b/flang/runtime/io-error.cpp @@ -56,9 +56,6 @@ void IoErrorHandler::SignalError(int iostatOrErrno, const char *msg, ...) { #endif ioMsg_ = SaveDefaultCharacter( buffer, Fortran::runtime::strlen(buffer) + 1, *this); -#if !defined(RT_DEVICE_COMPILATION) - va_end(ap); -#endif } } return; -- GitLab From daa755ba7b7fe11e078f1e6f43d446234023f859 Mon Sep 17 00:00:00 2001 From: Joseph Huber Date: Thu, 28 Mar 2024 06:49:15 -0500 Subject: [PATCH 045/788] [libc] Disable testing for NVPTX debug builds (#86856) Summary: Debug builds don't optimize out certain parts of the code that end up making the GPU backend crash. This results in regular builds not being successful just to build the testing objects. Disable them for now in debug mode. --- libc/cmake/modules/prepare_libc_gpu_build.cmake | 5 +++++ 1 file changed, 5 insertions(+) diff --git a/libc/cmake/modules/prepare_libc_gpu_build.cmake b/libc/cmake/modules/prepare_libc_gpu_build.cmake index bea6bb016491..20aca16990fc 100644 --- a/libc/cmake/modules/prepare_libc_gpu_build.cmake +++ b/libc/cmake/modules/prepare_libc_gpu_build.cmake @@ -93,6 +93,11 @@ else() endif() set(LIBC_GPU_TARGET_ARCHITECTURE "${gpu_test_architecture}") +# The NVPTX backend cannot currently handle objects created in debug mode. +if(LIBC_TARGET_ARCHITECTURE_IS_NVPTX AND CMAKE_BUILD_TYPE STREQUAL "Debug") + set(LIBC_GPU_TESTS_DISABLED TRUE) +endif() + # Identify the GPU loader utility used to run tests. set(LIBC_GPU_LOADER_EXECUTABLE "" CACHE STRING "Executable for the GPU loader.") if(LIBC_GPU_LOADER_EXECUTABLE) -- GitLab From 896037c75ace929327e5b0bf5832157f9d81e6e7 Mon Sep 17 00:00:00 2001 From: Haohai Wen Date: Thu, 28 Mar 2024 20:07:15 +0800 Subject: [PATCH 046/788] [LoopRotate] Set loop back edge weight to not less than exit weight (#86496) Branch weight from sample-based PGO may be not inaccurate due to sampling. If the loop body must be executed, then origin loop back edge weight must be not less than exit weight. --- llvm/lib/Transforms/Utils/LoopRotationUtils.cpp | 10 ++++++++++ .../Transforms/LoopRotate/update-branch-weights.ll | 4 ++-- 2 files changed, 12 insertions(+), 2 deletions(-) diff --git a/llvm/lib/Transforms/Utils/LoopRotationUtils.cpp b/llvm/lib/Transforms/Utils/LoopRotationUtils.cpp index bc6711711371..0f55af3b6edd 100644 --- a/llvm/lib/Transforms/Utils/LoopRotationUtils.cpp +++ b/llvm/lib/Transforms/Utils/LoopRotationUtils.cpp @@ -347,9 +347,19 @@ static void updateBranchWeights(BranchInst &PreHeaderBI, BranchInst &LoopBI, // probabilities as if there are only 0-trip and 1-trip cases. ExitWeight0 = OrigLoopExitWeight - OrigLoopBackedgeWeight; } + } else { + // Theoretically, if the loop body must be executed at least once, the + // backedge count must be not less than exit count. However the branch + // weight collected by sampling-based PGO may be not very accurate due to + // sampling. Therefore this workaround is required here to avoid underflow + // of unsigned in following update of branch weight. + if (OrigLoopExitWeight > OrigLoopBackedgeWeight) + OrigLoopBackedgeWeight = OrigLoopExitWeight; } + assert(OrigLoopExitWeight >= ExitWeight0 && "Bad branch weight"); ExitWeight1 = OrigLoopExitWeight - ExitWeight0; EnterWeight = ExitWeight1; + assert(OrigLoopBackedgeWeight >= EnterWeight && "Bad branch weight"); LoopBackWeight = OrigLoopBackedgeWeight - EnterWeight; } else if (OrigLoopExitWeight == 0) { if (OrigLoopBackedgeWeight == 0) { diff --git a/llvm/test/Transforms/LoopRotate/update-branch-weights.ll b/llvm/test/Transforms/LoopRotate/update-branch-weights.ll index acb2038d17bb..9a1f36ec5ff2 100644 --- a/llvm/test/Transforms/LoopRotate/update-branch-weights.ll +++ b/llvm/test/Transforms/LoopRotate/update-branch-weights.ll @@ -240,7 +240,7 @@ loop_exit: ; BFI_AFTER-LABEL: block-frequency-info: func6_inaccurate_branch_weight ; BFI_AFTER: - entry: {{.*}} count = 1024 -; BFI_AFTER: - loop_body: {{.*}} count = 4294967296 +; BFI_AFTER: - loop_body: {{.*}} count = 1024 ; BFI_AFTER: - loop_exit: {{.*}} count = 1024 ; IR-LABEL: define void @func6_inaccurate_branch_weight( @@ -292,4 +292,4 @@ loop_exit: ; IR: [[PROF_FUNC3_0]] = !{!"branch_weights", i32 0, i32 1} ; IR: [[PROF_FUNC4_0]] = !{!"branch_weights", i32 1, i32 0} ; IR: [[PROF_FUNC5_0]] = !{!"branch_weights", i32 0, i32 0} -; IR: [[PROF_FUNC6_0]] = !{!"branch_weights", i32 -1, i32 1024} +; IR: [[PROF_FUNC6_0]] = !{!"branch_weights", i32 0, i32 1024} -- GitLab From fb8cccf88c5d04f36148ff336b6dc7c25746b1de Mon Sep 17 00:00:00 2001 From: Haojian Wu Date: Thu, 28 Mar 2024 13:07:58 +0100 Subject: [PATCH 047/788] [AST] Print the "aggregate" for aggregate deduction guide decl. (#84018) I found this is useful for debugging purpose to identify different kind of deduction guide decl. --- clang/include/clang/AST/TextNodeDumper.h | 1 + clang/lib/AST/TextNodeDumper.cpp | 13 +++++++++++++ clang/test/SemaTemplate/deduction-guide.cpp | 9 +++++++++ 3 files changed, 23 insertions(+) diff --git a/clang/include/clang/AST/TextNodeDumper.h b/clang/include/clang/AST/TextNodeDumper.h index de67f0b57148..efb5bfe7f83d 100644 --- a/clang/include/clang/AST/TextNodeDumper.h +++ b/clang/include/clang/AST/TextNodeDumper.h @@ -352,6 +352,7 @@ public: void VisitEnumConstantDecl(const EnumConstantDecl *D); void VisitIndirectFieldDecl(const IndirectFieldDecl *D); void VisitFunctionDecl(const FunctionDecl *D); + void VisitCXXDeductionGuideDecl(const CXXDeductionGuideDecl *D); void VisitFieldDecl(const FieldDecl *D); void VisitVarDecl(const VarDecl *D); void VisitBindingDecl(const BindingDecl *D); diff --git a/clang/lib/AST/TextNodeDumper.cpp b/clang/lib/AST/TextNodeDumper.cpp index b683eb1edd8f..413e452146bd 100644 --- a/clang/lib/AST/TextNodeDumper.cpp +++ b/clang/lib/AST/TextNodeDumper.cpp @@ -1990,6 +1990,19 @@ void TextNodeDumper::VisitFunctionDecl(const FunctionDecl *D) { } } +void TextNodeDumper::VisitCXXDeductionGuideDecl( + const CXXDeductionGuideDecl *D) { + VisitFunctionDecl(D); + switch (D->getDeductionCandidateKind()) { + case DeductionCandidate::Normal: + case DeductionCandidate::Copy: + return; + case DeductionCandidate::Aggregate: + OS << " aggregate "; + break; + } +} + void TextNodeDumper::VisitLifetimeExtendedTemporaryDecl( const LifetimeExtendedTemporaryDecl *D) { OS << " extended by "; diff --git a/clang/test/SemaTemplate/deduction-guide.cpp b/clang/test/SemaTemplate/deduction-guide.cpp index 16c7083df29d..0caef78fedbf 100644 --- a/clang/test/SemaTemplate/deduction-guide.cpp +++ b/clang/test/SemaTemplate/deduction-guide.cpp @@ -239,3 +239,12 @@ F s(0); // CHECK: |-InjectedClassNameType {{.*}} 'F<>' dependent // CHECK: | `-CXXRecord {{.*}} 'F' // CHECK: `-TemplateTypeParmType {{.*}} 'type-parameter-0-1' dependent depth 0 index 1 + +template +struct G { T t; }; + +G g = {1}; +// CHECK-LABEL: Dumping : +// CHECK: FunctionTemplateDecl +// CHECK: |-CXXDeductionGuideDecl {{.*}} implicit 'auto (T) -> G' aggregate +// CHECK: `-CXXDeductionGuideDecl {{.*}} implicit used 'auto (int) -> G' implicit_instantiation aggregate -- GitLab From a042fcbe45d1ae64acc5d818db90e26e16e1aab3 Mon Sep 17 00:00:00 2001 From: Haojian Wu Date: Thu, 28 Mar 2024 13:10:02 +0100 Subject: [PATCH 048/788] [clang] Bailout when the substitution of template parameter mapping is invalid. (#86869) Fixes #86757 We missed to handle the invalid case when substituting into the parameter mapping of an constraint during normalization. The constructor of `InstantiatingTemplate` will bail out (no `CodeSynthesisContext` will be added to the instantiation stack) if there was a fatal error, consequently we should stop doing any further template instantiations. --- clang/docs/ReleaseNotes.rst | 1 + clang/lib/Sema/SemaConcept.cpp | 2 ++ clang/test/SemaTemplate/concepts-GH86757.cpp | 13 +++++++++++++ 3 files changed, 16 insertions(+) create mode 100644 clang/test/SemaTemplate/concepts-GH86757.cpp diff --git a/clang/docs/ReleaseNotes.rst b/clang/docs/ReleaseNotes.rst index ccc399d36dbb..232de0d7d8bb 100644 --- a/clang/docs/ReleaseNotes.rst +++ b/clang/docs/ReleaseNotes.rst @@ -458,6 +458,7 @@ Bug Fixes to C++ Support - Fix an issue where a namespace alias could be defined using a qualified name (all name components following the first `::` were ignored). - Fix an out-of-bounds crash when checking the validity of template partial specializations. (part of #GH86757). +- Fix an issue caused by not handling invalid cases when substituting into the parameter mapping of a constraint. Fixes (#GH86757). Bug Fixes to AST Handling ^^^^^^^^^^^^^^^^^^^^^^^^^ diff --git a/clang/lib/Sema/SemaConcept.cpp b/clang/lib/Sema/SemaConcept.cpp index b6c4d3d540ef..a2d8ba9a96d7 100644 --- a/clang/lib/Sema/SemaConcept.cpp +++ b/clang/lib/Sema/SemaConcept.cpp @@ -1281,6 +1281,8 @@ substituteParameterMappings(Sema &S, NormalizedConstraint &N, S, InstLocBegin, Sema::InstantiatingTemplate::ParameterMappingSubstitution{}, Concept, {InstLocBegin, InstLocEnd}); + if (Inst.isInvalid()) + return true; if (S.SubstTemplateArguments(*Atomic.ParameterMapping, MLTAL, SubstArgs)) return true; diff --git a/clang/test/SemaTemplate/concepts-GH86757.cpp b/clang/test/SemaTemplate/concepts-GH86757.cpp new file mode 100644 index 000000000000..3122381b2035 --- /dev/null +++ b/clang/test/SemaTemplate/concepts-GH86757.cpp @@ -0,0 +1,13 @@ +// RUN: %clang_cc1 -std=c++20 -Wfatal-errors -verify %s + +template int a; +template concept c = a; +template concept e = c<>; + +// must be a fatal error to trigger the crash +undefined; // expected-error {{a type specifier is required for all declarations}} + +template concept g = e; +template struct h +template +struct h; -- GitLab From 4ddd4ed7fe15a356dace649e18492dd01071f475 Mon Sep 17 00:00:00 2001 From: Zaara Syeda Date: Thu, 28 Mar 2024 08:37:25 -0400 Subject: [PATCH 049/788] [AIX][TOC] -mtocdata/-mno-tocdata fix non deterministic iteration order (#86840) Failure with testcase toc-conf.c observed when building with LLVM_REVERSE_ITERATION=ON. Changing from using llvm::StringSet to std::set to ensure iteration order is deterministic. Note: the functionality of the feature does not require a specific iteration order, however, this will allow testing to be consistent. From llvm docs: The advantages of std::set are that its iterators are stable (deleting or inserting an element from the set does not affect iterators or pointers to other elements) and that iteration over the set is guaranteed to be in sorted order. --- clang/lib/Driver/ToolChains/AIX.cpp | 6 +++--- clang/test/Driver/toc-conf.c | 2 +- 2 files changed, 4 insertions(+), 4 deletions(-) diff --git a/clang/lib/Driver/ToolChains/AIX.cpp b/clang/lib/Driver/ToolChains/AIX.cpp index 6e089903a315..7a62b0f9aec4 100644 --- a/clang/lib/Driver/ToolChains/AIX.cpp +++ b/clang/lib/Driver/ToolChains/AIX.cpp @@ -471,7 +471,7 @@ static void addTocDataOptions(const llvm::opt::ArgList &Args, // the global setting of tocdata in TOCDataGloballyinEffect. // Those that have the opposite setting to TOCDataGloballyinEffect, are added // to ExplicitlySpecifiedGlobals. - llvm::StringSet<> ExplicitlySpecifiedGlobals; + std::set ExplicitlySpecifiedGlobals; for (const auto Arg : Args.filtered(options::OPT_mtocdata_EQ, options::OPT_mno_tocdata_EQ)) { TOCDataSetting ArgTocDataSetting = @@ -486,7 +486,7 @@ static void addTocDataOptions(const llvm::opt::ArgList &Args, ExplicitlySpecifiedGlobals.erase(Val); } - auto buildExceptionList = [](const llvm::StringSet<> &ExplicitValues, + auto buildExceptionList = [](const std::set &ExplicitValues, const char *OptionSpelling) { std::string Option(OptionSpelling); bool IsFirst = true; @@ -495,7 +495,7 @@ static void addTocDataOptions(const llvm::opt::ArgList &Args, Option += ","; IsFirst = false; - Option += E.first(); + Option += E.str(); } return Option; }; diff --git a/clang/test/Driver/toc-conf.c b/clang/test/Driver/toc-conf.c index 80d92ee1a90b..7b2d5122ebc6 100644 --- a/clang/test/Driver/toc-conf.c +++ b/clang/test/Driver/toc-conf.c @@ -23,7 +23,7 @@ void func() { // CHECK-CONF1-NOT: warning: // CHECK-CONF1: "-cc1"{{.*}}" "-mno-tocdata" -// CHECK-CONF1: "-mtocdata=g2,g1" +// CHECK-CONF1: "-mtocdata=g1,g2" // CHECK-CONF2-NOT: warning: // CHECK-CONF2: "-cc1"{{.*}}" "-mtocdata" -- GitLab From 79199753fd6c39aac881b9556614c5db2775dc85 Mon Sep 17 00:00:00 2001 From: Krzysztof Parzyszek Date: Thu, 28 Mar 2024 07:46:01 -0500 Subject: [PATCH 050/788] [flang][OpenMP] Make several function local to OpenMP.cpp, NFC (#86726) There were several functions, mostly reduction-related, that were only called from OpenMP.cpp. Remove them from OpenMP.h, and make them local in OpenMP.cpp: - genOpenMPReduction - findReductionChain - getConvertFromReductionOp - updateReduction - removeStoreOp Also, move the function bodies out of the "public" section. --- flang/include/flang/Lower/OpenMP.h | 12 - flang/lib/Lower/OpenMP/OpenMP.cpp | 417 ++++++++++++++--------------- 2 files changed, 207 insertions(+), 222 deletions(-) diff --git a/flang/include/flang/Lower/OpenMP.h b/flang/include/flang/Lower/OpenMP.h index 3b22a652d1fc..6e150ef4e8e8 100644 --- a/flang/include/flang/Lower/OpenMP.h +++ b/flang/include/flang/Lower/OpenMP.h @@ -19,7 +19,6 @@ #include namespace mlir { -class Value; class Operation; class Location; namespace omp { @@ -30,7 +29,6 @@ enum class DeclareTargetCaptureClause : uint32_t; namespace fir { class FirOpBuilder; -class ConvertOp; } // namespace fir namespace Fortran { @@ -84,16 +82,6 @@ void genOpenMPSymbolProperties(AbstractConverter &converter, int64_t getCollapseValue(const Fortran::parser::OmpClauseList &clauseList); void genThreadprivateOp(AbstractConverter &, const pft::Variable &); void genDeclareTargetIntGlobal(AbstractConverter &, const pft::Variable &); -void genOpenMPReduction(AbstractConverter &, - Fortran::semantics::SemanticsContext &, - const Fortran::parser::OmpClauseList &clauseList); - -mlir::Operation *findReductionChain(mlir::Value, mlir::Value * = nullptr); -fir::ConvertOp getConvertFromReductionOp(mlir::Operation *, mlir::Value); -void updateReduction(mlir::Operation *, fir::FirOpBuilder &, mlir::Value, - mlir::Value, fir::ConvertOp * = nullptr); -void removeStoreOp(mlir::Operation *, mlir::Value); - bool isOpenMPTargetConstruct(const parser::OpenMPConstruct &); bool isOpenMPDeviceDeclareTarget(Fortran::lower::AbstractConverter &, Fortran::semantics::SemanticsContext &, diff --git a/flang/lib/Lower/OpenMP/OpenMP.cpp b/flang/lib/Lower/OpenMP/OpenMP.cpp index 5defffd738b4..340921c86724 100644 --- a/flang/lib/Lower/OpenMP/OpenMP.cpp +++ b/flang/lib/Lower/OpenMP/OpenMP.cpp @@ -237,6 +237,213 @@ createAndSetPrivatizedLoopVar(Fortran::lower::AbstractConverter &converter, return storeOp; } +static mlir::Operation * +findReductionChain(mlir::Value loadVal, mlir::Value *reductionVal = nullptr) { + for (mlir::OpOperand &loadOperand : loadVal.getUses()) { + if (mlir::Operation *reductionOp = loadOperand.getOwner()) { + if (auto convertOp = mlir::dyn_cast(reductionOp)) { + for (mlir::OpOperand &convertOperand : convertOp.getRes().getUses()) { + if (mlir::Operation *reductionOp = convertOperand.getOwner()) + return reductionOp; + } + } + for (mlir::OpOperand &reductionOperand : reductionOp->getUses()) { + if (auto store = + mlir::dyn_cast(reductionOperand.getOwner())) { + if (store.getMemref() == *reductionVal) { + store.erase(); + return reductionOp; + } + } + if (auto assign = + mlir::dyn_cast(reductionOperand.getOwner())) { + if (assign.getLhs() == *reductionVal) { + assign.erase(); + return reductionOp; + } + } + } + } + } + return nullptr; +} + +// for a logical operator 'op' reduction X = X op Y +// This function returns the operation responsible for converting Y from +// fir.logical<4> to i1 +static fir::ConvertOp getConvertFromReductionOp(mlir::Operation *reductionOp, + mlir::Value loadVal) { + for (mlir::Value reductionOperand : reductionOp->getOperands()) { + if (auto convertOp = + mlir::dyn_cast(reductionOperand.getDefiningOp())) { + if (convertOp.getOperand() == loadVal) + continue; + return convertOp; + } + } + return nullptr; +} + +static void updateReduction(mlir::Operation *op, + fir::FirOpBuilder &firOpBuilder, + mlir::Value loadVal, mlir::Value reductionVal, + fir::ConvertOp *convertOp = nullptr) { + mlir::OpBuilder::InsertPoint insertPtDel = firOpBuilder.saveInsertionPoint(); + firOpBuilder.setInsertionPoint(op); + + mlir::Value reductionOp; + if (convertOp) + reductionOp = convertOp->getOperand(); + else if (op->getOperand(0) == loadVal) + reductionOp = op->getOperand(1); + else + reductionOp = op->getOperand(0); + + firOpBuilder.create(op->getLoc(), reductionOp, + reductionVal); + firOpBuilder.restoreInsertionPoint(insertPtDel); +} + +static void removeStoreOp(mlir::Operation *reductionOp, mlir::Value symVal) { + for (mlir::Operation *reductionOpUse : reductionOp->getUsers()) { + if (auto convertReduction = + mlir::dyn_cast(reductionOpUse)) { + for (mlir::Operation *convertReductionUse : + convertReduction.getRes().getUsers()) { + if (auto storeOp = mlir::dyn_cast(convertReductionUse)) { + if (storeOp.getMemref() == symVal) + storeOp.erase(); + } + if (auto assignOp = + mlir::dyn_cast(convertReductionUse)) { + if (assignOp.getLhs() == symVal) + assignOp.erase(); + } + } + } + } +} + +// Generate an OpenMP reduction operation. +// TODO: Currently assumes it is either an integer addition/multiplication +// reduction, or a logical and reduction. Generalize this for various reduction +// operation types. +// TODO: Generate the reduction operation during lowering instead of creating +// and removing operations since this is not a robust approach. Also, removing +// ops in the builder (instead of a rewriter) is probably not the best approach. +static void +genOpenMPReduction(Fortran::lower::AbstractConverter &converter, + Fortran::semantics::SemanticsContext &semaCtx, + const Fortran::parser::OmpClauseList &clauseList) { + fir::FirOpBuilder &firOpBuilder = converter.getFirOpBuilder(); + + List clauses{makeClauses(clauseList, semaCtx)}; + + for (const Clause &clause : clauses) { + if (const auto &reductionClause = + std::get_if(&clause.u)) { + const auto &redOperatorList{ + std::get( + reductionClause->t)}; + assert(redOperatorList.size() == 1 && "Expecting single operator"); + const auto &redOperator = redOperatorList.front(); + const auto &objects{std::get(reductionClause->t)}; + if (const auto *reductionOp = + std::get_if(&redOperator.u)) { + const auto &intrinsicOp{ + std::get( + reductionOp->u)}; + + switch (intrinsicOp) { + case clause::DefinedOperator::IntrinsicOperator::Add: + case clause::DefinedOperator::IntrinsicOperator::Multiply: + case clause::DefinedOperator::IntrinsicOperator::AND: + case clause::DefinedOperator::IntrinsicOperator::EQV: + case clause::DefinedOperator::IntrinsicOperator::OR: + case clause::DefinedOperator::IntrinsicOperator::NEQV: + break; + default: + continue; + } + for (const Object &object : objects) { + if (const Fortran::semantics::Symbol *symbol = object.id()) { + mlir::Value reductionVal = converter.getSymbolAddress(*symbol); + if (auto declOp = reductionVal.getDefiningOp()) + reductionVal = declOp.getBase(); + mlir::Type reductionType = + reductionVal.getType().cast().getEleTy(); + if (!reductionType.isa()) { + if (!reductionType.isIntOrIndexOrFloat()) + continue; + } + for (mlir::OpOperand &reductionValUse : reductionVal.getUses()) { + if (auto loadOp = + mlir::dyn_cast(reductionValUse.getOwner())) { + mlir::Value loadVal = loadOp.getRes(); + if (reductionType.isa()) { + mlir::Operation *reductionOp = findReductionChain(loadVal); + fir::ConvertOp convertOp = + getConvertFromReductionOp(reductionOp, loadVal); + updateReduction(reductionOp, firOpBuilder, loadVal, + reductionVal, &convertOp); + removeStoreOp(reductionOp, reductionVal); + } else if (mlir::Operation *reductionOp = + findReductionChain(loadVal, &reductionVal)) { + updateReduction(reductionOp, firOpBuilder, loadVal, + reductionVal); + } + } + } + } + } + } else if (const auto *reductionIntrinsic = + std::get_if(&redOperator.u)) { + if (!ReductionProcessor::supportedIntrinsicProcReduction( + *reductionIntrinsic)) + continue; + ReductionProcessor::ReductionIdentifier redId = + ReductionProcessor::getReductionType(*reductionIntrinsic); + for (const Object &object : objects) { + if (const Fortran::semantics::Symbol *symbol = object.id()) { + mlir::Value reductionVal = converter.getSymbolAddress(*symbol); + if (auto declOp = reductionVal.getDefiningOp()) + reductionVal = declOp.getBase(); + for (const mlir::OpOperand &reductionValUse : + reductionVal.getUses()) { + if (auto loadOp = + mlir::dyn_cast(reductionValUse.getOwner())) { + mlir::Value loadVal = loadOp.getRes(); + // Max is lowered as a compare -> select. + // Match the pattern here. + mlir::Operation *reductionOp = + findReductionChain(loadVal, &reductionVal); + if (reductionOp == nullptr) + continue; + + if (redId == ReductionProcessor::ReductionIdentifier::MAX || + redId == ReductionProcessor::ReductionIdentifier::MIN) { + assert(mlir::isa(reductionOp) && + "Selection Op not found in reduction intrinsic"); + mlir::Operation *compareOp = + getCompareFromReductionOp(reductionOp, loadVal); + updateReduction(compareOp, firOpBuilder, loadVal, + reductionVal); + } + if (redId == ReductionProcessor::ReductionIdentifier::IOR || + redId == ReductionProcessor::ReductionIdentifier::IEOR || + redId == ReductionProcessor::ReductionIdentifier::IAND) { + updateReduction(reductionOp, firOpBuilder, loadVal, + reductionVal); + } + } + } + } + } + } + } + } +} + struct OpWithBodyGenInfo { /// A type for a code-gen callback function. This takes as argument the op for /// which the code is being generated and returns the arguments of the op's @@ -2339,216 +2546,6 @@ void Fortran::lower::genDeclareTargetIntGlobal( } } -// Generate an OpenMP reduction operation. -// TODO: Currently assumes it is either an integer addition/multiplication -// reduction, or a logical and reduction. Generalize this for various reduction -// operation types. -// TODO: Generate the reduction operation during lowering instead of creating -// and removing operations since this is not a robust approach. Also, removing -// ops in the builder (instead of a rewriter) is probably not the best approach. -void Fortran::lower::genOpenMPReduction( - Fortran::lower::AbstractConverter &converter, - Fortran::semantics::SemanticsContext &semaCtx, - const Fortran::parser::OmpClauseList &clauseList) { - fir::FirOpBuilder &firOpBuilder = converter.getFirOpBuilder(); - - List clauses{makeClauses(clauseList, semaCtx)}; - - for (const Clause &clause : clauses) { - if (const auto &reductionClause = - std::get_if(&clause.u)) { - const auto &redOperatorList{ - std::get( - reductionClause->t)}; - assert(redOperatorList.size() == 1 && "Expecting single operator"); - const auto &redOperator = redOperatorList.front(); - const auto &objects{std::get(reductionClause->t)}; - if (const auto *reductionOp = - std::get_if(&redOperator.u)) { - const auto &intrinsicOp{ - std::get( - reductionOp->u)}; - - switch (intrinsicOp) { - case clause::DefinedOperator::IntrinsicOperator::Add: - case clause::DefinedOperator::IntrinsicOperator::Multiply: - case clause::DefinedOperator::IntrinsicOperator::AND: - case clause::DefinedOperator::IntrinsicOperator::EQV: - case clause::DefinedOperator::IntrinsicOperator::OR: - case clause::DefinedOperator::IntrinsicOperator::NEQV: - break; - default: - continue; - } - for (const Object &object : objects) { - if (const Fortran::semantics::Symbol *symbol = object.id()) { - mlir::Value reductionVal = converter.getSymbolAddress(*symbol); - if (auto declOp = reductionVal.getDefiningOp()) - reductionVal = declOp.getBase(); - mlir::Type reductionType = - reductionVal.getType().cast().getEleTy(); - if (!reductionType.isa()) { - if (!reductionType.isIntOrIndexOrFloat()) - continue; - } - for (mlir::OpOperand &reductionValUse : reductionVal.getUses()) { - if (auto loadOp = - mlir::dyn_cast(reductionValUse.getOwner())) { - mlir::Value loadVal = loadOp.getRes(); - if (reductionType.isa()) { - mlir::Operation *reductionOp = findReductionChain(loadVal); - fir::ConvertOp convertOp = - getConvertFromReductionOp(reductionOp, loadVal); - updateReduction(reductionOp, firOpBuilder, loadVal, - reductionVal, &convertOp); - removeStoreOp(reductionOp, reductionVal); - } else if (mlir::Operation *reductionOp = - findReductionChain(loadVal, &reductionVal)) { - updateReduction(reductionOp, firOpBuilder, loadVal, - reductionVal); - } - } - } - } - } - } else if (const auto *reductionIntrinsic = - std::get_if(&redOperator.u)) { - if (!ReductionProcessor::supportedIntrinsicProcReduction( - *reductionIntrinsic)) - continue; - ReductionProcessor::ReductionIdentifier redId = - ReductionProcessor::getReductionType(*reductionIntrinsic); - for (const Object &object : objects) { - if (const Fortran::semantics::Symbol *symbol = object.id()) { - mlir::Value reductionVal = converter.getSymbolAddress(*symbol); - if (auto declOp = reductionVal.getDefiningOp()) - reductionVal = declOp.getBase(); - for (const mlir::OpOperand &reductionValUse : - reductionVal.getUses()) { - if (auto loadOp = - mlir::dyn_cast(reductionValUse.getOwner())) { - mlir::Value loadVal = loadOp.getRes(); - // Max is lowered as a compare -> select. - // Match the pattern here. - mlir::Operation *reductionOp = - findReductionChain(loadVal, &reductionVal); - if (reductionOp == nullptr) - continue; - - if (redId == ReductionProcessor::ReductionIdentifier::MAX || - redId == ReductionProcessor::ReductionIdentifier::MIN) { - assert(mlir::isa(reductionOp) && - "Selection Op not found in reduction intrinsic"); - mlir::Operation *compareOp = - getCompareFromReductionOp(reductionOp, loadVal); - updateReduction(compareOp, firOpBuilder, loadVal, - reductionVal); - } - if (redId == ReductionProcessor::ReductionIdentifier::IOR || - redId == ReductionProcessor::ReductionIdentifier::IEOR || - redId == ReductionProcessor::ReductionIdentifier::IAND) { - updateReduction(reductionOp, firOpBuilder, loadVal, - reductionVal); - } - } - } - } - } - } - } - } -} - -mlir::Operation *Fortran::lower::findReductionChain(mlir::Value loadVal, - mlir::Value *reductionVal) { - for (mlir::OpOperand &loadOperand : loadVal.getUses()) { - if (mlir::Operation *reductionOp = loadOperand.getOwner()) { - if (auto convertOp = mlir::dyn_cast(reductionOp)) { - for (mlir::OpOperand &convertOperand : convertOp.getRes().getUses()) { - if (mlir::Operation *reductionOp = convertOperand.getOwner()) - return reductionOp; - } - } - for (mlir::OpOperand &reductionOperand : reductionOp->getUses()) { - if (auto store = - mlir::dyn_cast(reductionOperand.getOwner())) { - if (store.getMemref() == *reductionVal) { - store.erase(); - return reductionOp; - } - } - if (auto assign = - mlir::dyn_cast(reductionOperand.getOwner())) { - if (assign.getLhs() == *reductionVal) { - assign.erase(); - return reductionOp; - } - } - } - } - } - return nullptr; -} - -// for a logical operator 'op' reduction X = X op Y -// This function returns the operation responsible for converting Y from -// fir.logical<4> to i1 -fir::ConvertOp -Fortran::lower::getConvertFromReductionOp(mlir::Operation *reductionOp, - mlir::Value loadVal) { - for (mlir::Value reductionOperand : reductionOp->getOperands()) { - if (auto convertOp = - mlir::dyn_cast(reductionOperand.getDefiningOp())) { - if (convertOp.getOperand() == loadVal) - continue; - return convertOp; - } - } - return nullptr; -} - -void Fortran::lower::updateReduction(mlir::Operation *op, - fir::FirOpBuilder &firOpBuilder, - mlir::Value loadVal, - mlir::Value reductionVal, - fir::ConvertOp *convertOp) { - mlir::OpBuilder::InsertPoint insertPtDel = firOpBuilder.saveInsertionPoint(); - firOpBuilder.setInsertionPoint(op); - - mlir::Value reductionOp; - if (convertOp) - reductionOp = convertOp->getOperand(); - else if (op->getOperand(0) == loadVal) - reductionOp = op->getOperand(1); - else - reductionOp = op->getOperand(0); - - firOpBuilder.create(op->getLoc(), reductionOp, - reductionVal); - firOpBuilder.restoreInsertionPoint(insertPtDel); -} - -void Fortran::lower::removeStoreOp(mlir::Operation *reductionOp, - mlir::Value symVal) { - for (mlir::Operation *reductionOpUse : reductionOp->getUsers()) { - if (auto convertReduction = - mlir::dyn_cast(reductionOpUse)) { - for (mlir::Operation *convertReductionUse : - convertReduction.getRes().getUsers()) { - if (auto storeOp = mlir::dyn_cast(convertReductionUse)) { - if (storeOp.getMemref() == symVal) - storeOp.erase(); - } - if (auto assignOp = - mlir::dyn_cast(convertReductionUse)) { - if (assignOp.getLhs() == symVal) - assignOp.erase(); - } - } - } - } -} - bool Fortran::lower::isOpenMPTargetConstruct( const Fortran::parser::OpenMPConstruct &omp) { llvm::omp::Directive dir = llvm::omp::Directive::OMPD_unknown; -- GitLab From 56a10a3c7930164a875db7c34da8c2a8b8abfbee Mon Sep 17 00:00:00 2001 From: VitaNuo <115406782+VitaNuo@users.noreply.github.com> Date: Thu, 28 Mar 2024 13:48:09 +0100 Subject: [PATCH 051/788] =?UTF-8?q?[clangd][trace]=20Fix=20comment=20to=20?= =?UTF-8?q?mention=20that=20trace=20spans=20are=20measured=20=E2=80=A6=20(?= =?UTF-8?q?#86938)?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit …in milliseconds rather than seconds. --- clang-tools-extra/clangd/support/Trace.h | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/clang-tools-extra/clangd/support/Trace.h b/clang-tools-extra/clangd/support/Trace.h index 1bfc75b874d8..36c3745a41e9 100644 --- a/clang-tools-extra/clangd/support/Trace.h +++ b/clang-tools-extra/clangd/support/Trace.h @@ -143,8 +143,8 @@ bool enabled(); class Span { public: Span(llvm::Twine Name); - /// Records span's duration in seconds to \p LatencyMetric with \p Name as the - /// label. + /// Records span's duration in milliseconds to \p LatencyMetric with \p Name + /// as the label. Span(llvm::Twine Name, const Metric &LatencyMetric); ~Span(); -- GitLab From e8e80d07c867cadcfd82741693a04b2913904956 Mon Sep 17 00:00:00 2001 From: Krzysztof Parzyszek Date: Thu, 28 Mar 2024 07:52:47 -0500 Subject: [PATCH 052/788] [OpenMP] Apply post-commit review comments in PR86289, NFC (#86828) Fix include guard name, fix typo, add comments with OpenMP spec sections. --- flang/lib/Lower/OpenMP/Clauses.cpp | 2 +- llvm/include/llvm/Frontend/OpenMP/ClauseT.h | 151 +++++++++++++++++++- 2 files changed, 149 insertions(+), 4 deletions(-) diff --git a/flang/lib/Lower/OpenMP/Clauses.cpp b/flang/lib/Lower/OpenMP/Clauses.cpp index 853dcd78e266..40da71c8b55f 100644 --- a/flang/lib/Lower/OpenMP/Clauses.cpp +++ b/flang/lib/Lower/OpenMP/Clauses.cpp @@ -325,7 +325,7 @@ ReductionOperator makeReductionOperator(const parser::OmpReductionOperator &inp, // Absent: missing-in-parser // AcqRel: empty // Acquire: empty -// AdjustArgs: incomplate +// AdjustArgs: incomplete Affinity make(const parser::OmpClause::Affinity &inp, semantics::SemanticsContext &semaCtx) { diff --git a/llvm/include/llvm/Frontend/OpenMP/ClauseT.h b/llvm/include/llvm/Frontend/OpenMP/ClauseT.h index c48b9169c60e..6ce972adcf0f 100644 --- a/llvm/include/llvm/Frontend/OpenMP/ClauseT.h +++ b/llvm/include/llvm/Frontend/OpenMP/ClauseT.h @@ -5,8 +5,41 @@ // SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception // //===----------------------------------------------------------------------===// -#ifndef FORTRAN_LOWER_OPENMP_CLAUSET_H -#define FORTRAN_LOWER_OPENMP_CLAUSET_H +// This file contains template classes that represent OpenMP clauses, as +// described in the OpenMP API specification. +// +// The general structure of any specific clause class is that it is either +// empty, or it consists of a single data member, which can take one of these +// three forms: +// - a value member, named `v`, or +// - a tuple of values, named `t`, or +// - a variant (i.e. union) of values, named `u`. +// To assist with generic visit algorithms, classes define one of the following +// traits: +// - EmptyTrait: the class has no data members. +// - WrapperTrait: the class has a single member `v` +// - TupleTrait: the class has a tuple member `t` +// - UnionTrait the class has a varuant member `u` +// - IncompleteTrait: the class is a placeholder class that is currently empty, +// but will be completed at a later time. +// Note: This structure follows the one used in flang parser. +// +// The types used in the class definitions follow the names used in the spec +// (there are a few exceptions to this). For example, given +// Clause `foo` +// - foo-modifier : description... +// - list : list of variables +// the corresponding class would be +// template <...> +// struct FooT { +// using FooModifier = type that can represent the modifier +// using List = ListT>; +// using TupleTrait = std::true_type; +// std::tuple, List> t; +// }; +//===----------------------------------------------------------------------===// +#ifndef LLVM_FRONTEND_OPENMP_CLAUSET_H +#define LLVM_FRONTEND_OPENMP_CLAUSET_H #include "llvm/ADT/ArrayRef.h" #include "llvm/ADT/DenseMap.h" @@ -161,6 +194,7 @@ struct DefinedOperatorT { std::variant u; }; +// V5.2: [3.2.6] `iterator` modifier template // struct RangeT { // range-specification: begin : end[: step] @@ -168,6 +202,7 @@ struct RangeT { std::tuple t; }; +// V5.2: [3.2.6] `iterator` modifier template // struct IteratorSpecifierT { // iterators-specifier: [ iterator-type ] identifier = range-specification @@ -183,6 +218,7 @@ struct IteratorSpecifierT { // is allowed. If the mapper list contains a single element, it applies to // all objects in the clause, otherwise there should be as many mappers as // there are objects. +// V5.2: [5.8.2] Mapper identifiers and `mapper` modifiers template // struct MapperT { using MapperIdentifier = ObjectT; @@ -190,8 +226,11 @@ struct MapperT { MapperIdentifier v; }; +// V5.2: [15.8.1] `memory-order` clauses +// When used as arguments for other clauses, e.g. `fail`. ENUM(MemoryOrder, AcqRel, Acquire, Relaxed, Release, SeqCst); ENUM(MotionExpectation, Present); +// V5.2: [15.9.1] `task-dependence-type` modifier ENUM(TaskDependenceType, In, Out, Inout, Mutexinoutset, Inoutset, Depobj); template // @@ -246,6 +285,7 @@ ListT makeList(ContainerTy &&container, FunctionTy &&func) { } namespace clause { +// V5.2: [8.3.1] `assumption` clauses template // struct AbsentT { using List = ListT; @@ -253,21 +293,25 @@ struct AbsentT { List v; }; +// V5.2: [15.8.1] `memory-order` clauses template // struct AcqRelT { using EmptyTrait = std::true_type; }; +// V5.2: [15.8.1] `memory-order` clauses template // struct AcquireT { using EmptyTrait = std::true_type; }; +// V5.2: [7.5.2] `adjust_args` clause template // struct AdjustArgsT { using IncompleteTrait = std::true_type; }; +// V5.2: [12.5.1] `affinity` clause template // struct AffinityT { using Iterator = type::IteratorT; @@ -277,6 +321,7 @@ struct AffinityT { std::tuple t; }; +// V5.2: [6.3] `align` clause template // struct AlignT { using Alignment = E; @@ -285,6 +330,7 @@ struct AlignT { Alignment v; }; +// V5.2: [5.11] `aligned` clause template // struct AlignedT { using Alignment = E; @@ -297,6 +343,7 @@ struct AlignedT { template // struct AllocatorT; +// V5.2: [6.6] `allocate` clause template // struct AllocateT { using AllocatorSimpleModifier = E; @@ -310,6 +357,7 @@ struct AllocateT { t; }; +// V5.2: [6.4] `allocator` clause template // struct AllocatorT { using Allocator = E; @@ -317,11 +365,13 @@ struct AllocatorT { Allocator v; }; +// V5.2: [7.5.3] `append_args` clause template // struct AppendArgsT { using IncompleteTrait = std::true_type; }; +// V5.2: [8.1] `at` clause template // struct AtT { ENUM(ActionTime, Compilation, Execution); @@ -329,6 +379,7 @@ struct AtT { ActionTime v; }; +// V5.2: [8.2.1] `requirement` clauses template // struct AtomicDefaultMemOrderT { using MemoryOrder = type::MemoryOrder; @@ -336,6 +387,7 @@ struct AtomicDefaultMemOrderT { MemoryOrder v; // Name not provided in spec }; +// V5.2: [11.7.1] `bind` clause template // struct BindT { ENUM(Binding, Teams, Parallel, Thread); @@ -343,11 +395,13 @@ struct BindT { Binding v; }; +// V5.2: [15.8.3] `extended-atomic` clauses template // struct CaptureT { using EmptyTrait = std::true_type; }; +// V5.2: [4.4.3] `collapse` clause template // struct CollapseT { using N = E; @@ -355,11 +409,13 @@ struct CollapseT { N v; }; +// V5.2: [15.8.3] `extended-atomic` clauses template // struct CompareT { using EmptyTrait = std::true_type; }; +// V5.2: [8.3.1] `assumption` clauses template // struct ContainsT { using List = ListT; @@ -367,6 +423,7 @@ struct ContainsT { List v; }; +// V5.2: [5.7.1] `copyin` clause template // struct CopyinT { using List = ObjectListT; @@ -374,6 +431,7 @@ struct CopyinT { List v; }; +// V5.2: [5.7.2] `copyprivate` clause template // struct CopyprivateT { using List = ObjectListT; @@ -381,6 +439,7 @@ struct CopyprivateT { List v; }; +// V5.2: [5.4.1] `default` clause template // struct DefaultT { ENUM(DataSharingAttribute, Firstprivate, None, Private, Shared); @@ -388,6 +447,7 @@ struct DefaultT { DataSharingAttribute v; }; +// V5.2: [5.8.7] `defaultmap` clause template // struct DefaultmapT { ENUM(ImplicitBehavior, Alloc, To, From, Tofrom, Firstprivate, None, Default, @@ -400,6 +460,7 @@ struct DefaultmapT { template // struct DoacrossT; +// V5.2: [15.9.5] `depend` clause template // struct DependT { using Iterator = type::IteratorT; @@ -417,6 +478,7 @@ struct DependT { std::variant u; // Doacross form is legacy }; +// V5.2: [3.5] `destroy` clause template // struct DestroyT { using DestroyVar = ObjectT; @@ -425,6 +487,7 @@ struct DestroyT { OPT(DestroyVar) v; }; +// V5.2: [12.5.2] `detach` clause template // struct DetachT { using EventHandle = ObjectT; @@ -432,6 +495,7 @@ struct DetachT { EventHandle v; }; +// V5.2: [13.2] `device` clause template // struct DeviceT { using DeviceDescription = E; @@ -440,6 +504,7 @@ struct DeviceT { std::tuple t; }; +// V5.2: [13.1] `device_type` clause template // struct DeviceTypeT { ENUM(DeviceTypeDescription, Any, Host, Nohost); @@ -447,6 +512,7 @@ struct DeviceTypeT { DeviceTypeDescription v; }; +// V5.2: [11.6.1] `dist_schedule` clause template // struct DistScheduleT { ENUM(Kind, Static); @@ -455,6 +521,7 @@ struct DistScheduleT { std::tuple t; }; +// V5.2: [15.9.6] `doacross` clause template // struct DoacrossT { using Vector = ListT>; @@ -464,11 +531,13 @@ struct DoacrossT { std::tuple t; }; +// V5.2: [8.2.1] `requirement` clauses template // struct DynamicAllocatorsT { using EmptyTrait = std::true_type; }; +// V5.2: [5.8.4] `enter` clause template // struct EnterT { using List = ObjectListT; @@ -476,6 +545,7 @@ struct EnterT { List v; }; +// V5.2: [5.6.2] `exclusive` clause template // struct ExclusiveT { using WrapperTrait = std::true_type; @@ -483,6 +553,7 @@ struct ExclusiveT { List v; }; +// V5.2: [15.8.3] `extended-atomic` clauses template // struct FailT { using MemoryOrder = type::MemoryOrder; @@ -490,6 +561,7 @@ struct FailT { MemoryOrder v; }; +// V5.2: [10.5.1] `filter` clause template // struct FilterT { using ThreadNum = E; @@ -497,6 +569,7 @@ struct FilterT { ThreadNum v; }; +// V5.2: [12.3] `final` clause template // struct FinalT { using Finalize = E; @@ -504,6 +577,7 @@ struct FinalT { Finalize v; }; +// V5.2: [5.4.4] `firstprivate` clause template // struct FirstprivateT { using List = ObjectListT; @@ -511,6 +585,7 @@ struct FirstprivateT { List v; }; +// V5.2: [5.9.2] `from` clause template // struct FromT { using LocatorList = ObjectListT; @@ -523,11 +598,13 @@ struct FromT { std::tuple t; }; +// V5.2: [9.2.1] `full` clause template // struct FullT { using EmptyTrait = std::true_type; }; +// V5.2: [12.6.1] `grainsize` clause template // struct GrainsizeT { ENUM(Prescriptiveness, Strict); @@ -536,6 +613,7 @@ struct GrainsizeT { std::tuple t; }; +// V5.2: [5.4.9] `has_device_addr` clause template // struct HasDeviceAddrT { using List = ObjectListT; @@ -543,6 +621,7 @@ struct HasDeviceAddrT { List v; }; +// V5.2: [15.1.2] `hint` clause template // struct HintT { using HintExpr = E; @@ -550,12 +629,14 @@ struct HintT { HintExpr v; }; +// V5.2: [8.3.1] Assumption clauses template // struct HoldsT { using WrapperTrait = std::true_type; E v; // No argument name in spec 5.2 }; +// V5.2: [3.4] `if` clause template // struct IfT { using DirectiveNameModifier = type::DirectiveName; @@ -564,11 +645,13 @@ struct IfT { std::tuple t; }; +// V5.2: [7.7.1] `branch` clauses template // struct InbranchT { using EmptyTrait = std::true_type; }; +// V5.2: [5.6.1] `exclusive` clause template // struct InclusiveT { using List = ObjectListT; @@ -576,6 +659,7 @@ struct InclusiveT { List v; }; +// V5.2: [7.8.3] `indirect` clause template // struct IndirectT { using InvokedByFptr = E; @@ -583,6 +667,7 @@ struct IndirectT { InvokedByFptr v; }; +// V5.2: [14.1.2] `init` clause template // struct InitT { using ForeignRuntimeId = E; @@ -595,6 +680,7 @@ struct InitT { std::tuple t; }; +// V5.2: [5.5.4] `initializer` clause template // struct InitializerT { using InitializerExpr = E; @@ -602,6 +688,7 @@ struct InitializerT { InitializerExpr v; }; +// V5.2: [5.5.10] `in_reduction` clause template // struct InReductionT { using List = ObjectListT; @@ -612,6 +699,7 @@ struct InReductionT { std::tuple t; }; +// V5.2: [5.4.7] `is_device_ptr` clause template // struct IsDevicePtrT { using List = ObjectListT; @@ -619,6 +707,7 @@ struct IsDevicePtrT { List v; }; +// V5.2: [5.4.5] `lastprivate` clause template // struct LastprivateT { using List = ObjectListT; @@ -627,6 +716,7 @@ struct LastprivateT { std::tuple t; }; +// V5.2: [5.4.6] `linear` clause template // struct LinearT { // std::get won't work here due to duplicate types in the tuple. @@ -642,6 +732,7 @@ struct LinearT { t; }; +// V5.2: [5.8.5] `link` clause template // struct LinkT { using List = ObjectListT; @@ -649,6 +740,7 @@ struct LinkT { List v; }; +// V5.2: [5.8.3] `map` clause template // struct MapT { using LocatorList = ObjectListT; @@ -665,16 +757,19 @@ struct MapT { t; }; +// V5.2: [7.5.1] `match` clause template // struct MatchT { using IncompleteTrait = std::true_type; }; +// V5.2: [12.2] `mergeable` clause template // struct MergeableT { using EmptyTrait = std::true_type; }; +// V5.2: [8.5.2] `message` clause template // struct MessageT { using MsgString = E; @@ -682,6 +777,7 @@ struct MessageT { MsgString v; }; +// V5.2: [7.6.2] `nocontext` clause template // struct NocontextT { using DoNotUpdateContext = E; @@ -689,11 +785,13 @@ struct NocontextT { DoNotUpdateContext v; }; +// V5.2: [15.7] `nowait` clause template // struct NogroupT { using EmptyTrait = std::true_type; }; +// V5.2: [10.4.1] `nontemporal` clause template // struct NontemporalT { using List = ObjectListT; @@ -701,26 +799,31 @@ struct NontemporalT { List v; }; +// V5.2: [8.3.1] `assumption` clauses template // struct NoOpenmpT { using EmptyTrait = std::true_type; }; +// V5.2: [8.3.1] `assumption` clauses template // struct NoOpenmpRoutinesT { using EmptyTrait = std::true_type; }; +// V5.2: [8.3.1] `assumption` clauses template // struct NoParallelismT { using EmptyTrait = std::true_type; }; +// V5.2: [7.7.1] `branch` clauses template // struct NotinbranchT { using EmptyTrait = std::true_type; }; +// V5.2: [7.6.1] `novariants` clause template // struct NovariantsT { using DoNotUseVariant = E; @@ -728,11 +831,13 @@ struct NovariantsT { DoNotUseVariant v; }; +// V5.2: [15.6] `nowait` clause template // struct NowaitT { using EmptyTrait = std::true_type; }; +// V5.2: [12.6.2] `num_tasks` clause template // struct NumTasksT { using NumTasks = E; @@ -741,6 +846,7 @@ struct NumTasksT { std::tuple t; }; +// V5.2: [10.2.1] `num_teams` clause template // struct NumTeamsT { using TupleTrait = std::true_type; @@ -749,6 +855,7 @@ struct NumTeamsT { std::tuple t; }; +// V5.2: [10.1.2] `num_threads` clause template // struct NumThreadsT { using Nthreads = E; @@ -772,6 +879,7 @@ struct OmpxDynCgroupMemT { E v; }; +// V5.2: [10.3] `order` clause template // struct OrderT { ENUM(OrderModifier, Reproducible, Unconstrained); @@ -780,6 +888,7 @@ struct OrderT { std::tuple t; }; +// V5.2: [4.4.4] `ordered` clause template // struct OrderedT { using N = E; @@ -787,11 +896,13 @@ struct OrderedT { OPT(N) v; }; +// V5.2: [7.4.2] `otherwise` clause template // struct OtherwiseT { using IncompleteTrait = std::true_type; }; +// V5.2: [9.2.2] `partial` clause template // struct PartialT { using UnrollFactor = E; @@ -799,6 +910,7 @@ struct PartialT { OPT(UnrollFactor) v; }; +// V5.2: [12.4] `priority` clause template // struct PriorityT { using PriorityValue = E; @@ -806,6 +918,7 @@ struct PriorityT { PriorityValue v; }; +// V5.2: [5.4.3] `private` clause template // struct PrivateT { using List = ObjectListT; @@ -813,6 +926,7 @@ struct PrivateT { List v; }; +// V5.2: [10.1.4] `proc_bind` clause template // struct ProcBindT { ENUM(AffinityPolicy, Close, Master, Spread, Primary); @@ -820,11 +934,13 @@ struct ProcBindT { AffinityPolicy v; }; +// V5.2: [15.8.2] Atomic clauses template // struct ReadT { using EmptyTrait = std::true_type; }; +// V5.2: [5.5.8] `reduction` clause template // struct ReductionT { using List = ObjectListT; @@ -836,21 +952,25 @@ struct ReductionT { std::tuple t; }; +// V5.2: [15.8.1] `memory-order` clauses template // struct RelaxedT { using EmptyTrait = std::true_type; }; +// V5.2: [15.8.1] `memory-order` clauses template // struct ReleaseT { using EmptyTrait = std::true_type; }; +// V5.2: [8.2.1] `requirement` clauses template // struct ReverseOffloadT { using EmptyTrait = std::true_type; }; +// V5.2: [10.4.2] `safelen` clause template // struct SafelenT { using Length = E; @@ -858,6 +978,7 @@ struct SafelenT { Length v; }; +// V5.2: [11.5.3] `schedule` clause template // struct ScheduleT { ENUM(Kind, Static, Dynamic, Guided, Auto, Runtime); @@ -868,11 +989,13 @@ struct ScheduleT { std::tuple t; }; +// V5.2: [15.8.1] Memory-order clauses template // struct SeqCstT { using EmptyTrait = std::true_type; }; +// V5.2: [8.5.1] `severity` clause template // struct SeverityT { ENUM(SevLevel, Fatal, Warning); @@ -880,6 +1003,7 @@ struct SeverityT { SevLevel v; }; +// V5.2: [5.4.2] `shared` clause template // struct SharedT { using List = ObjectListT; @@ -887,11 +1011,13 @@ struct SharedT { List v; }; +// V5.2: [15.10.3] `parallelization-level` clauses template // struct SimdT { using EmptyTrait = std::true_type; }; +// V5.2: [10.4.3] `simdlen` clause template // struct SimdlenT { using Length = E; @@ -899,6 +1025,7 @@ struct SimdlenT { Length v; }; +// V5.2: [9.1.1] `sizes` clause template // struct SizesT { using SizeList = ListT; @@ -906,6 +1033,7 @@ struct SizesT { SizeList v; }; +// V5.2: [5.5.9] `task_reduction` clause template // struct TaskReductionT { using List = ObjectListT; @@ -916,6 +1044,7 @@ struct TaskReductionT { std::tuple t; }; +// V5.2: [13.3] `thread_limit` clause template // struct ThreadLimitT { using Threadlim = E; @@ -923,11 +1052,13 @@ struct ThreadLimitT { Threadlim v; }; +// V5.2: [15.10.3] `parallelization-level` clauses template // struct ThreadsT { using EmptyTrait = std::true_type; }; +// V5.2: [5.9.1] `to` clause template // struct ToT { using LocatorList = ObjectListT; @@ -940,16 +1071,19 @@ struct ToT { std::tuple t; }; +// V5.2: [8.2.1] `requirement` clauses template // struct UnifiedAddressT { using EmptyTrait = std::true_type; }; +// V5.2: [8.2.1] `requirement` clauses template // struct UnifiedSharedMemoryT { using EmptyTrait = std::true_type; }; +// V5.2: [5.10] `uniform` clause template // struct UniformT { using ParameterList = ObjectListT; @@ -962,11 +1096,15 @@ struct UnknownT { using EmptyTrait = std::true_type; }; +// V5.2: [12.1] `untied` clause template // struct UntiedT { using EmptyTrait = std::true_type; }; +// Both of the following +// V5.2: [15.8.2] `atomic` clauses +// V5.2: [15.9.3] `update` clause template // struct UpdateT { using TaskDependenceType = tomp::type::TaskDependenceType; @@ -974,6 +1112,7 @@ struct UpdateT { OPT(TaskDependenceType) v; }; +// V5.2: [14.1.3] `use` clause template // struct UseT { using InteropVar = ObjectT; @@ -981,6 +1120,7 @@ struct UseT { InteropVar v; }; +// V5.2: [5.4.10] `use_device_addr` clause template // struct UseDeviceAddrT { using List = ObjectListT; @@ -988,6 +1128,7 @@ struct UseDeviceAddrT { List v; }; +// V5.2: [5.4.8] `use_device_ptr` clause template // struct UseDevicePtrT { using List = ObjectListT; @@ -995,6 +1136,7 @@ struct UseDevicePtrT { List v; }; +// V5.2: [6.8] `uses_allocators` clause template // struct UsesAllocatorsT { using MemSpace = E; @@ -1007,16 +1149,19 @@ struct UsesAllocatorsT { Allocators v; }; +// V5.2: [15.8.3] `extended-atomic` clauses template // struct WeakT { using EmptyTrait = std::true_type; }; +// V5.2: [7.4.1] `when` clause template // struct WhenT { using IncompleteTrait = std::true_type; }; +// V5.2: [15.8.2] Atomic clauses template // struct WriteT { using EmptyTrait = std::true_type; @@ -1120,4 +1265,4 @@ struct ClauseT { #undef OPT #undef ENUM -#endif // FORTRAN_LOWER_OPENMP_CLAUSET_H +#endif // LLVM_FRONTEND_OPENMP_CLAUSET_H -- GitLab From a2982a29fdfcfe2904754815c85f630a4dc6d88c Mon Sep 17 00:00:00 2001 From: Leandro Lupori Date: Thu, 28 Mar 2024 09:56:14 -0300 Subject: [PATCH 053/788] Revert "[compiler-rt] Allow building builtins.a without a libc (#86737)" This reverts commit 86692258637549ed9f863c3d2ba47b49f61bbc1f. Reverting due to buildbot failures. --- compiler-rt/cmake/config-ix.cmake | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/compiler-rt/cmake/config-ix.cmake b/compiler-rt/cmake/config-ix.cmake index 911f48fa1381..46a6fdf8728f 100644 --- a/compiler-rt/cmake/config-ix.cmake +++ b/compiler-rt/cmake/config-ix.cmake @@ -235,9 +235,9 @@ set(COMPILER_RT_SUPPORTED_ARCH) # Try to compile a very simple source file to ensure we can target the given # platform. We use the results of these tests to build only the various target # runtime libraries supported by our current compilers cross-compiling -# abilities. Avoids using libc as that may not be available yet. +# abilities. set(SIMPLE_SOURCE ${CMAKE_BINARY_DIR}${CMAKE_FILES_DIRECTORY}/simple.cc) -file(WRITE ${SIMPLE_SOURCE} "int main(void) { return 0; }\n") +file(WRITE ${SIMPLE_SOURCE} "#include \n#include \nint main(void) { printf(\"hello, world\"); }\n") # Detect whether the current target platform is 32-bit or 64-bit, and setup # the correct commandline flags needed to attempt to target 32-bit and 64-bit. -- GitLab From 96c8e2e88cc68416ddce4a9bf1a9221387b6d4b3 Mon Sep 17 00:00:00 2001 From: Egor Zhdan Date: Thu, 28 Mar 2024 12:59:57 +0000 Subject: [PATCH 054/788] [APINotes] For a re-exported module, look for APINotes in the re-exporting module's apinotes file This upstreams https://github.com/apple/llvm-project/pull/8063. If module FooCore is re-exported through module Foo (by using `export_as` in the modulemap), look for attributes of FooCore symbols in Foo.apinotes file. Swift bundles `std.apinotes` file that adds Swift-specific attributes to the C++ stdlib symbols. In recent versions of libc++, module std got split into multiple top-level modules, each of them is re-exported through std. This change allows us to keep using a single modulemap file for all supported C++ stdlibs. rdar://121680760 --- clang/lib/APINotes/APINotesManager.cpp | 5 +++++ clang/test/APINotes/Inputs/Headers/ExportAs.apinotes | 5 +++++ clang/test/APINotes/Inputs/Headers/ExportAs.h | 1 + clang/test/APINotes/Inputs/Headers/ExportAsCore.h | 1 + clang/test/APINotes/Inputs/Headers/module.modulemap | 10 ++++++++++ clang/test/APINotes/export-as.c | 8 ++++++++ 6 files changed, 30 insertions(+) create mode 100644 clang/test/APINotes/Inputs/Headers/ExportAs.apinotes create mode 100644 clang/test/APINotes/Inputs/Headers/ExportAs.h create mode 100644 clang/test/APINotes/Inputs/Headers/ExportAsCore.h create mode 100644 clang/test/APINotes/export-as.c diff --git a/clang/lib/APINotes/APINotesManager.cpp b/clang/lib/APINotes/APINotesManager.cpp index f60f09e2b3c2..789bb97d81de 100644 --- a/clang/lib/APINotes/APINotesManager.cpp +++ b/clang/lib/APINotes/APINotesManager.cpp @@ -221,6 +221,7 @@ APINotesManager::getCurrentModuleAPINotes(Module *M, bool LookInModule, ArrayRef SearchPaths) { FileManager &FM = SM.getFileManager(); auto ModuleName = M->getTopLevelModuleName(); + auto ExportedModuleName = M->getTopLevelModule()->ExportAsModule; llvm::SmallVector APINotes; // First, look relative to the module itself. @@ -233,6 +234,10 @@ APINotesManager::getCurrentModuleAPINotes(Module *M, bool LookInModule, APINotes.push_back(*File); } + // If module FooCore is re-exported through module Foo, try Foo.apinotes. + if (!ExportedModuleName.empty()) + if (auto File = findAPINotesFile(Dir, ExportedModuleName, WantPublic)) + APINotes.push_back(*File); }; if (M->IsFramework) { diff --git a/clang/test/APINotes/Inputs/Headers/ExportAs.apinotes b/clang/test/APINotes/Inputs/Headers/ExportAs.apinotes new file mode 100644 index 000000000000..14c77afd8c30 --- /dev/null +++ b/clang/test/APINotes/Inputs/Headers/ExportAs.apinotes @@ -0,0 +1,5 @@ +Name: ExportAs +Globals: + - Name: globalInt + Availability: none + AvailabilityMsg: "oh no" diff --git a/clang/test/APINotes/Inputs/Headers/ExportAs.h b/clang/test/APINotes/Inputs/Headers/ExportAs.h new file mode 100644 index 000000000000..ff490e096417 --- /dev/null +++ b/clang/test/APINotes/Inputs/Headers/ExportAs.h @@ -0,0 +1 @@ +#include "ExportAsCore.h" diff --git a/clang/test/APINotes/Inputs/Headers/ExportAsCore.h b/clang/test/APINotes/Inputs/Headers/ExportAsCore.h new file mode 100644 index 000000000000..f7674c19935d --- /dev/null +++ b/clang/test/APINotes/Inputs/Headers/ExportAsCore.h @@ -0,0 +1 @@ +static int globalInt = 123; diff --git a/clang/test/APINotes/Inputs/Headers/module.modulemap b/clang/test/APINotes/Inputs/Headers/module.modulemap index 98b4ee3e96cf..99fb1aec8648 100644 --- a/clang/test/APINotes/Inputs/Headers/module.modulemap +++ b/clang/test/APINotes/Inputs/Headers/module.modulemap @@ -2,6 +2,16 @@ module ExternCtx { header "ExternCtx.h" } +module ExportAsCore { + header "ExportAsCore.h" + export_as ExportAs +} + +module ExportAs { + header "ExportAs.h" + export * +} + module HeaderLib { header "HeaderLib.h" } diff --git a/clang/test/APINotes/export-as.c b/clang/test/APINotes/export-as.c new file mode 100644 index 000000000000..7a8a652ab755 --- /dev/null +++ b/clang/test/APINotes/export-as.c @@ -0,0 +1,8 @@ +// RUN: rm -rf %t && mkdir -p %t +// RUN: %clang_cc1 -fmodules -fimplicit-module-maps -fmodules-cache-path=%t/ModulesCache -fdisable-module-hash -fapinotes-modules -fsyntax-only -I %S/Inputs/Headers %s -ast-dump -ast-dump-filter globalInt -x c | FileCheck %s + +#include "ExportAs.h" + +// CHECK: Dumping globalInt: +// CHECK: VarDecl {{.+}} imported in ExportAsCore globalInt 'int' +// CHECK: UnavailableAttr {{.+}} <> "oh no" -- GitLab From 91856b34e3eddf157ab4c6ea623483b49d149e62 Mon Sep 17 00:00:00 2001 From: "Oleksandr \"Alex\" Zinenko" Date: Thu, 28 Mar 2024 14:00:22 +0100 Subject: [PATCH 055/788] [mlir] move MatchOpInterface under Transform/Interfaces (#86899) This is similar to the TransformOpInterface move. --- mlir/examples/transform/Ch4/include/MyExtension.td | 2 +- .../mlir/Dialect/Linalg/TransformOps/LinalgMatchOps.h | 2 +- .../mlir/Dialect/Linalg/TransformOps/LinalgMatchOps.td | 2 +- .../SparseTensor/TransformOps/SparseTensorTransformOps.h | 2 +- .../SparseTensor/TransformOps/SparseTensorTransformOps.td | 2 +- .../Dialect/Transform/DebugExtension/DebugExtensionOps.h | 2 +- .../Dialect/Transform/DebugExtension/DebugExtensionOps.td | 2 +- mlir/include/mlir/Dialect/Transform/IR/CMakeLists.txt | 4 ---- mlir/include/mlir/Dialect/Transform/IR/TransformOps.h | 2 +- mlir/include/mlir/Dialect/Transform/IR/TransformOps.td | 2 +- .../mlir/Dialect/Transform/Interfaces/CMakeLists.txt | 6 ++++++ .../Dialect/Transform/{IR => Interfaces}/MatchInterfaces.h | 2 +- .../Dialect/Transform/{IR => Interfaces}/MatchInterfaces.td | 0 mlir/lib/Dialect/Linalg/TransformOps/LinalgMatchOps.cpp | 2 +- mlir/lib/Dialect/Transform/IR/CMakeLists.txt | 5 ----- mlir/lib/Dialect/Transform/IR/TransformOps.cpp | 2 +- mlir/lib/Dialect/Transform/Interfaces/CMakeLists.txt | 2 ++ .../Transform/{IR => Interfaces}/MatchInterfaces.cpp | 4 ++-- .../lib/Dialect/Transform/TestTransformDialectExtension.h | 2 +- .../lib/Dialect/Transform/TestTransformDialectExtension.td | 2 +- 20 files changed, 24 insertions(+), 25 deletions(-) rename mlir/include/mlir/Dialect/Transform/{IR => Interfaces}/MatchInterfaces.h (99%) rename mlir/include/mlir/Dialect/Transform/{IR => Interfaces}/MatchInterfaces.td (100%) rename mlir/lib/Dialect/Transform/{IR => Interfaces}/MatchInterfaces.cpp (97%) diff --git a/mlir/examples/transform/Ch4/include/MyExtension.td b/mlir/examples/transform/Ch4/include/MyExtension.td index 6c83ff0f46c8..660680334178 100644 --- a/mlir/examples/transform/Ch4/include/MyExtension.td +++ b/mlir/examples/transform/Ch4/include/MyExtension.td @@ -14,7 +14,7 @@ #ifndef MY_EXTENSION #define MY_EXTENSION -include "mlir/Dialect/Transform/IR/MatchInterfaces.td" +include "mlir/Dialect/Transform/Interfaces/MatchInterfaces.td" include "mlir/Dialect/Transform/IR/TransformDialect.td" include "mlir/Dialect/Transform/Interfaces/TransformInterfaces.td" include "mlir/IR/OpBase.td" diff --git a/mlir/include/mlir/Dialect/Linalg/TransformOps/LinalgMatchOps.h b/mlir/include/mlir/Dialect/Linalg/TransformOps/LinalgMatchOps.h index d6bbcf88b79f..fdebcb031b11 100644 --- a/mlir/include/mlir/Dialect/Linalg/TransformOps/LinalgMatchOps.h +++ b/mlir/include/mlir/Dialect/Linalg/TransformOps/LinalgMatchOps.h @@ -10,8 +10,8 @@ #define MLIR_DIALECT_LINALG_TRANSFORMOPS_LINALGMATCHOPS_H #include "mlir/Dialect/Linalg/IR/Linalg.h" -#include "mlir/Dialect/Transform/IR/MatchInterfaces.h" #include "mlir/Dialect/Transform/IR/TransformAttrs.h" +#include "mlir/Dialect/Transform/Interfaces/MatchInterfaces.h" namespace mlir { namespace transform { diff --git a/mlir/include/mlir/Dialect/Linalg/TransformOps/LinalgMatchOps.td b/mlir/include/mlir/Dialect/Linalg/TransformOps/LinalgMatchOps.td index dfeb8ae5d5dd..cdc29d053e5a 100644 --- a/mlir/include/mlir/Dialect/Linalg/TransformOps/LinalgMatchOps.td +++ b/mlir/include/mlir/Dialect/Linalg/TransformOps/LinalgMatchOps.td @@ -10,7 +10,7 @@ #define LINALG_MATCH_OPS include "mlir/Dialect/Linalg/TransformOps/LinalgTransformEnums.td" -include "mlir/Dialect/Transform/IR/MatchInterfaces.td" +include "mlir/Dialect/Transform/Interfaces/MatchInterfaces.td" include "mlir/Dialect/Transform/IR/TransformAttrs.td" include "mlir/Dialect/Transform/IR/TransformDialect.td" include "mlir/Dialect/Transform/IR/TransformTypes.td" diff --git a/mlir/include/mlir/Dialect/SparseTensor/TransformOps/SparseTensorTransformOps.h b/mlir/include/mlir/Dialect/SparseTensor/TransformOps/SparseTensorTransformOps.h index 54a9e2aec805..8c3124909052 100644 --- a/mlir/include/mlir/Dialect/SparseTensor/TransformOps/SparseTensorTransformOps.h +++ b/mlir/include/mlir/Dialect/SparseTensor/TransformOps/SparseTensorTransformOps.h @@ -9,9 +9,9 @@ #ifndef MLIR_DIALECT_SPARSETENSOR_TRANSFORMOPS_SPARSETENSORTRANSFORMOPS_H #define MLIR_DIALECT_SPARSETENSOR_TRANSFORMOPS_SPARSETENSORTRANSFORMOPS_H -#include "mlir/Dialect/Transform/IR/MatchInterfaces.h" #include "mlir/Dialect/Transform/IR/TransformAttrs.h" #include "mlir/Dialect/Transform/IR/TransformDialect.h" +#include "mlir/Dialect/Transform/Interfaces/MatchInterfaces.h" #include "mlir/Dialect/Transform/Interfaces/TransformInterfaces.h" #include "mlir/IR/OpImplementation.h" #include "mlir/IR/RegionKindInterface.h" diff --git a/mlir/include/mlir/Dialect/SparseTensor/TransformOps/SparseTensorTransformOps.td b/mlir/include/mlir/Dialect/SparseTensor/TransformOps/SparseTensorTransformOps.td index 9f0436e701b8..e340228795cd 100644 --- a/mlir/include/mlir/Dialect/SparseTensor/TransformOps/SparseTensorTransformOps.td +++ b/mlir/include/mlir/Dialect/SparseTensor/TransformOps/SparseTensorTransformOps.td @@ -11,7 +11,7 @@ #ifndef SPARSETENSOR_TRANSFORM_OPS #define SPARSETENSOR_TRANSFORM_OPS -include "mlir/Dialect/Transform/IR/MatchInterfaces.td" +include "mlir/Dialect/Transform/Interfaces/MatchInterfaces.td" include "mlir/Dialect/Transform/IR/TransformAttrs.td" include "mlir/Dialect/Transform/IR/TransformDialect.td" include "mlir/Dialect/Transform/IR/TransformTypes.td" diff --git a/mlir/include/mlir/Dialect/Transform/DebugExtension/DebugExtensionOps.h b/mlir/include/mlir/Dialect/Transform/DebugExtension/DebugExtensionOps.h index 05abe5adbe80..ea541c9515b8 100644 --- a/mlir/include/mlir/Dialect/Transform/DebugExtension/DebugExtensionOps.h +++ b/mlir/include/mlir/Dialect/Transform/DebugExtension/DebugExtensionOps.h @@ -10,8 +10,8 @@ #define MLIR_DIALECT_TRANSFORM_DEBUGEXTENSION_DEBUGEXTENSIONOPS_H #include "mlir/Bytecode/BytecodeOpInterface.h" -#include "mlir/Dialect/Transform/IR/MatchInterfaces.h" #include "mlir/Dialect/Transform/IR/TransformDialect.h" +#include "mlir/Dialect/Transform/Interfaces/MatchInterfaces.h" #include "mlir/Dialect/Transform/Interfaces/TransformInterfaces.h" #include "mlir/IR/OpDefinition.h" #include "mlir/IR/OpImplementation.h" diff --git a/mlir/include/mlir/Dialect/Transform/DebugExtension/DebugExtensionOps.td b/mlir/include/mlir/Dialect/Transform/DebugExtension/DebugExtensionOps.td index dc9b7c4229ac..0275f241fda3 100644 --- a/mlir/include/mlir/Dialect/Transform/DebugExtension/DebugExtensionOps.td +++ b/mlir/include/mlir/Dialect/Transform/DebugExtension/DebugExtensionOps.td @@ -16,7 +16,7 @@ include "mlir/Interfaces/SideEffectInterfaces.td" include "mlir/IR/OpBase.td" -include "mlir/Dialect/Transform/IR/MatchInterfaces.td" +include "mlir/Dialect/Transform/Interfaces/MatchInterfaces.td" include "mlir/Dialect/Transform/Interfaces/TransformInterfaces.td" include "mlir/Dialect/Transform/IR/TransformDialect.td" diff --git a/mlir/include/mlir/Dialect/Transform/IR/CMakeLists.txt b/mlir/include/mlir/Dialect/Transform/IR/CMakeLists.txt index e90d04a20244..df5af7ae710d 100644 --- a/mlir/include/mlir/Dialect/Transform/IR/CMakeLists.txt +++ b/mlir/include/mlir/Dialect/Transform/IR/CMakeLists.txt @@ -24,7 +24,3 @@ add_dependencies(mlir-headers MLIRTransformDialectEnumIncGen) add_mlir_dialect(TransformOps transform) add_mlir_doc(TransformOps TransformOps Dialects/ -gen-op-doc -dialect=transform) -add_mlir_interface(MatchInterfaces) -add_dependencies(MLIRMatchInterfacesIncGen MLIRTransformInterfacesIncGen) -add_mlir_doc(MatchInterfaces MatchOpInterfaces Dialects/ -gen-op-interface-docs) - diff --git a/mlir/include/mlir/Dialect/Transform/IR/TransformOps.h b/mlir/include/mlir/Dialect/Transform/IR/TransformOps.h index 6c10fcf75804..88185a07966d 100644 --- a/mlir/include/mlir/Dialect/Transform/IR/TransformOps.h +++ b/mlir/include/mlir/Dialect/Transform/IR/TransformOps.h @@ -10,10 +10,10 @@ #define MLIR_DIALECT_TRANSFORM_IR_TRANSFORMOPS_H #include "mlir/Bytecode/BytecodeOpInterface.h" -#include "mlir/Dialect/Transform/IR/MatchInterfaces.h" #include "mlir/Dialect/Transform/IR/TransformAttrs.h" #include "mlir/Dialect/Transform/IR/TransformDialect.h" #include "mlir/Dialect/Transform/IR/TransformTypes.h" +#include "mlir/Dialect/Transform/Interfaces/MatchInterfaces.h" #include "mlir/Dialect/Transform/Interfaces/TransformInterfaces.h" #include "mlir/IR/OpDefinition.h" #include "mlir/IR/OpImplementation.h" diff --git a/mlir/include/mlir/Dialect/Transform/IR/TransformOps.td b/mlir/include/mlir/Dialect/Transform/IR/TransformOps.td index 9caa7632c177..bf1a8016cd9d 100644 --- a/mlir/include/mlir/Dialect/Transform/IR/TransformOps.td +++ b/mlir/include/mlir/Dialect/Transform/IR/TransformOps.td @@ -18,7 +18,7 @@ include "mlir/Interfaces/FunctionInterfaces.td" include "mlir/IR/OpAsmInterface.td" include "mlir/IR/RegionKindInterface.td" include "mlir/IR/SymbolInterfaces.td" -include "mlir/Dialect/Transform/IR/MatchInterfaces.td" +include "mlir/Dialect/Transform/Interfaces/MatchInterfaces.td" include "mlir/Dialect/Transform/IR/TransformAttrs.td" include "mlir/Dialect/Transform/IR/TransformDialect.td" include "mlir/Dialect/Transform/Interfaces/TransformInterfaces.td" diff --git a/mlir/include/mlir/Dialect/Transform/Interfaces/CMakeLists.txt b/mlir/include/mlir/Dialect/Transform/Interfaces/CMakeLists.txt index b3396b67b4f7..14ce5b82b811 100644 --- a/mlir/include/mlir/Dialect/Transform/Interfaces/CMakeLists.txt +++ b/mlir/include/mlir/Dialect/Transform/Interfaces/CMakeLists.txt @@ -9,3 +9,9 @@ mlir_tablegen(TransformTypeInterfaces.cpp.inc -gen-type-interface-defs) add_public_tablegen_target(MLIRTransformDialectTypeInterfacesIncGen) add_dependencies(mlir-headers MLIRTransformDialectTypeInterfacesIncGen) add_mlir_doc(TransformInterfaces TransformTypeInterfaces Dialects/ -gen-type-interface-docs) + +add_mlir_interface(MatchInterfaces) +add_dependencies(MLIRMatchInterfacesIncGen MLIRTransformInterfacesIncGen) +add_dependencies(mlir-headers MLIRMatchInterfacesIncGen) +add_mlir_doc(MatchInterfaces MatchOpInterfaces Dialects/ -gen-op-interface-docs) + diff --git a/mlir/include/mlir/Dialect/Transform/IR/MatchInterfaces.h b/mlir/include/mlir/Dialect/Transform/Interfaces/MatchInterfaces.h similarity index 99% rename from mlir/include/mlir/Dialect/Transform/IR/MatchInterfaces.h rename to mlir/include/mlir/Dialect/Transform/Interfaces/MatchInterfaces.h index 13a52b54201e..ad3e375c326f 100644 --- a/mlir/include/mlir/Dialect/Transform/IR/MatchInterfaces.h +++ b/mlir/include/mlir/Dialect/Transform/Interfaces/MatchInterfaces.h @@ -218,6 +218,6 @@ expandTargetSpecification(Location loc, bool isAll, bool isInverted, } // namespace transform } // namespace mlir -#include "mlir/Dialect/Transform/IR/MatchInterfaces.h.inc" +#include "mlir/Dialect/Transform/Interfaces/MatchInterfaces.h.inc" #endif // MLIR_DIALECT_TRANSFORM_IR_MATCHINTERFACES_H diff --git a/mlir/include/mlir/Dialect/Transform/IR/MatchInterfaces.td b/mlir/include/mlir/Dialect/Transform/Interfaces/MatchInterfaces.td similarity index 100% rename from mlir/include/mlir/Dialect/Transform/IR/MatchInterfaces.td rename to mlir/include/mlir/Dialect/Transform/Interfaces/MatchInterfaces.td diff --git a/mlir/lib/Dialect/Linalg/TransformOps/LinalgMatchOps.cpp b/mlir/lib/Dialect/Linalg/TransformOps/LinalgMatchOps.cpp index ae2a34bcf3e5..3e85559e1ec0 100644 --- a/mlir/lib/Dialect/Linalg/TransformOps/LinalgMatchOps.cpp +++ b/mlir/lib/Dialect/Linalg/TransformOps/LinalgMatchOps.cpp @@ -12,8 +12,8 @@ #include "mlir/Dialect/Linalg/IR/LinalgInterfaces.h" #include "mlir/Dialect/Linalg/TransformOps/Syntax.h" #include "mlir/Dialect/Linalg/Utils/Utils.h" -#include "mlir/Dialect/Transform/IR/MatchInterfaces.h" #include "mlir/Dialect/Transform/IR/TransformTypes.h" +#include "mlir/Dialect/Transform/Interfaces/MatchInterfaces.h" #include "mlir/IR/BuiltinAttributes.h" #include "mlir/Interfaces/FunctionImplementation.h" #include "llvm/Support/Debug.h" diff --git a/mlir/lib/Dialect/Transform/IR/CMakeLists.txt b/mlir/lib/Dialect/Transform/IR/CMakeLists.txt index f90ac089adaa..5b4989f328e6 100644 --- a/mlir/lib/Dialect/Transform/IR/CMakeLists.txt +++ b/mlir/lib/Dialect/Transform/IR/CMakeLists.txt @@ -1,15 +1,10 @@ add_mlir_dialect_library(MLIRTransformDialect - MatchInterfaces.cpp TransformAttrs.cpp TransformDialect.cpp TransformOps.cpp TransformTypes.cpp Utils.cpp - DEPENDS - MLIRMatchInterfacesIncGen - MLIRTransformDialectIncGen - LINK_LIBS PUBLIC MLIRCastInterfaces MLIRFunctionInterfaces diff --git a/mlir/lib/Dialect/Transform/IR/TransformOps.cpp b/mlir/lib/Dialect/Transform/IR/TransformOps.cpp index abd557a508a1..942341093817 100644 --- a/mlir/lib/Dialect/Transform/IR/TransformOps.cpp +++ b/mlir/lib/Dialect/Transform/IR/TransformOps.cpp @@ -11,10 +11,10 @@ #include "mlir/Conversion/ConvertToLLVM/ToLLVMInterface.h" #include "mlir/Conversion/LLVMCommon/ConversionTarget.h" #include "mlir/Conversion/LLVMCommon/TypeConverter.h" -#include "mlir/Dialect/Transform/IR/MatchInterfaces.h" #include "mlir/Dialect/Transform/IR/TransformAttrs.h" #include "mlir/Dialect/Transform/IR/TransformDialect.h" #include "mlir/Dialect/Transform/IR/TransformTypes.h" +#include "mlir/Dialect/Transform/Interfaces/MatchInterfaces.h" #include "mlir/Dialect/Transform/Interfaces/TransformInterfaces.h" #include "mlir/IR/BuiltinAttributes.h" #include "mlir/IR/Diagnostics.h" diff --git a/mlir/lib/Dialect/Transform/Interfaces/CMakeLists.txt b/mlir/lib/Dialect/Transform/Interfaces/CMakeLists.txt index 7b837bde0625..fc9cbfdc9a5b 100644 --- a/mlir/lib/Dialect/Transform/Interfaces/CMakeLists.txt +++ b/mlir/lib/Dialect/Transform/Interfaces/CMakeLists.txt @@ -1,7 +1,9 @@ add_mlir_library(MLIRTransformDialectInterfaces + MatchInterfaces.cpp TransformInterfaces.cpp DEPENDS + MLIRMatchInterfacesIncGen MLIRTransformInterfacesIncGen LINK_LIBS PUBLIC diff --git a/mlir/lib/Dialect/Transform/IR/MatchInterfaces.cpp b/mlir/lib/Dialect/Transform/Interfaces/MatchInterfaces.cpp similarity index 97% rename from mlir/lib/Dialect/Transform/IR/MatchInterfaces.cpp rename to mlir/lib/Dialect/Transform/Interfaces/MatchInterfaces.cpp index b9b6dabc2621..4151d0ea5bee 100644 --- a/mlir/lib/Dialect/Transform/IR/MatchInterfaces.cpp +++ b/mlir/lib/Dialect/Transform/Interfaces/MatchInterfaces.cpp @@ -6,7 +6,7 @@ // //===----------------------------------------------------------------------===// -#include "mlir/Dialect/Transform/IR/MatchInterfaces.h" +#include "mlir/Dialect/Transform/Interfaces/MatchInterfaces.h" using namespace mlir; @@ -149,4 +149,4 @@ DiagnosedSilenceableFailure transform::expandTargetSpecification( // Generated interface implementation. //===----------------------------------------------------------------------===// -#include "mlir/Dialect/Transform/IR/MatchInterfaces.cpp.inc" +#include "mlir/Dialect/Transform/Interfaces/MatchInterfaces.cpp.inc" diff --git a/mlir/test/lib/Dialect/Transform/TestTransformDialectExtension.h b/mlir/test/lib/Dialect/Transform/TestTransformDialectExtension.h index ddc38b993564..60dc959b0050 100644 --- a/mlir/test/lib/Dialect/Transform/TestTransformDialectExtension.h +++ b/mlir/test/lib/Dialect/Transform/TestTransformDialectExtension.h @@ -16,8 +16,8 @@ #include "mlir/Bytecode/BytecodeOpInterface.h" #include "mlir/Dialect/PDL/IR/PDLTypes.h" -#include "mlir/Dialect/Transform/IR/MatchInterfaces.h" #include "mlir/Dialect/Transform/IR/TransformTypes.h" +#include "mlir/Dialect/Transform/Interfaces/MatchInterfaces.h" #include "mlir/Dialect/Transform/Interfaces/TransformInterfaces.h" #include "mlir/IR/OpImplementation.h" diff --git a/mlir/test/lib/Dialect/Transform/TestTransformDialectExtension.td b/mlir/test/lib/Dialect/Transform/TestTransformDialectExtension.td index 75134b25882f..4f2cf34f7d33 100644 --- a/mlir/test/lib/Dialect/Transform/TestTransformDialectExtension.td +++ b/mlir/test/lib/Dialect/Transform/TestTransformDialectExtension.td @@ -17,7 +17,7 @@ include "mlir/Interfaces/SideEffectInterfaces.td" include "mlir/IR/AttrTypeBase.td" include "mlir/IR/OpBase.td" -include "mlir/Dialect/Transform/IR/MatchInterfaces.td" +include "mlir/Dialect/Transform/Interfaces/MatchInterfaces.td" include "mlir/Dialect/Transform/IR/TransformDialect.td" include "mlir/Dialect/Transform/Interfaces/TransformInterfaces.td" include "mlir/Dialect/PDL/IR/PDLTypes.td" -- GitLab From eacda36c7dd842cb15c0c954eda74b67d0c73814 Mon Sep 17 00:00:00 2001 From: Rolf Morel Date: Thu, 28 Mar 2024 13:13:08 +0000 Subject: [PATCH 056/788] [SCF][Transform] Add support for scf.for in LoopFuseSibling op (#81495) Adds support for fusing two scf.for loops occurring in the same block. Uses the rudimentary checks already in place for scf.forall (like the target loop's operands being dominated by the source loop). - Fixes a bug in the dominance check whereby it was checked that values in the target loop themselves dominated the source loop rather than the ops that define these operands. - Renames the LoopFuseSibling op to LoopFuseSiblingOp. - Updates LoopFuseSiblingOp's description. - Adds tests for using LoopFuseSiblingOp on scf.for loops, including one which fails without the fix for the dominance check. - Adds tests checking the different failure modes of the dominance checker. - Adds test for case whereby scf.yield is automatically generated when there are no loop-carried variables. --- .../SCF/TransformOps/SCFTransformOps.td | 23 +- mlir/include/mlir/Dialect/SCF/Utils/Utils.h | 10 + .../SCF/TransformOps/SCFTransformOps.cpp | 66 +++-- mlir/lib/Dialect/SCF/Utils/Utils.cpp | 99 ++++--- .../SCF/transform-loop-fuse-sibling.mlir | 251 ++++++++++++++++-- 5 files changed, 357 insertions(+), 92 deletions(-) diff --git a/mlir/include/mlir/Dialect/SCF/TransformOps/SCFTransformOps.td b/mlir/include/mlir/Dialect/SCF/TransformOps/SCFTransformOps.td index 6f94cee5b019..5eefe2664d0a 100644 --- a/mlir/include/mlir/Dialect/SCF/TransformOps/SCFTransformOps.td +++ b/mlir/include/mlir/Dialect/SCF/TransformOps/SCFTransformOps.td @@ -333,23 +333,24 @@ def TakeAssumedBranchOp : Op]> { let summary = "Fuse a loop into another loop, assuming the fusion is legal."; let description = [{ Fuses the `target` loop into the `source` loop assuming they are - independent of each other. It is the responsibility of the user to ensure - that the given two loops are independent of each other, this operation will - not performa any legality checks and will simply fuse the two given loops. + independent of each other. In the fused loop, the arguments, body and + results of `target` are placed _before_ those of `source`. - Currently, the only fusion supported is when both `target` and `source` - are `scf.forall` operations. For `scf.forall` fusion, the bounds and the - mapping must match, otherwise a silencable failure is produced. + For fusion of two `scf.for` loops, the bounds and step size must match. For + fusion of two `scf.forall` loops, the bounds and the mapping must match. + Otherwise a silencable failure is produced. - The input handles `target` and `source` must map to exactly one operation, - a definite failure is produced otherwise. + The `target` and `source` handles must refer to exactly one operation, + otherwise a definite failure is produced. It is the responsibility of the + user to ensure that the `target` and `source` loops are independent of each + other -- this op will only perform rudimentary legality checks. #### Return modes @@ -362,10 +363,6 @@ def LoopFuseSibling : Op - ]; } #endif // SCF_TRANSFORM_OPS diff --git a/mlir/include/mlir/Dialect/SCF/Utils/Utils.h b/mlir/include/mlir/Dialect/SCF/Utils/Utils.h index 9bdd6eb83387..883d11bcc4df 100644 --- a/mlir/include/mlir/Dialect/SCF/Utils/Utils.h +++ b/mlir/include/mlir/Dialect/SCF/Utils/Utils.h @@ -162,6 +162,16 @@ scf::ForallOp fuseIndependentSiblingForallLoops(scf::ForallOp target, scf::ForallOp source, RewriterBase &rewriter); +/// Given two scf.for loops, `target` and `source`, fuses `target` into +/// `source`. Assumes that the given loops are siblings and are independent of +/// each other. +/// +/// This function does not perform any legality checks and simply fuses the +/// loops. The caller is responsible for ensuring that the loops are legal to +/// fuse. +scf::ForOp fuseIndependentSiblingForLoops(scf::ForOp target, scf::ForOp source, + RewriterBase &rewriter); + } // namespace mlir #endif // MLIR_DIALECT_SCF_UTILS_UTILS_H_ diff --git a/mlir/lib/Dialect/SCF/TransformOps/SCFTransformOps.cpp b/mlir/lib/Dialect/SCF/TransformOps/SCFTransformOps.cpp index 4d8d93f7aac7..c09184148208 100644 --- a/mlir/lib/Dialect/SCF/TransformOps/SCFTransformOps.cpp +++ b/mlir/lib/Dialect/SCF/TransformOps/SCFTransformOps.cpp @@ -384,7 +384,7 @@ void transform::TakeAssumedBranchOp::getEffects( } //===----------------------------------------------------------------------===// -// LoopFuseSibling +// LoopFuseSiblingOp //===----------------------------------------------------------------------===// /// Check if `target` and `source` are siblings, in the context that `target` @@ -408,7 +408,7 @@ static DiagnosedSilenceableFailure isOpSibling(Operation *target, // Check if fusion will violate dominance. DominanceInfo domInfo(source); if (target->isBeforeInBlock(source)) { - // Since, `target` is before `source`, all users of results of `target` + // Since `target` is before `source`, all users of results of `target` // need to be dominated by `source`. for (Operation *user : target->getUsers()) { if (!domInfo.properlyDominates(source, user, /*enclosingOpOk=*/false)) { @@ -424,9 +424,8 @@ static DiagnosedSilenceableFailure isOpSibling(Operation *target, // Check if operands of `target` are dominated by `source`. for (Value operand : target->getOperands()) { Operation *operandOp = operand.getDefiningOp(); - // If operand does not have a defining operation, it is a block arguement, - // which will always dominate `source`, since `target` and `source` are in - // the same block and the operand dominated `source` before. + // Operands without defining operations are block arguments. When `target` + // and `source` occur in the same block, these operands dominate `source`. if (!operandOp) continue; @@ -441,8 +440,11 @@ static DiagnosedSilenceableFailure isOpSibling(Operation *target, bool failed = false; OpOperand *failedValue = nullptr; visitUsedValuesDefinedAbove(target->getRegions(), [&](OpOperand *operand) { - if (!domInfo.properlyDominates(operand->getOwner(), source, - /*enclosingOpOk=*/false)) { + Operation *operandOp = operand->get().getDefiningOp(); + if (operandOp && !domInfo.properlyDominates(operandOp, source, + /*enclosingOpOk=*/false)) { + // `operand` is not an argument of an enclosing block and the defining + // op of `operand` is outside `target` but does not dominate `source`. failed = true; failedValue = operand; } @@ -457,12 +459,11 @@ static DiagnosedSilenceableFailure isOpSibling(Operation *target, return DiagnosedSilenceableFailure::success(); } -/// Check if `target` can be fused into `source`. +/// Check if `target` scf.forall can be fused into `source` scf.forall. /// -/// This is a simple check that just checks if both loops have same -/// bounds, steps and mapping. This check does not ensure that the side effects -/// of `target` are independent of `source` or vice-versa. It is the -/// responsibility of the caller to ensure that. +/// This simply checks if both loops have the same bounds, steps and mapping. +/// No attempt is made at checking that the side effects of `target` and +/// `source` are independent of each other. static bool isForallWithIdenticalConfiguration(Operation *target, Operation *source) { auto targetOp = dyn_cast(target); @@ -476,21 +477,27 @@ static bool isForallWithIdenticalConfiguration(Operation *target, targetOp.getMapping() == sourceOp.getMapping(); } -/// Fuse `target` into `source` assuming they are siblings and indepndent. -/// TODO: Add fusion for more operations. Currently, we handle only scf.forall. -static Operation *fuseSiblings(Operation *target, Operation *source, - RewriterBase &rewriter) { - auto targetOp = dyn_cast(target); - auto sourceOp = dyn_cast(source); +/// Check if `target` scf.for can be fused into `source` scf.for. +/// +/// This simply checks if both loops have the same bounds and steps. No attempt +/// is made at checking that the side effects of `target` and `source` are +/// independent of each other. +static bool isForWithIdenticalConfiguration(Operation *target, + Operation *source) { + auto targetOp = dyn_cast(target); + auto sourceOp = dyn_cast(source); if (!targetOp || !sourceOp) - return nullptr; - return fuseIndependentSiblingForallLoops(targetOp, sourceOp, rewriter); + return false; + + return targetOp.getLowerBound() == sourceOp.getLowerBound() && + targetOp.getUpperBound() == sourceOp.getUpperBound() && + targetOp.getStep() == sourceOp.getStep(); } DiagnosedSilenceableFailure -transform::LoopFuseSibling::apply(transform::TransformRewriter &rewriter, - transform::TransformResults &results, - transform::TransformState &state) { +transform::LoopFuseSiblingOp::apply(transform::TransformRewriter &rewriter, + transform::TransformResults &results, + transform::TransformState &state) { auto targetOps = state.getPayloadOps(getTarget()); auto sourceOps = state.getPayloadOps(getSource()); @@ -510,13 +517,18 @@ transform::LoopFuseSibling::apply(transform::TransformRewriter &rewriter, if (!diag.succeeded()) return diag; - // Check if the target can be fused into source. - if (!isForallWithIdenticalConfiguration(target, source)) { + Operation *fusedLoop; + /// TODO: Support fusion for loop-like ops besides scf.for and scf.forall. + if (isForWithIdenticalConfiguration(target, source)) { + fusedLoop = fuseIndependentSiblingForLoops( + cast(target), cast(source), rewriter); + } else if (isForallWithIdenticalConfiguration(target, source)) { + fusedLoop = fuseIndependentSiblingForallLoops( + cast(target), cast(source), rewriter); + } else return emitSilenceableFailure(target->getLoc()) << "operations cannot be fused"; - } - Operation *fusedLoop = fuseSiblings(target, source, rewriter); assert(fusedLoop && "failed to fuse operations"); results.set(cast(getFusedLoop()), {fusedLoop}); diff --git a/mlir/lib/Dialect/SCF/Utils/Utils.cpp b/mlir/lib/Dialect/SCF/Utils/Utils.cpp index 502d7e197a6f..914aeb4fa79f 100644 --- a/mlir/lib/Dialect/SCF/Utils/Utils.cpp +++ b/mlir/lib/Dialect/SCF/Utils/Utils.cpp @@ -910,61 +910,98 @@ scf::ForallOp mlir::fuseIndependentSiblingForallLoops(scf::ForallOp target, unsigned numTargetOuts = target.getNumResults(); unsigned numSourceOuts = source.getNumResults(); - OperandRange targetOuts = target.getOutputs(); - OperandRange sourceOuts = source.getOutputs(); - // Create fused shared_outs. SmallVector fusedOuts; - fusedOuts.reserve(numTargetOuts + numSourceOuts); - fusedOuts.append(targetOuts.begin(), targetOuts.end()); - fusedOuts.append(sourceOuts.begin(), sourceOuts.end()); + llvm::append_range(fusedOuts, target.getOutputs()); + llvm::append_range(fusedOuts, source.getOutputs()); - // Create a new scf::forall op after the source loop. + // Create a new scf.forall op after the source loop. rewriter.setInsertionPointAfter(source); scf::ForallOp fusedLoop = rewriter.create( source.getLoc(), source.getMixedLowerBound(), source.getMixedUpperBound(), source.getMixedStep(), fusedOuts, source.getMapping()); // Map control operands. - IRMapping fusedMapping; - fusedMapping.map(target.getInductionVars(), fusedLoop.getInductionVars()); - fusedMapping.map(source.getInductionVars(), fusedLoop.getInductionVars()); + IRMapping mapping; + mapping.map(target.getInductionVars(), fusedLoop.getInductionVars()); + mapping.map(source.getInductionVars(), fusedLoop.getInductionVars()); // Map shared outs. - fusedMapping.map(target.getRegionIterArgs(), - fusedLoop.getRegionIterArgs().slice(0, numTargetOuts)); - fusedMapping.map( - source.getRegionIterArgs(), - fusedLoop.getRegionIterArgs().slice(numTargetOuts, numSourceOuts)); + mapping.map(target.getRegionIterArgs(), + fusedLoop.getRegionIterArgs().take_front(numTargetOuts)); + mapping.map(source.getRegionIterArgs(), + fusedLoop.getRegionIterArgs().take_back(numSourceOuts)); // Append everything except the terminator into the fused operation. rewriter.setInsertionPointToStart(fusedLoop.getBody()); for (Operation &op : target.getBody()->without_terminator()) - rewriter.clone(op, fusedMapping); + rewriter.clone(op, mapping); for (Operation &op : source.getBody()->without_terminator()) - rewriter.clone(op, fusedMapping); + rewriter.clone(op, mapping); // Fuse the old terminator in_parallel ops into the new one. scf::InParallelOp targetTerm = target.getTerminator(); scf::InParallelOp sourceTerm = source.getTerminator(); scf::InParallelOp fusedTerm = fusedLoop.getTerminator(); - rewriter.setInsertionPointToStart(fusedTerm.getBody()); for (Operation &op : targetTerm.getYieldingOps()) - rewriter.clone(op, fusedMapping); + rewriter.clone(op, mapping); for (Operation &op : sourceTerm.getYieldingOps()) - rewriter.clone(op, fusedMapping); - - // Replace all uses of the old loops with the fused loop. - rewriter.replaceAllUsesWith(target.getResults(), - fusedLoop.getResults().slice(0, numTargetOuts)); - rewriter.replaceAllUsesWith( - source.getResults(), - fusedLoop.getResults().slice(numTargetOuts, numSourceOuts)); - - // Erase the old loops. - rewriter.eraseOp(target); - rewriter.eraseOp(source); + rewriter.clone(op, mapping); + + // Replace old loops by substituting their uses by results of the fused loop. + rewriter.replaceOp(target, fusedLoop.getResults().take_front(numTargetOuts)); + rewriter.replaceOp(source, fusedLoop.getResults().take_back(numSourceOuts)); + + return fusedLoop; +} + +scf::ForOp mlir::fuseIndependentSiblingForLoops(scf::ForOp target, + scf::ForOp source, + RewriterBase &rewriter) { + unsigned numTargetOuts = target.getNumResults(); + unsigned numSourceOuts = source.getNumResults(); + + // Create fused init_args, with target's init_args before source's init_args. + SmallVector fusedInitArgs; + llvm::append_range(fusedInitArgs, target.getInitArgs()); + llvm::append_range(fusedInitArgs, source.getInitArgs()); + + // Create a new scf.for op after the source loop (with scf.yield terminator + // (without arguments) only in case its init_args is empty). + rewriter.setInsertionPointAfter(source); + scf::ForOp fusedLoop = rewriter.create( + source.getLoc(), source.getLowerBound(), source.getUpperBound(), + source.getStep(), fusedInitArgs); + + // Map original induction variables and operands to those of the fused loop. + IRMapping mapping; + mapping.map(target.getInductionVar(), fusedLoop.getInductionVar()); + mapping.map(target.getRegionIterArgs(), + fusedLoop.getRegionIterArgs().take_front(numTargetOuts)); + mapping.map(source.getInductionVar(), fusedLoop.getInductionVar()); + mapping.map(source.getRegionIterArgs(), + fusedLoop.getRegionIterArgs().take_back(numSourceOuts)); + + // Merge target's body into the new (fused) for loop and then source's body. + rewriter.setInsertionPointToStart(fusedLoop.getBody()); + for (Operation &op : target.getBody()->without_terminator()) + rewriter.clone(op, mapping); + for (Operation &op : source.getBody()->without_terminator()) + rewriter.clone(op, mapping); + + // Build fused yield results by appropriately mapping original yield operands. + SmallVector yieldResults; + for (Value operand : target.getBody()->getTerminator()->getOperands()) + yieldResults.push_back(mapping.lookupOrDefault(operand)); + for (Value operand : source.getBody()->getTerminator()->getOperands()) + yieldResults.push_back(mapping.lookupOrDefault(operand)); + if (!yieldResults.empty()) + rewriter.create(source.getLoc(), yieldResults); + + // Replace old loops by substituting their uses by results of the fused loop. + rewriter.replaceOp(target, fusedLoop.getResults().take_front(numTargetOuts)); + rewriter.replaceOp(source, fusedLoop.getResults().take_back(numSourceOuts)); return fusedLoop; } diff --git a/mlir/test/Dialect/SCF/transform-loop-fuse-sibling.mlir b/mlir/test/Dialect/SCF/transform-loop-fuse-sibling.mlir index faaa2db3aa57..0f51b1cdbe0c 100644 --- a/mlir/test/Dialect/SCF/transform-loop-fuse-sibling.mlir +++ b/mlir/test/Dialect/SCF/transform-loop-fuse-sibling.mlir @@ -1,14 +1,113 @@ // RUN: mlir-opt %s -transform-interpreter --cse --canonicalize -split-input-file -verify-diagnostics | FileCheck %s +// RUN: mlir-opt %s -transform-interpreter -split-input-file -verify-diagnostics | FileCheck %s --check-prefix CHECK-NOCLEANUP -func.func @test(%A : tensor<128x128xf32>, %B1 : tensor<128x128xf32>, %B2 : tensor<128x128xf32>) -> (tensor<128x128xf32>, tensor<128x128xf32>) { +// CHECK: func.func @fuse_1st_for_into_2nd([[A:%.*]]: {{.*}}, [[B:%.*]]: {{.*}} +func.func @fuse_1st_for_into_2nd(%A: tensor<128xf32>, %B: tensor<128xf32>) -> (tensor<128xf32>, tensor<128xf32>) { + // CHECK-DAG: [[C0:%.*]] = arith.constant 0 : index + // CHECK-DAG: [[C16:%.*]] = arith.constant 16 : index + // CHECK-DAG: [[C128:%.*]] = arith.constant 128 : index + // CHECK-DAG: [[ZERO:%.*]] = arith.constant 0.000000e+00 : f32 + %c0 = arith.constant 0 : index + %c16 = arith.constant 16 : index + %c128 = arith.constant 128 : index + %cst = arith.constant 0.000000e+00 : f32 + // CHECK: [[R0:%.*]]:2 = scf.for [[IV:%.*]] = [[C0]] to [[C128]] step [[C16]] iter_args([[IA:%.*]] = [[A]], [[IB:%.*]] = [[B]]) {{.*}} + %1 = scf.for %arg3 = %c0 to %c128 step %c16 iter_args(%arg4 = %A) -> (tensor<128xf32>) { + // CHECK-DAG: [[ASLICE:%.*]] = vector.transfer_read [[A]][[[IV]]], [[ZERO]] + // CHECK-DAG: [[SLICE0:%.*]] = vector.transfer_read [[IA]][[[IV]]], [[ZERO]] + // CHECK: [[OUT1:%.*]] = arith.addf [[SLICE0]], [[ASLICE]] + // CHECK-NEXT: [[WRT0:%.*]] = vector.transfer_write [[OUT1]], [[IA]][[[IV]]] + %2 = vector.transfer_read %A[%arg3], %cst {in_bounds = [true]} : tensor<128xf32>, vector<16xf32> + %3 = vector.transfer_read %arg4[%arg3], %cst {in_bounds = [true]} : tensor<128xf32>, vector<16xf32> + %5 = arith.addf %3, %2 : vector<16xf32> + %6 = vector.transfer_write %5, %arg4[%arg3] {in_bounds = [true]} : vector<16xf32>, tensor<128xf32> + scf.yield %6 : tensor<128xf32> + } + %dup1 = scf.for %arg3 = %c0 to %c128 step %c16 iter_args(%arg4 = %B) -> (tensor<128xf32>) { + // CHECK-DAG: [[SLICE1:%.*]] = vector.transfer_read [[IB]][[[IV]]], [[ZERO]] + // CHECK: [[OUT2:%.*]] = arith.addf [[SLICE1]], [[ASLICE]] + // CHECK-NEXT: [[WRT1:%.*]] = vector.transfer_write [[OUT2]], [[IB]][[[IV]]] + %dup2 = vector.transfer_read %A[%arg3], %cst {in_bounds = [true]} : tensor<128xf32>, vector<16xf32> + %dup3 = vector.transfer_read %arg4[%arg3], %cst {in_bounds = [true]} : tensor<128xf32>, vector<16xf32> + %dup5 = arith.addf %dup3, %dup2 : vector<16xf32> + %dup6 = vector.transfer_write %dup5, %arg4[%arg3] {in_bounds = [true]} : vector<16xf32>, tensor<128xf32> + // CHECK: scf.yield [[WRT0]], [[WRT1]] : {{.*}} + scf.yield %dup6 : tensor<128xf32> + } + return %1, %dup1 : tensor<128xf32>, tensor<128xf32> +} +module attributes {transform.with_named_sequence} { + transform.named_sequence @__transform_main(%arg0: !transform.any_op {transform.readonly}) { + %0 = transform.structured.match ops{["scf.for"]} in %arg0 : (!transform.any_op) -> !transform.any_op + %for:2 = transform.split_handle %0 : (!transform.any_op) -> (!transform.any_op, !transform.any_op) + %fused = transform.loop.fuse_sibling %for#0 into %for#1 : (!transform.any_op,!transform.any_op) -> !transform.any_op + transform.yield + } +} + +// ----- + +// CHECK: func.func @fuse_2nd_for_into_1st([[A:%.*]]: {{.*}}, [[B:%.*]]: {{.*}} +func.func @fuse_2nd_for_into_1st(%A: tensor<128xf32>, %B: tensor<128xf32>) -> (tensor<128xf32>, tensor<128xf32>) { + // CHECK-DAG: [[C0:%.*]] = arith.constant 0 : index + // CHECK-DAG: [[C16:%.*]] = arith.constant 16 : index + // CHECK-DAG: [[C128:%.*]] = arith.constant 128 : index + // CHECK-DAG: [[ZERO:%.*]] = arith.constant 0.000000e+00 : f32 + %c0 = arith.constant 0 : index + %c16 = arith.constant 16 : index + %c128 = arith.constant 128 : index + %cst = arith.constant 0.000000e+00 : f32 + // CHECK: [[R0:%.*]]:2 = scf.for [[IV:%.*]] = [[C0]] to [[C128]] step [[C16]] iter_args([[IB:%.*]] = [[B]], [[IA:%.*]] = [[A]]) {{.*}} + %1 = scf.for %arg3 = %c0 to %c128 step %c16 iter_args(%arg4 = %A) -> (tensor<128xf32>) { + // CHECK-DAG: [[ASLICE:%.*]] = vector.transfer_read [[A]][[[IV]]], [[ZERO]] + // CHECK-DAG: [[SLICE0:%.*]] = vector.transfer_read [[IB]][[[IV]]], [[ZERO]] + // CHECK: [[OUT1:%.*]] = arith.addf [[SLICE0]], [[ASLICE]] + // CHECK-NEXT: [[WRT0:%.*]] = vector.transfer_write [[OUT1]], [[IB]][[[IV]]] + %2 = vector.transfer_read %A[%arg3], %cst {in_bounds = [true]} : tensor<128xf32>, vector<16xf32> + %3 = vector.transfer_read %arg4[%arg3], %cst {in_bounds = [true]} : tensor<128xf32>, vector<16xf32> + %5 = arith.addf %3, %2 : vector<16xf32> + %6 = vector.transfer_write %5, %arg4[%arg3] {in_bounds = [true]} : vector<16xf32>, tensor<128xf32> + scf.yield %6 : tensor<128xf32> + } + %dup1 = scf.for %arg3 = %c0 to %c128 step %c16 iter_args(%arg4 = %B) -> (tensor<128xf32>) { + // CHECK-DAG: [[SLICE1:%.*]] = vector.transfer_read [[IA]][[[IV]]], [[ZERO]] + // CHECK: [[OUT2:%.*]] = arith.addf [[SLICE1]], [[ASLICE]] + // CHECK-NEXT: [[WRT1:%.*]] = vector.transfer_write [[OUT2]], [[IA]][[[IV]]] + %dup2 = vector.transfer_read %A[%arg3], %cst {in_bounds = [true]} : tensor<128xf32>, vector<16xf32> + // NB: the dominance check used to fail on the following line, + // however the defining op for the value of %arg3 occurs above the source loop and hence is safe + // and %arg4 is a block argument of the scope of the loops and hence is safe + %dup3 = vector.transfer_read %arg4[%arg3], %cst {in_bounds = [true]} : tensor<128xf32>, vector<16xf32> + %dup5 = arith.addf %dup3, %dup2 : vector<16xf32> + %dup6 = vector.transfer_write %dup5, %arg4[%arg3] {in_bounds = [true]} : vector<16xf32>, tensor<128xf32> + // CHECK: scf.yield [[WRT0]], [[WRT1]] : {{.*}} + scf.yield %dup6 : tensor<128xf32> + } + return %1, %dup1 : tensor<128xf32>, tensor<128xf32> +} +module attributes {transform.with_named_sequence} { + transform.named_sequence @__transform_main(%arg0: !transform.any_op {transform.readonly}) { + %0 = transform.structured.match ops{["scf.for"]} in %arg0 : (!transform.any_op) -> !transform.any_op + %for:2 = transform.split_handle %0 : (!transform.any_op) -> (!transform.any_op, !transform.any_op) + %fused = transform.loop.fuse_sibling %for#1 into %for#0 : (!transform.any_op,!transform.any_op) -> !transform.any_op + transform.yield + } +} + +// ----- + +// CHECK: func.func @matmul_fuse_1st_forall_into_2nd([[A1:%.*]]: {{.*}}, [[A2:%.*]]: {{.*}}, [[B:%.*]]: {{.*}} +func.func @matmul_fuse_1st_forall_into_2nd(%A1 : tensor<128x128xf32>, %A2 : tensor<128x128xf32>, %B : tensor<128x128xf32>) -> (tensor<128x128xf32>, tensor<128x128xf32>) { %zero = arith.constant 0.0 : f32 %out_alloc = tensor.empty() : tensor<128x128xf32> %out = linalg.fill ins(%zero : f32) outs(%out_alloc : tensor<128x128xf32>) -> tensor<128x128xf32> // CHECK: scf.forall ([[I:%.*]]) in (4) shared_outs([[S1:%.*]] = [[IN1:%.*]], [[S2:%.*]] = [[IN2:%.*]]) -> (tensor<128x128xf32>, tensor<128x128xf32>) { // CHECK: [[T:%.*]] = affine.apply + // CHECK: tensor.extract_slice [[A2]][[[T]], 0] [32, 128] [1, 1] // CHECK: tensor.extract_slice [[S1]][[[T]], 0] [32, 128] [1, 1] // CHECK: [[OUT1:%.*]] = linalg.matmul + // CHECK: tensor.extract_slice [[A1]][[[T]], 0] [32, 128] [1, 1] // CHECK: tensor.extract_slice [[S2]][[[T]], 0] [32, 128] [1, 1] // CHECK: [[OUT2:%.*]] = linalg.matmul // CHECK: scf.forall.in_parallel { @@ -16,12 +115,11 @@ func.func @test(%A : tensor<128x128xf32>, %B1 : tensor<128x128xf32>, %B2 : tenso // CHECK: tensor.parallel_insert_slice [[OUT2]] into [[S2]][[[T]], 0] [32, 128] [1, 1] // CHECK: } // CHECK: } - %out1 = linalg.matmul ins(%A, %B1 : tensor<128x128xf32>, tensor<128x128xf32>) outs(%out : tensor<128x128xf32>) -> tensor<128x128xf32> - %out2 = linalg.matmul ins(%A, %B2 : tensor<128x128xf32>, tensor<128x128xf32>) outs(%out : tensor<128x128xf32>) -> tensor<128x128xf32> + %out1 = linalg.matmul ins(%A1, %B : tensor<128x128xf32>, tensor<128x128xf32>) outs(%out : tensor<128x128xf32>) -> tensor<128x128xf32> + %out2 = linalg.matmul ins(%A2, %B : tensor<128x128xf32>, tensor<128x128xf32>) outs(%out : tensor<128x128xf32>) -> tensor<128x128xf32> func.return %out1, %out2 : tensor<128x128xf32>, tensor<128x128xf32> } - module attributes {transform.with_named_sequence} { transform.named_sequence @__transform_main(%variant_op : !transform.any_op {transform.readonly}) { %matched = transform.structured.match ops{["linalg.matmul"]} in %variant_op : (!transform.any_op) -> (!transform.any_op) @@ -31,25 +129,37 @@ module attributes {transform.with_named_sequence} { %tiled_mm1, %loop1 = transform.structured.tile_using_forall %mm1 tile_sizes [32] : (!transform.any_op) -> (!transform.any_op, !transform.any_op) %tiled_mm2, %loop2 = transform.structured.tile_using_forall %mm2 tile_sizes [32] : (!transform.any_op) -> (!transform.any_op, !transform.any_op) - %fused_loop = transform.loop.fuse_sibling %loop1 into %loop2 : (!transform.any_op, !transform.any_op) -> !transform.any_op + %fused_loop = transform.loop.fuse_sibling %loop2 into %loop1 : (!transform.any_op, !transform.any_op) -> !transform.any_op transform.yield } } // ----- -func.func @test(%A : tensor<128x128xf32>, %B1 : tensor<128x128xf32>, %B2 : tensor<128x128xf32>) -> (tensor<128x128xf32>, tensor<128x128xf32>) { +// CHECK: func.func @matmul_fuse_2nd_forall_into_1st([[A1:%.*]]: {{.*}}, [[A2:%.*]]: {{.*}}, [[B:%.*]]: {{.*}} +func.func @matmul_fuse_2nd_forall_into_1st(%A1 : tensor<128x128xf32>, %A2 : tensor<128x128xf32>, %B : tensor<128x128xf32>) -> (tensor<128x128xf32>, tensor<128x128xf32>) { %zero = arith.constant 0.0 : f32 %out_alloc = tensor.empty() : tensor<128x128xf32> %out = linalg.fill ins(%zero : f32) outs(%out_alloc : tensor<128x128xf32>) -> tensor<128x128xf32> - // expected-error @below {{user of results of target should be properly dominated by source}} - %out1 = linalg.matmul ins(%A, %B1 : tensor<128x128xf32>, tensor<128x128xf32>) outs(%out : tensor<128x128xf32>) -> tensor<128x128xf32> - %out2 = linalg.matmul ins(%A, %out1 : tensor<128x128xf32>, tensor<128x128xf32>) outs(%out : tensor<128x128xf32>) -> tensor<128x128xf32> + // CHECK: scf.forall ([[I:%.*]]) in (4) shared_outs([[S1:%.*]] = [[IN1:%.*]], [[S2:%.*]] = [[IN2:%.*]]) -> (tensor<128x128xf32>, tensor<128x128xf32>) { + // CHECK: [[T:%.*]] = affine.apply + // CHECK: tensor.extract_slice [[A1]][[[T]], 0] [32, 128] [1, 1] + // CHECK: tensor.extract_slice [[S1]][[[T]], 0] [32, 128] [1, 1] + // CHECK: [[OUT1:%.*]] = linalg.matmul + // CHECK: tensor.extract_slice [[A2]][[[T]], 0] [32, 128] [1, 1] + // CHECK: tensor.extract_slice [[S2]][[[T]], 0] [32, 128] [1, 1] + // CHECK: [[OUT2:%.*]] = linalg.matmul + // CHECK: scf.forall.in_parallel { + // CHECK: tensor.parallel_insert_slice [[OUT1]] into [[S1]][[[T]], 0] [32, 128] [1, 1] + // CHECK: tensor.parallel_insert_slice [[OUT2]] into [[S2]][[[T]], 0] [32, 128] [1, 1] + // CHECK: } + // CHECK: } + %out1 = linalg.matmul ins(%A1, %B : tensor<128x128xf32>, tensor<128x128xf32>) outs(%out : tensor<128x128xf32>) -> tensor<128x128xf32> + %out2 = linalg.matmul ins(%A2, %B : tensor<128x128xf32>, tensor<128x128xf32>) outs(%out : tensor<128x128xf32>) -> tensor<128x128xf32> func.return %out1, %out2 : tensor<128x128xf32>, tensor<128x128xf32> } - module attributes {transform.with_named_sequence} { transform.named_sequence @__transform_main(%variant_op : !transform.any_op {transform.readonly}) { %matched = transform.structured.match ops{["linalg.matmul"]} in %variant_op : (!transform.any_op) -> (!transform.any_op) @@ -66,18 +176,84 @@ module attributes {transform.with_named_sequence} { // ----- -func.func @test(%A : tensor<128x128xf32>, %B1 : tensor<128x128xf32>, %B2 : tensor<128x128xf32>) -> (tensor<128x128xf32>, tensor<128x128xf32>) { +// CHECK-NOCLEANUP: func.func @fuse_no_iter_args([[A:%.*]]: {{.*}}, [[B:%.*]]: {{.*}} +func.func @fuse_no_iter_args(%A: tensor<128xf32>, %B: tensor<128xf32>) { + // CHECK-NOCLEANUP: [[C0:%.*]] = arith.constant 0 : index + // CHECK-NOCLEANUP: [[C16:%.*]] = arith.constant 16 : index + // CHECK-NOCLEANUP: [[C128:%.*]] = arith.constant 128 : index + // CHECK-NOCLEANUP: [[ZERO:%.*]] = arith.constant 0.000000e+00 : f32 + %c0 = arith.constant 0 : index + %c16 = arith.constant 16 : index + %c128 = arith.constant 128 : index + %cst = arith.constant 0.000000e+00 : f32 + // CHECK-NOCLEANUP: scf.for [[IV:%.*]] = [[C0]] to [[C128]] step [[C16]] {{.*}} + scf.for %arg0 = %c0 to %c128 step %c16 { + // CHECK-NOCLEANUP: [[ASLICE:%.*]] = vector.transfer_read [[A]][[[IV]]], [[ZERO]] + %2 = vector.transfer_read %A[%arg0], %cst {in_bounds = [true]} : tensor<128xf32>, vector<16xf32> + scf.yield + } + scf.for %arg0 = %c0 to %c128 step %c16 { + // CHECK-NOCLEANUP: [[BSLICE:%.*]] = vector.transfer_read [[B]][[[IV]]], [[ZERO]] + %dup2 = vector.transfer_read %B[%arg0], %cst {in_bounds = [true]} : tensor<128xf32>, vector<16xf32> + scf.yield + } + return +} +module attributes {transform.with_named_sequence} { + transform.named_sequence @__transform_main(%arg0: !transform.any_op {transform.readonly}) { + %0 = transform.structured.match ops{["scf.for"]} in %arg0 : (!transform.any_op) -> !transform.any_op + %for:2 = transform.split_handle %0 : (!transform.any_op) -> (!transform.any_op, !transform.any_op) + %fused = transform.loop.fuse_sibling %for#0 into %for#1 : (!transform.any_op,!transform.any_op) -> !transform.any_op + transform.yield + } +} + +// ----- + +func.func @source_for_uses_result_of_target_for_err(%A: tensor<128xf32>, %B: tensor<128xf32>) -> (tensor<128xf32>, tensor<128xf32>) { + %c0 = arith.constant 0 : index + %c16 = arith.constant 16 : index + %c128 = arith.constant 128 : index + %cst = arith.constant 0.000000e+00 : f32 + // expected-error @below {{user of results of target should be properly dominated by source}} + %1 = scf.for %arg3 = %c0 to %c128 step %c16 iter_args(%arg4 = %A) -> (tensor<128xf32>) { + %2 = vector.transfer_read %A[%arg3], %cst {in_bounds = [true]} : tensor<128xf32>, vector<16xf32> + %3 = vector.transfer_read %arg4[%arg3], %cst {in_bounds = [true]} : tensor<128xf32>, vector<16xf32> + %5 = arith.addf %3, %2 : vector<16xf32> + %6 = vector.transfer_write %5, %arg4[%arg3] {in_bounds = [true]} : vector<16xf32>, tensor<128xf32> + scf.yield %6 : tensor<128xf32> + } + %dup1 = scf.for %arg3 = %c0 to %c128 step %c16 iter_args(%arg4 = %1) -> (tensor<128xf32>) { + %dup2 = vector.transfer_read %A[%arg3], %cst {in_bounds = [true]} : tensor<128xf32>, vector<16xf32> + %dup3 = vector.transfer_read %arg4[%arg3], %cst {in_bounds = [true]} : tensor<128xf32>, vector<16xf32> + %dup5 = arith.addf %dup3, %dup2 : vector<16xf32> + %dup6 = vector.transfer_write %dup5, %arg4[%arg3] {in_bounds = [true]} : vector<16xf32>, tensor<128xf32> + scf.yield %dup6 : tensor<128xf32> + } + return %1, %dup1 : tensor<128xf32>, tensor<128xf32> +} +module attributes {transform.with_named_sequence} { + transform.named_sequence @__transform_main(%arg0: !transform.any_op {transform.readonly}) { + %0 = transform.structured.match ops{["scf.for"]} in %arg0 : (!transform.any_op) -> !transform.any_op + %for:2 = transform.split_handle %0 : (!transform.any_op) -> (!transform.any_op, !transform.any_op) + %fused = transform.loop.fuse_sibling %for#0 into %for#1 : (!transform.any_op,!transform.any_op) -> !transform.any_op + transform.yield + } +} + +// ----- + +func.func @source_forall_uses_result_of_target_forall_err(%A : tensor<128x128xf32>, %B1 : tensor<128x128xf32>, %B2 : tensor<128x128xf32>) -> (tensor<128x128xf32>, tensor<128x128xf32>) { %zero = arith.constant 0.0 : f32 %out_alloc = tensor.empty() : tensor<128x128xf32> %out = linalg.fill ins(%zero : f32) outs(%out_alloc : tensor<128x128xf32>) -> tensor<128x128xf32> + // expected-error @below {{user of results of target should be properly dominated by source}} %out1 = linalg.matmul ins(%A, %B1 : tensor<128x128xf32>, tensor<128x128xf32>) outs(%out : tensor<128x128xf32>) -> tensor<128x128xf32> - // expected-error @below {{values used inside regions of target should be properly dominated by source}} %out2 = linalg.matmul ins(%A, %out1 : tensor<128x128xf32>, tensor<128x128xf32>) outs(%out : tensor<128x128xf32>) -> tensor<128x128xf32> func.return %out1, %out2 : tensor<128x128xf32>, tensor<128x128xf32> } - module attributes {transform.with_named_sequence} { transform.named_sequence @__transform_main(%variant_op : !transform.any_op {transform.readonly}) { %matched = transform.structured.match ops{["linalg.matmul"]} in %variant_op : (!transform.any_op) -> (!transform.any_op) @@ -87,25 +263,58 @@ module attributes {transform.with_named_sequence} { %tiled_mm1, %loop1 = transform.structured.tile_using_forall %mm1 tile_sizes [32] : (!transform.any_op) -> (!transform.any_op, !transform.any_op) %tiled_mm2, %loop2 = transform.structured.tile_using_forall %mm2 tile_sizes [32] : (!transform.any_op) -> (!transform.any_op, !transform.any_op) - %fused_loop = transform.loop.fuse_sibling %loop2 into %loop1 : (!transform.any_op, !transform.any_op) -> !transform.any_op + %fused_loop = transform.loop.fuse_sibling %loop1 into %loop2 : (!transform.any_op, !transform.any_op) -> !transform.any_op transform.yield } } // ----- -func.func @test(%A : tensor<128x128xf32>, %B1 : tensor<128x128xf32>, %B2 : tensor<128x128xf32>) -> (tensor<128x128xf32>, tensor<128x128xf32>) { - %zero = arith.constant 0.0 : f32 - %out_alloc = tensor.empty() : tensor<128x128xf32> - %out = linalg.fill ins(%zero : f32) outs(%out_alloc : tensor<128x128xf32>) -> tensor<128x128xf32> +func.func @target_for_region_uses_result_of_source_for_err(%A: tensor<128xf32>, %B: tensor<128xf32>) -> (tensor<128xf32>, tensor<128xf32>) { + %c0 = arith.constant 0 : index + %c16 = arith.constant 16 : index + %c128 = arith.constant 128 : index + %cst = arith.constant 0.000000e+00 : f32 + %1 = scf.for %arg3 = %c0 to %c128 step %c16 iter_args(%arg4 = %A) -> (tensor<128xf32>) { + %2 = vector.transfer_read %A[%arg3], %cst {in_bounds = [true]} : tensor<128xf32>, vector<16xf32> + %3 = vector.transfer_read %arg4[%arg3], %cst {in_bounds = [true]} : tensor<128xf32>, vector<16xf32> + %5 = arith.addf %3, %2 : vector<16xf32> + %6 = vector.transfer_write %5, %arg4[%arg3] {in_bounds = [true]} : vector<16xf32>, tensor<128xf32> + scf.yield %6 : tensor<128xf32> + } + %dup1 = scf.for %arg3 = %c0 to %c128 step %c16 iter_args(%arg4 = %B) -> (tensor<128xf32>) { + // expected-error @below {{values used inside regions of target should be properly dominated by source}} + %dup2 = vector.transfer_read %1[%arg3], %cst {in_bounds = [true]} : tensor<128xf32>, vector<16xf32> + %dup3 = vector.transfer_read %arg4[%arg3], %cst {in_bounds = [true]} : tensor<128xf32>, vector<16xf32> + %dup5 = arith.addf %dup3, %dup2 : vector<16xf32> + %dup6 = vector.transfer_write %dup5, %arg4[%arg3] {in_bounds = [true]} : vector<16xf32>, tensor<128xf32> + scf.yield %dup6 : tensor<128xf32> + } + return %1, %dup1 : tensor<128xf32>, tensor<128xf32> +} +module attributes {transform.with_named_sequence} { + transform.named_sequence @__transform_main(%arg0: !transform.any_op {transform.readonly}) { + %0 = transform.structured.match ops{["scf.for"]} in %arg0 : (!transform.any_op) -> !transform.any_op + %for:2 = transform.split_handle %0 : (!transform.any_op) -> (!transform.any_op, !transform.any_op) + %fused = transform.loop.fuse_sibling %for#1 into %for#0 : (!transform.any_op,!transform.any_op) -> !transform.any_op + transform.yield + } +} - %out1 = linalg.matmul ins(%A, %B1 : tensor<128x128xf32>, tensor<128x128xf32>) outs(%out : tensor<128x128xf32>) -> tensor<128x128xf32> +// ----- + +func.func @target_forall_depends_on_value_not_dominated_by_source_forall_err(%A1 : tensor<128x128xf32>, %A2 : tensor<128x128xf32>, %B : tensor<128x128xf32>) -> (tensor<128x128xf32>, tensor<128x128xf32>) { + %zero = arith.constant 0.0 : f32 + %buf1_alloc = tensor.empty() : tensor<128x128xf32> + %buf1 = linalg.fill ins(%zero : f32) outs(%buf1_alloc : tensor<128x128xf32>) -> tensor<128x128xf32> + %out1 = linalg.matmul ins(%A1, %B : tensor<128x128xf32>, tensor<128x128xf32>) outs(%buf1 : tensor<128x128xf32>) -> tensor<128x128xf32> + %out_alloc2 = tensor.empty() : tensor<128x128xf32> + %buf2 = linalg.fill ins(%zero : f32) outs(%buf1_alloc : tensor<128x128xf32>) -> tensor<128x128xf32> // expected-error @below {{operands of target should be properly dominated by source}} - %out2 = linalg.matmul ins(%A, %B2 : tensor<128x128xf32>, tensor<128x128xf32>) outs(%out1 : tensor<128x128xf32>) -> tensor<128x128xf32> + %out2 = linalg.matmul ins(%A2, %B : tensor<128x128xf32>, tensor<128x128xf32>) outs(%buf2 : tensor<128x128xf32>) -> tensor<128x128xf32> func.return %out1, %out2 : tensor<128x128xf32>, tensor<128x128xf32> } - module attributes {transform.with_named_sequence} { transform.named_sequence @__transform_main(%variant_op : !transform.any_op {transform.readonly}) { %matched = transform.structured.match ops{["linalg.matmul"]} in %variant_op : (!transform.any_op) -> (!transform.any_op) -- GitLab From a3efc53f168b1451803a40075201c3490d6e3928 Mon Sep 17 00:00:00 2001 From: Amy Kwan Date: Thu, 28 Mar 2024 09:18:45 -0400 Subject: [PATCH 057/788] [AIX][TLS] Produce a faster local-exec access sequence for the "aix-small-tls" global variable attribute (#83053) Similar to 3f46e5453d9310b15d974e876f6132e3cf50c4b1, this patch allows the backend to produce a faster access sequence for the local-exec TLS model, where loading from the TOC can be avoided, for local-exec TLS variables that are annotated with the "aix-small-tls" attribute. The expectation is for local-exec TLS variables to be set with this attribute through PGO. Furthermore, the optimized access sequence is only generated for local-exec TLS variables annotated with "aix-small-tls", only if they are less than ~32KB in size. --- llvm/lib/Target/PowerPC/PPCISelDAGToDAG.cpp | 28 ++- llvm/lib/Target/PowerPC/PPCISelLowering.cpp | 23 +- .../aix-small-tls-globalvarattr-funcattr.ll | 105 +++++++++ .../aix-small-tls-globalvarattr-loadaddr.ll | 222 ++++++++++++++++++ .../aix-small-tls-globalvarattr-targetattr.ll | 53 +++++ 5 files changed, 416 insertions(+), 15 deletions(-) create mode 100644 llvm/test/CodeGen/PowerPC/aix-small-tls-globalvarattr-funcattr.ll create mode 100644 llvm/test/CodeGen/PowerPC/aix-small-tls-globalvarattr-loadaddr.ll create mode 100644 llvm/test/CodeGen/PowerPC/aix-small-tls-globalvarattr-targetattr.ll diff --git a/llvm/lib/Target/PowerPC/PPCISelDAGToDAG.cpp b/llvm/lib/Target/PowerPC/PPCISelDAGToDAG.cpp index dfea9e770924..af82b6cdb180 100644 --- a/llvm/lib/Target/PowerPC/PPCISelDAGToDAG.cpp +++ b/llvm/lib/Target/PowerPC/PPCISelDAGToDAG.cpp @@ -7558,6 +7558,16 @@ static void reduceVSXSwap(SDNode *N, SelectionDAG *DAG) { DAG->ReplaceAllUsesOfValueWith(SDValue(N, 0), N->getOperand(0)); } +// Check if an SDValue has the 'aix-small-tls' global variable attribute. +static bool hasAIXSmallTLSAttr(SDValue Val) { + if (GlobalAddressSDNode *GA = dyn_cast(Val)) + if (const GlobalVariable *GV = dyn_cast(GA->getGlobal())) + if (GV->hasAttribute("aix-small-tls")) + return true; + + return false; +} + // Is an ADDI eligible for folding for non-TOC-based local-exec accesses? static bool isEligibleToFoldADDIForLocalExecAccesses(SelectionDAG *DAG, SDValue ADDIToFold) { @@ -7567,20 +7577,25 @@ static bool isEligibleToFoldADDIForLocalExecAccesses(SelectionDAG *DAG, (ADDIToFold.getMachineOpcode() != PPC::ADDI8)) return false; + // Folding is only allowed for the AIX small-local-exec TLS target attribute + // or when the 'aix-small-tls' global variable attribute is present. + const PPCSubtarget &Subtarget = + DAG->getMachineFunction().getSubtarget(); + SDValue TLSVarNode = ADDIToFold.getOperand(1); + if (!(Subtarget.hasAIXSmallLocalExecTLS() || hasAIXSmallTLSAttr(TLSVarNode))) + return false; + // The first operand of the ADDIToFold should be the thread pointer. // This transformation is only performed if the first operand of the // addi is the thread pointer. SDValue TPRegNode = ADDIToFold.getOperand(0); RegisterSDNode *TPReg = dyn_cast(TPRegNode.getNode()); - const PPCSubtarget &Subtarget = - DAG->getMachineFunction().getSubtarget(); if (!TPReg || (TPReg->getReg() != Subtarget.getThreadPointerRegister())) return false; // The second operand of the ADDIToFold should be the global TLS address // (the local-exec TLS variable). We only perform the folding if the TLS // variable is the second operand. - SDValue TLSVarNode = ADDIToFold.getOperand(1); GlobalAddressSDNode *GA = dyn_cast(TLSVarNode); if (!GA) return false; @@ -7649,7 +7664,6 @@ static void foldADDIForLocalExecAccesses(SDNode *N, SelectionDAG *DAG) { void PPCDAGToDAGISel::PeepholePPC64() { SelectionDAG::allnodes_iterator Position = CurDAG->allnodes_end(); - bool HasAIXSmallLocalExecTLS = Subtarget->hasAIXSmallLocalExecTLS(); while (Position != CurDAG->allnodes_begin()) { SDNode *N = &*--Position; @@ -7661,8 +7675,7 @@ void PPCDAGToDAGISel::PeepholePPC64() { reduceVSXSwap(N, CurDAG); // This optimization is performed for non-TOC-based local-exec accesses. - if (HasAIXSmallLocalExecTLS) - foldADDIForLocalExecAccesses(N, CurDAG); + foldADDIForLocalExecAccesses(N, CurDAG); unsigned FirstOp; unsigned StorageOpcode = N->getMachineOpcode(); @@ -7821,8 +7834,7 @@ void PPCDAGToDAGISel::PeepholePPC64() { ImmOpnd.getValueType()); } else if (Offset != 0) { // This optimization is performed for non-TOC-based local-exec accesses. - if (HasAIXSmallLocalExecTLS && - isEligibleToFoldADDIForLocalExecAccesses(CurDAG, Base)) { + if (isEligibleToFoldADDIForLocalExecAccesses(CurDAG, Base)) { // Add the non-zero offset information into the load or store // instruction to be used for non-TOC-based local-exec accesses. GlobalAddressSDNode *GA = dyn_cast(ImmOpnd); diff --git a/llvm/lib/Target/PowerPC/PPCISelLowering.cpp b/llvm/lib/Target/PowerPC/PPCISelLowering.cpp index cce0efad39c7..7436b202fba0 100644 --- a/llvm/lib/Target/PowerPC/PPCISelLowering.cpp +++ b/llvm/lib/Target/PowerPC/PPCISelLowering.cpp @@ -3367,15 +3367,21 @@ SDValue PPCTargetLowering::LowerGlobalTLSAddressAIX(SDValue Op, const GlobalValue *GV = GA->getGlobal(); EVT PtrVT = getPointerTy(DAG.getDataLayout()); bool Is64Bit = Subtarget.isPPC64(); - bool HasAIXSmallLocalExecTLS = Subtarget.hasAIXSmallLocalExecTLS(); TLSModel::Model Model = getTargetMachine().getTLSModel(GV); bool IsTLSLocalExecModel = Model == TLSModel::LocalExec; if (IsTLSLocalExecModel || Model == TLSModel::InitialExec) { + bool HasAIXSmallLocalExecTLS = Subtarget.hasAIXSmallLocalExecTLS(); + bool HasAIXSmallTLSGlobalAttr = false; SDValue VariableOffsetTGA = DAG.getTargetGlobalAddress(GV, dl, PtrVT, 0, PPCII::MO_TPREL_FLAG); SDValue VariableOffset = getTOCEntry(DAG, dl, VariableOffsetTGA); SDValue TLSReg; + + if (const GlobalVariable *GVar = dyn_cast(GV)) + if (GVar->hasAttribute("aix-small-tls")) + HasAIXSmallTLSGlobalAttr = true; + if (Is64Bit) { // For local-exec and initial-exec on AIX (64-bit), the sequence generated // involves a load of the variable offset (from the TOC), followed by an @@ -3385,14 +3391,16 @@ SDValue PPCTargetLowering::LowerGlobalTLSAddressAIX(SDValue Op, // add reg2, reg1, r13 // r13 contains the thread pointer TLSReg = DAG.getRegister(PPC::X13, MVT::i64); - // With the -maix-small-local-exec-tls option, produce a faster access - // sequence for local-exec TLS variables where the offset from the TLS - // base is encoded as an immediate operand. + // With the -maix-small-local-exec-tls option, or with the "aix-small-tls" + // global variable attribute, produce a faster access sequence for + // local-exec TLS variables where the offset from the TLS base is encoded + // as an immediate operand. // // We only utilize the faster local-exec access sequence when the TLS // variable has a size within the policy limit. We treat types that are // not sized or are empty as being over the policy size limit. - if (HasAIXSmallLocalExecTLS && IsTLSLocalExecModel) { + if ((HasAIXSmallLocalExecTLS || HasAIXSmallTLSGlobalAttr) && + IsTLSLocalExecModel) { Type *GVType = GV->getValueType(); if (GVType->isSized() && !GVType->isEmptyTy() && GV->getParent()->getDataLayout().getTypeAllocSize(GVType) <= @@ -3410,8 +3418,9 @@ SDValue PPCTargetLowering::LowerGlobalTLSAddressAIX(SDValue Op, TLSReg = DAG.getNode(PPCISD::GET_TPOINTER, dl, PtrVT); // We do not implement the 32-bit version of the faster access sequence - // for local-exec that is controlled by -maix-small-local-exec-tls. - if (HasAIXSmallLocalExecTLS) + // for local-exec that is controlled by the -maix-small-local-exec-tls + // option, or the "aix-small-tls" global variable attribute. + if (HasAIXSmallLocalExecTLS || HasAIXSmallTLSGlobalAttr) report_fatal_error("The small-local-exec TLS access sequence is " "currently only supported on AIX (64-bit mode)."); } diff --git a/llvm/test/CodeGen/PowerPC/aix-small-tls-globalvarattr-funcattr.ll b/llvm/test/CodeGen/PowerPC/aix-small-tls-globalvarattr-funcattr.ll new file mode 100644 index 000000000000..38b35dc6c81c --- /dev/null +++ b/llvm/test/CodeGen/PowerPC/aix-small-tls-globalvarattr-funcattr.ll @@ -0,0 +1,105 @@ +; RUN: llc -verify-machineinstrs -mcpu=pwr7 -ppc-asm-full-reg-names \ +; RUN: -mtriple powerpc64-ibm-aix-xcoff < %s \ +; RUN: | FileCheck %s --check-prefixes=COMMONCM,CHECK-SMALLCM64 +; RUN: llc -verify-machineinstrs -mcpu=pwr7 -ppc-asm-full-reg-names \ +; RUN: -mtriple powerpc64-ibm-aix-xcoff --code-model=large \ +; RUN: < %s | FileCheck %s --check-prefixes=COMMONCM,CHECK-LARGECM64 + +@mySmallTLS = thread_local(localexec) global [7800 x i64] zeroinitializer, align 8 #0 +@mySmallTLS2 = thread_local(localexec) global [3000 x i64] zeroinitializer, align 8 #0 +@mySmallTLS3 = thread_local(localexec) global [3000 x i64] zeroinitializer, align 8 +declare nonnull ptr @llvm.threadlocal.address.p0(ptr nonnull) + +; All accesses use a "faster" local-exec sequence directly off the thread pointer, +; except for mySmallTLS, as this variable is over the 32KB size limit. +define i64 @StoreLargeAccess1() #1 { +; COMMONCM-LABEL: StoreLargeAccess1: +; COMMONCM-NEXT: # %bb.0: # %entry +; CHECK-SMALLCM64: ld r3, L..C0(r2) # target-flags(ppc-tprel) @mySmallTLS +; CHECK-SMALLCM64-NEXT: li r4, 0 +; CHECK-SMALLCM64-NEXT: li r5, 23 +; CHECK-LARGECM64: addis r3, L..C0@u(r2) +; CHECK-LARGECM64-NEXT: li r4, 0 +; CHECK-LARGECM64-NEXT: li r5, 23 +; CHECK-LARGECM64-NEXT: ld r3, L..C0@l(r3) +; COMMONCM: ori r4, r4, 53328 +; COMMONCM-NEXT: add r3, r13, r3 +; COMMONCM-NEXT: stdx r5, r3, r4 +; COMMONCM-NEXT: li r3, 55 +; COMMONCM-NEXT: li r4, 64 +; COMMONCM-NEXT: std r3, (mySmallTLS2[TL]@le+696)-65536(r13) +; COMMONCM-NEXT: li r3, 142 +; COMMONCM-NEXT: std r4, (mySmallTLS3[TL]@le+20000)-131072(r13) +; COMMONCM-NEXT: blr +entry: + %tls0 = tail call align 8 ptr @llvm.threadlocal.address.p0(ptr align 8 @mySmallTLS) + %arrayidx = getelementptr inbounds i8, ptr %tls0, i32 53328 + store i64 23, ptr %arrayidx, align 8 + %tls1 = tail call align 8 ptr @llvm.threadlocal.address.p0(ptr align 8 @mySmallTLS2) + %arrayidx1 = getelementptr inbounds i8, ptr %tls1, i32 696 + store i64 55, ptr %arrayidx1, align 8 + %tls2 = tail call align 8 ptr @llvm.threadlocal.address.p0(ptr align 8 @mySmallTLS3) + %arrayidx2 = getelementptr inbounds i8, ptr %tls2, i32 20000 + store i64 64, ptr %arrayidx2, align 8 + %load1 = load i64, ptr %arrayidx, align 8 + %load2 = load i64, ptr %arrayidx1, align 8 + %add1 = add i64 %load1, 64 + %add2 = add i64 %add1, %load2 + ret i64 %add2 +} + +; Since this function does not have the 'aix-small-local-exec-tls` attribute, +; only some local-exec variables should have the small-local-exec TLS access +; sequence (as opposed to all of them). +define i64 @StoreLargeAccess2() { +; COMMONCM-LABEL: StoreLargeAccess2: +; COMMONCM-NEXT: # %bb.0: # %entry +; CHECK-SMALLCM64: ld r5, L..C0(r2) # target-flags(ppc-tprel) @mySmallTLS +; CHECK-SMALLCM64-NEXT: li r3, 0 +; CHECK-SMALLCM64-NEXT: li r4, 23 +; CHECK-SMALLCM64-NEXT: ori r3, r3, 53328 +; CHECK-SMALLCM64-NEXT: add r5, r13, r5 +; CHECK-SMALLCM64-NEXT: stdx r4, r5, r3 +; CHECK-SMALLCM64-NEXT: ld r5, L..C1(r2) # target-flags(ppc-tprel) @mySmallTLS3 +; CHECK-SMALLCM64-NEXT: li r3, 55 +; CHECK-SMALLCM64-NEXT: li r4, 64 +; CHECK-SMALLCM64-NEXT: std r3, mySmallTLS2[TL]@le+696(r13) +; CHECK-SMALLCM64-NEXT: li r3, 142 +; CHECK-SMALLCM64-NEXT: add r5, r13, r5 +; CHECK-SMALLCM64-NEXT: std r4, 20000(r5) +; CHECK-LARGECM64: addis r3, L..C0@u(r2) +; CHECK-LARGECM64-NEXT: li r4, 0 +; CHECK-LARGECM64-NEXT: li r5, 23 +; CHECK-LARGECM64-NEXT: ld r3, L..C0@l(r3) +; CHECK-LARGECM64-NEXT: ori r4, r4, 53328 +; CHECK-LARGECM64-NEXT: add r3, r13, r3 +; CHECK-LARGECM64-NEXT: stdx r5, r3, r4 +; CHECK-LARGECM64-NEXT: addis r3, L..C1@u(r2) +; CHECK-LARGECM64-NEXT: li r4, 55 +; CHECK-LARGECM64-NEXT: li r5, 64 +; CHECK-LARGECM64-NEXT: ld r3, L..C1@l(r3) +; CHECK-LARGECM64-NEXT: std r4, mySmallTLS2[TL]@le+696(r13) +; CHECK-LARGECM64-NEXT: add r3, r13, r3 +; CHECK-LARGECM64-NEXT: std r5, 20000(r3) +; CHECK-LARGECM64-NEXT: li r3, 142 +; COMMONCM-NEXT: blr +; +entry: + %tls0 = tail call align 8 ptr @llvm.threadlocal.address.p0(ptr align 8 @mySmallTLS) + %arrayidx = getelementptr inbounds i8, ptr %tls0, i32 53328 + store i64 23, ptr %arrayidx, align 8 + %tls1 = tail call align 8 ptr @llvm.threadlocal.address.p0(ptr align 8 @mySmallTLS2) + %arrayidx1 = getelementptr inbounds i8, ptr %tls1, i32 696 + store i64 55, ptr %arrayidx1, align 8 + %tls2 = tail call align 8 ptr @llvm.threadlocal.address.p0(ptr align 8 @mySmallTLS3) + %arrayidx2 = getelementptr inbounds i8, ptr %tls2, i32 20000 + store i64 64, ptr %arrayidx2, align 8 + %load1 = load i64, ptr %arrayidx, align 8 + %load2 = load i64, ptr %arrayidx1, align 8 + %add1 = add i64 %load1, 64 + %add2 = add i64 %add1, %load2 + ret i64 %add2 +} + +attributes #0 = { "aix-small-tls" } +attributes #1 = { "target-features"="+aix-small-local-exec-tls" } diff --git a/llvm/test/CodeGen/PowerPC/aix-small-tls-globalvarattr-loadaddr.ll b/llvm/test/CodeGen/PowerPC/aix-small-tls-globalvarattr-loadaddr.ll new file mode 100644 index 000000000000..c8537fba6a3c --- /dev/null +++ b/llvm/test/CodeGen/PowerPC/aix-small-tls-globalvarattr-loadaddr.ll @@ -0,0 +1,222 @@ +; NOTE: Assertions have been autogenerated by utils/update_llc_test_checks.py UTC_ARGS: --version 4 +; RUN: llc -verify-machineinstrs -mcpu=pwr7 -ppc-asm-full-reg-names \ +; RUN: -mtriple powerpc64-ibm-aix-xcoff -mattr=-aix-small-local-exec-tls \ +; RUN: < %s | FileCheck %s --check-prefixes=COMMONCM,SMALLCM64 +; RUN: llc -verify-machineinstrs -mcpu=pwr7 -ppc-asm-full-reg-names \ +; RUN: -mtriple powerpc64-ibm-aix-xcoff --code-model=large \ +; RUN: -mattr=-aix-small-local-exec-tls < %s | \ +; RUN: FileCheck %s --check-prefixes=COMMONCM,LARGECM64 + +; Test that the 'aix-small-tls' global variable attribute generates the +; optimized small-local-exec TLS sequence. Global variables without this +; attribute should still generate a TOC-based local-exec access sequence. + +declare nonnull ptr @llvm.threadlocal.address.p0(ptr nonnull) + +@a = thread_local(localexec) global [87 x i8] zeroinitializer, align 1 #0 +@a_noattr = thread_local(localexec) global [87 x i8] zeroinitializer, align 1 +@b = thread_local(localexec) global [87 x i16] zeroinitializer, align 2 #0 +@b_noattr = thread_local(localexec) global [87 x i16] zeroinitializer, align 2 +@c = thread_local(localexec) global [87 x i32] zeroinitializer, align 4 #0 +@c_noattr = thread_local(localexec) global [87 x i32] zeroinitializer, align 4 +@d = thread_local(localexec) global [87 x i64] zeroinitializer, align 8 #0 +@d_noattr = thread_local(localexec) global [87 x i64] zeroinitializer, align 8 #0 + +@e = thread_local(localexec) global [87 x double] zeroinitializer, align 8 #0 +@e_noattr = thread_local(localexec) global [87 x double] zeroinitializer, align 8 +@f = thread_local(localexec) global [87 x float] zeroinitializer, align 4 #0 +@f_noattr = thread_local(localexec) global [87 x float] zeroinitializer, align 4 + +define nonnull ptr @AddrTest1() { +; COMMONCM-LABEL: AddrTest1: +; COMMONCM: # %bb.0: # %entry +; COMMONCM-NEXT: addi r3, r13, a[TL]@le+1 +; COMMONCM-NEXT: blr +entry: + %tls0 = tail call align 1 ptr @llvm.threadlocal.address.p0(ptr align 1 @a) + %arrayidx = getelementptr inbounds [87 x i8], ptr %tls0, i64 0, i64 1 + ret ptr %arrayidx +} + +define nonnull ptr @AddrTest1_NoAttr() { +; SMALLCM64-LABEL: AddrTest1_NoAttr: +; SMALLCM64: # %bb.0: # %entry +; SMALLCM64-NEXT: ld r3, L..C0(r2) # target-flags(ppc-tprel) @a_noattr +; SMALLCM64-NEXT: add r3, r13, r3 +; SMALLCM64-NEXT: addi r3, r3, 1 +; SMALLCM64-NEXT: blr +; +; LARGECM64-LABEL: AddrTest1_NoAttr: +; LARGECM64: # %bb.0: # %entry +; LARGECM64-NEXT: addis r3, L..C0@u(r2) +; LARGECM64-NEXT: ld r3, L..C0@l(r3) +; LARGECM64-NEXT: add r3, r13, r3 +; LARGECM64-NEXT: addi r3, r3, 1 +; LARGECM64-NEXT: blr +entry: + %tls0 = tail call align 1 ptr @llvm.threadlocal.address.p0(ptr align 1 @a_noattr) + %arrayidx = getelementptr inbounds [87 x i8], ptr %tls0, i64 0, i64 1 + ret ptr %arrayidx +} + +define nonnull ptr @AddrTest2() { +; COMMONCM-LABEL: AddrTest2: +; COMMONCM: # %bb.0: # %entry +; COMMONCM-NEXT: addi r3, r13, b[TL]@le+4 +; COMMONCM-NEXT: blr +entry: + %tls0 = tail call align 2 ptr @llvm.threadlocal.address.p0(ptr align 2 @b) + %arrayidx = getelementptr inbounds [87 x i16], ptr %tls0, i64 0, i64 2 + ret ptr %arrayidx +} + +define nonnull ptr @AddrTest2_NoAttr() { +; SMALLCM64-LABEL: AddrTest2_NoAttr: +; SMALLCM64: # %bb.0: # %entry +; SMALLCM64-NEXT: ld r3, L..C1(r2) # target-flags(ppc-tprel) @b_noattr +; SMALLCM64-NEXT: add r3, r13, r3 +; SMALLCM64-NEXT: addi r3, r3, 4 +; SMALLCM64-NEXT: blr +; +; LARGECM64-LABEL: AddrTest2_NoAttr: +; LARGECM64: # %bb.0: # %entry +; LARGECM64-NEXT: addis r3, L..C1@u(r2) +; LARGECM64-NEXT: ld r3, L..C1@l(r3) +; LARGECM64-NEXT: add r3, r13, r3 +; LARGECM64-NEXT: addi r3, r3, 4 +; LARGECM64-NEXT: blr +entry: + %tls0 = tail call align 2 ptr @llvm.threadlocal.address.p0(ptr align 2 @b_noattr) + %arrayidx = getelementptr inbounds [87 x i16], ptr %tls0, i64 0, i64 2 + ret ptr %arrayidx +} + +define nonnull ptr @AddrTest3() { +; COMMONCM-LABEL: AddrTest3: +; COMMONCM: # %bb.0: # %entry +; COMMONCM-NEXT: addi r3, r13, c[TL]@le+12 +; COMMONCM-NEXT: blr +entry: + %tls0 = tail call align 4 ptr @llvm.threadlocal.address.p0(ptr align 4 @c) + %arrayidx = getelementptr inbounds [87 x i32], ptr %tls0, i64 0, i64 3 + ret ptr %arrayidx +} + +define nonnull ptr @AddrTest3_NoAttr() { +; SMALLCM64-LABEL: AddrTest3_NoAttr: +; SMALLCM64: # %bb.0: # %entry +; SMALLCM64-NEXT: ld r3, L..C2(r2) # target-flags(ppc-tprel) @c_noattr +; SMALLCM64-NEXT: add r3, r13, r3 +; SMALLCM64-NEXT: addi r3, r3, 12 +; SMALLCM64-NEXT: blr +; +; LARGECM64-LABEL: AddrTest3_NoAttr: +; LARGECM64: # %bb.0: # %entry +; LARGECM64-NEXT: addis r3, L..C2@u(r2) +; LARGECM64-NEXT: ld r3, L..C2@l(r3) +; LARGECM64-NEXT: add r3, r13, r3 +; LARGECM64-NEXT: addi r3, r3, 12 +; LARGECM64-NEXT: blr +entry: + %tls0 = tail call align 4 ptr @llvm.threadlocal.address.p0(ptr align 4 @c_noattr) + %arrayidx = getelementptr inbounds [87 x i32], ptr %tls0, i64 0, i64 3 + ret ptr %arrayidx +} + +define nonnull ptr @AddrTest4() { +; COMMONCM-LABEL: AddrTest4: +; COMMONCM: # %bb.0: # %entry +; COMMONCM-NEXT: addi r3, r13, c[TL]@le+56 +; COMMONCM-NEXT: blr +entry: + %tls0 = tail call align 8 ptr @llvm.threadlocal.address.p0(ptr align 8 @c) + %arrayidx = getelementptr inbounds [87 x i64], ptr %tls0, i64 0, i64 7 + ret ptr %arrayidx +} + +define nonnull ptr @AddrTest4_NoAttr() { +; SMALLCM64-LABEL: AddrTest4_NoAttr: +; SMALLCM64: # %bb.0: # %entry +; SMALLCM64-NEXT: ld r3, L..C2(r2) # target-flags(ppc-tprel) @c_noattr +; SMALLCM64-NEXT: add r3, r13, r3 +; SMALLCM64-NEXT: addi r3, r3, 56 +; SMALLCM64-NEXT: blr +; +; LARGECM64-LABEL: AddrTest4_NoAttr: +; LARGECM64: # %bb.0: # %entry +; LARGECM64-NEXT: addis r3, L..C2@u(r2) +; LARGECM64-NEXT: ld r3, L..C2@l(r3) +; LARGECM64-NEXT: add r3, r13, r3 +; LARGECM64-NEXT: addi r3, r3, 56 +; LARGECM64-NEXT: blr +entry: + %tls0 = tail call align 8 ptr @llvm.threadlocal.address.p0(ptr align 8 @c_noattr) + %arrayidx = getelementptr inbounds [87 x i64], ptr %tls0, i64 0, i64 7 + ret ptr %arrayidx +} + +define nonnull ptr @AddrTest5() { +; COMMONCM-LABEL: AddrTest5: +; COMMONCM: # %bb.0: # %entry +; COMMONCM-NEXT: addi r3, r13, e[TL]@le+48 +; COMMONCM-NEXT: blr +entry: + %tls0 = tail call align 8 ptr @llvm.threadlocal.address.p0(ptr align 8 @e) + %arrayidx = getelementptr inbounds [87 x double], ptr %tls0, i64 0, i64 6 + ret ptr %arrayidx +} + +define nonnull ptr @AddrTest5_NoAttr() { +; SMALLCM64-LABEL: AddrTest5_NoAttr: +; SMALLCM64: # %bb.0: # %entry +; SMALLCM64-NEXT: ld r3, L..C3(r2) # target-flags(ppc-tprel) @e_noattr +; SMALLCM64-NEXT: add r3, r13, r3 +; SMALLCM64-NEXT: addi r3, r3, 48 +; SMALLCM64-NEXT: blr +; +; LARGECM64-LABEL: AddrTest5_NoAttr: +; LARGECM64: # %bb.0: # %entry +; LARGECM64-NEXT: addis r3, L..C3@u(r2) +; LARGECM64-NEXT: ld r3, L..C3@l(r3) +; LARGECM64-NEXT: add r3, r13, r3 +; LARGECM64-NEXT: addi r3, r3, 48 +; LARGECM64-NEXT: blr +entry: + %tls0 = tail call align 8 ptr @llvm.threadlocal.address.p0(ptr align 8 @e_noattr) + %arrayidx = getelementptr inbounds [87 x double], ptr %tls0, i64 0, i64 6 + ret ptr %arrayidx +} + +define nonnull ptr @AddrTest6() { +; COMMONCM-LABEL: AddrTest6: +; COMMONCM: # %bb.0: # %entry +; COMMONCM-NEXT: addi r3, r13, f[TL]@le+16 +; COMMONCM-NEXT: blr +entry: + %tls0 = tail call align 4 ptr @llvm.threadlocal.address.p0(ptr align 4 @f) + %arrayidx = getelementptr inbounds [87 x float], ptr %tls0, i64 0, i64 4 + ret ptr %arrayidx +} + +define nonnull ptr @AddrTest6_NoAttr() { +; SMALLCM64-LABEL: AddrTest6_NoAttr: +; SMALLCM64: # %bb.0: # %entry +; SMALLCM64-NEXT: ld r3, L..C4(r2) # target-flags(ppc-tprel) @f_noattr +; SMALLCM64-NEXT: add r3, r13, r3 +; SMALLCM64-NEXT: addi r3, r3, 16 +; SMALLCM64-NEXT: blr +; +; LARGECM64-LABEL: AddrTest6_NoAttr: +; LARGECM64: # %bb.0: # %entry +; LARGECM64-NEXT: addis r3, L..C4@u(r2) +; LARGECM64-NEXT: ld r3, L..C4@l(r3) +; LARGECM64-NEXT: add r3, r13, r3 +; LARGECM64-NEXT: addi r3, r3, 16 +; LARGECM64-NEXT: blr +entry: + %tls0 = tail call align 4 ptr @llvm.threadlocal.address.p0(ptr align 4 @f_noattr) + %arrayidx = getelementptr inbounds [87 x float], ptr %tls0, i64 0, i64 4 + ret ptr %arrayidx +} + +attributes #0 = { "aix-small-tls" } diff --git a/llvm/test/CodeGen/PowerPC/aix-small-tls-globalvarattr-targetattr.ll b/llvm/test/CodeGen/PowerPC/aix-small-tls-globalvarattr-targetattr.ll new file mode 100644 index 000000000000..1e4a3b9bcc47 --- /dev/null +++ b/llvm/test/CodeGen/PowerPC/aix-small-tls-globalvarattr-targetattr.ll @@ -0,0 +1,53 @@ +; RUN: llc -verify-machineinstrs -mcpu=pwr7 -ppc-asm-full-reg-names \ +; RUN: -mtriple powerpc64-ibm-aix-xcoff -mattr=+aix-small-local-exec-tls < %s \ +; RUN: | FileCheck %s --check-prefixes=COMMONCM,SMALL-LOCAL-EXEC-SMALLCM64 +; RUN: llc -verify-machineinstrs -mcpu=pwr7 -ppc-asm-full-reg-names \ +; RUN: -mtriple powerpc64-ibm-aix-xcoff --code-model=large \ +; RUN: -mattr=+aix-small-local-exec-tls < %s | FileCheck %s \ +; RUN: --check-prefixes=COMMONCM,SMALL-LOCAL-EXEC-LARGECM64 + +@mySmallTLS = thread_local(localexec) global [7800 x i64] zeroinitializer, align 8 #0 +@mySmallTLS2 = thread_local(localexec) global [3000 x i64] zeroinitializer, align 8 #0 +@mySmallTLS3 = thread_local(localexec) global [3000 x i64] zeroinitializer, align 8 +declare nonnull ptr @llvm.threadlocal.address.p0(ptr nonnull) + +; Although some global variables are annotated with 'aix-small-tls', because the +; aix-small-local-exec-tls target attribute is turned on, all accesses will use +; a "faster" local-exec sequence directly off the thread pointer. +define i64 @StoreLargeAccess1() { +; COMMONCM-LABEL: StoreLargeAccess1: +; COMMONCM-NEXT: # %bb.0: # %entry +; SMALL-LOCAL-EXEC-SMALLCM64: ld r3, L..C0(r2) # target-flags(ppc-tprel) @mySmallTLS +; SMALL-LOCAL-EXEC-SMALLCM64-NEXT: li r4, 0 +; SMALL-LOCAL-EXEC-SMALLCM64-NEXT: li r5, 23 +; SMALL-LOCAL-EXEC-LARGECM64: addis r3, L..C0@u(r2) +; SMALL-LOCAL-EXEC-LARGECM64-NEXT: li r4, 0 +; SMALL-LOCAL-EXEC-LARGECM64-NEXT: li r5, 23 +; SMALL-LOCAL-EXEC-LARGECM64-NEXT: ld r3, L..C0@l(r3) +; COMMONCM: ori r4, r4, 53328 +; COMMONCM-NEXT: add r3, r13, r3 +; COMMONCM-NEXT: stdx r5, r3, r4 +; COMMONCM-NEXT: li r3, 55 +; COMMONCM-NEXT: li r4, 64 +; COMMONCM-NEXT: std r3, (mySmallTLS2[TL]@le+696)-65536(r13) +; COMMONCM-NEXT: li r3, 142 +; COMMONCM-NEXT: std r4, (mySmallTLS3[TL]@le+20000)-131072(r13) +; COMMONCM-NEXT: blr +entry: + %tls0 = tail call align 8 ptr @llvm.threadlocal.address.p0(ptr align 8 @mySmallTLS) + %arrayidx = getelementptr inbounds i8, ptr %tls0, i32 53328 + store i64 23, ptr %arrayidx, align 8 + %tls1 = tail call align 8 ptr @llvm.threadlocal.address.p0(ptr align 8 @mySmallTLS2) + %arrayidx1 = getelementptr inbounds i8, ptr %tls1, i32 696 + store i64 55, ptr %arrayidx1, align 8 + %tls2 = tail call align 8 ptr @llvm.threadlocal.address.p0(ptr align 8 @mySmallTLS3) + %arrayidx2 = getelementptr inbounds i8, ptr %tls2, i32 20000 + store i64 64, ptr %arrayidx2, align 8 + %load1 = load i64, ptr %arrayidx, align 8 + %load2 = load i64, ptr %arrayidx1, align 8 + %add1 = add i64 %load1, 64 + %add2 = add i64 %add1, %load2 + ret i64 %add2 +} + +attributes #0 = { "aix-small-tls" } -- GitLab From 84780af4b02cb3b86e4cb724f996bf8e02f2f2e7 Mon Sep 17 00:00:00 2001 From: Akira Hatanaka Date: Thu, 28 Mar 2024 06:54:36 -0700 Subject: [PATCH 058/788] [CodeGen][arm64e] Add methods and data members to Address, which are needed to authenticate signed pointers (#86923) To authenticate pointers, CodeGen needs access to the key and discriminators that were used to sign the pointer. That information is sometimes known from the context, but not always, which is why `Address` needs to hold that information. This patch adds methods and data members to `Address`, which will be needed in subsequent patches to authenticate signed pointers, and uses the newly added methods throughout CodeGen. Although this patch isn't strictly NFC as it causes CodeGen to use different code paths in some cases (e.g., `mergeAddressesInConditionalExpr`), it doesn't cause any changes in functionality as it doesn't add any information needed for authentication. In addition to the changes mentioned above, this patch introduces class `RawAddress`, which contains a pointer that we know is unsigned, and adds several new functions for creating `Address` and `LValue` objects. This reapplies d9a685a9dd589486e882b722e513ee7b8c84870c, which was reverted because it broke ubsan bots. There seems to be a bug in coroutine code-gen, which is causing EmitTypeCheck to use the wrong alignment. For now, pass alignment zero to EmitTypeCheck so that it can compute the correct alignment based on the passed type (see function EmitCXXMemberOrOperatorMemberCallExpr). --- clang/lib/CodeGen/ABIInfoImpl.cpp | 10 +- clang/lib/CodeGen/Address.h | 195 ++++++++++++++--- clang/lib/CodeGen/CGAtomic.cpp | 53 ++--- clang/lib/CodeGen/CGBlocks.cpp | 34 +-- clang/lib/CodeGen/CGBlocks.h | 3 +- clang/lib/CodeGen/CGBuilder.h | 234 ++++++++++++++------- clang/lib/CodeGen/CGBuiltin.cpp | 173 +++++++-------- clang/lib/CodeGen/CGCUDANV.cpp | 19 +- clang/lib/CodeGen/CGCXXABI.cpp | 21 +- clang/lib/CodeGen/CGCXXABI.h | 14 +- clang/lib/CodeGen/CGCall.cpp | 171 ++++++++------- clang/lib/CodeGen/CGCall.h | 1 + clang/lib/CodeGen/CGClass.cpp | 76 ++++--- clang/lib/CodeGen/CGCleanup.cpp | 110 ++++------ clang/lib/CodeGen/CGCleanup.h | 2 +- clang/lib/CodeGen/CGCoroutine.cpp | 4 +- clang/lib/CodeGen/CGDecl.cpp | 28 +-- clang/lib/CodeGen/CGException.cpp | 19 +- clang/lib/CodeGen/CGExpr.cpp | 227 ++++++++++---------- clang/lib/CodeGen/CGExprAgg.cpp | 29 +-- clang/lib/CodeGen/CGExprCXX.cpp | 115 +++++----- clang/lib/CodeGen/CGExprConstant.cpp | 4 +- clang/lib/CodeGen/CGExprScalar.cpp | 23 +- clang/lib/CodeGen/CGNonTrivialStruct.cpp | 8 +- clang/lib/CodeGen/CGObjC.cpp | 43 ++-- clang/lib/CodeGen/CGObjCGNU.cpp | 42 ++-- clang/lib/CodeGen/CGObjCMac.cpp | 95 ++++----- clang/lib/CodeGen/CGObjCRuntime.cpp | 6 +- clang/lib/CodeGen/CGOpenMPRuntime.cpp | 194 +++++++++-------- clang/lib/CodeGen/CGOpenMPRuntime.h | 5 +- clang/lib/CodeGen/CGOpenMPRuntimeGPU.cpp | 76 +++---- clang/lib/CodeGen/CGStmt.cpp | 8 +- clang/lib/CodeGen/CGStmtOpenMP.cpp | 87 ++++---- clang/lib/CodeGen/CGVTables.cpp | 9 +- clang/lib/CodeGen/CGValue.h | 250 +++++++++++----------- clang/lib/CodeGen/CodeGenFunction.cpp | 71 ++++--- clang/lib/CodeGen/CodeGenFunction.h | 257 ++++++++++++++++------- clang/lib/CodeGen/CodeGenModule.cpp | 2 +- clang/lib/CodeGen/CodeGenPGO.cpp | 10 +- clang/lib/CodeGen/CodeGenPGO.h | 6 +- clang/lib/CodeGen/ItaniumCXXABI.cpp | 52 ++--- clang/lib/CodeGen/MicrosoftCXXABI.cpp | 58 ++--- clang/lib/CodeGen/TargetInfo.h | 5 + clang/lib/CodeGen/Targets/NVPTX.cpp | 2 +- clang/lib/CodeGen/Targets/PPC.cpp | 11 +- clang/lib/CodeGen/Targets/Sparc.cpp | 2 +- clang/lib/CodeGen/Targets/SystemZ.cpp | 9 +- clang/lib/CodeGen/Targets/XCore.cpp | 2 +- clang/utils/TableGen/MveEmitter.cpp | 2 +- llvm/include/llvm/IR/IRBuilder.h | 1 + 50 files changed, 1644 insertions(+), 1234 deletions(-) diff --git a/clang/lib/CodeGen/ABIInfoImpl.cpp b/clang/lib/CodeGen/ABIInfoImpl.cpp index dd59101ecc81..3e34d82cb399 100644 --- a/clang/lib/CodeGen/ABIInfoImpl.cpp +++ b/clang/lib/CodeGen/ABIInfoImpl.cpp @@ -187,7 +187,7 @@ CodeGen::emitVoidPtrDirectVAArg(CodeGenFunction &CGF, Address VAListAddr, CharUnits FullDirectSize = DirectSize.alignTo(SlotSize); Address NextPtr = CGF.Builder.CreateConstInBoundsByteGEP(Addr, FullDirectSize, "argp.next"); - CGF.Builder.CreateStore(NextPtr.getPointer(), VAListAddr); + CGF.Builder.CreateStore(NextPtr.emitRawPointer(CGF), VAListAddr); // If the argument is smaller than a slot, and this is a big-endian // target, the argument will be right-adjusted in its slot. @@ -239,8 +239,8 @@ Address CodeGen::emitMergePHI(CodeGenFunction &CGF, Address Addr1, const llvm::Twine &Name) { assert(Addr1.getType() == Addr2.getType()); llvm::PHINode *PHI = CGF.Builder.CreatePHI(Addr1.getType(), 2, Name); - PHI->addIncoming(Addr1.getPointer(), Block1); - PHI->addIncoming(Addr2.getPointer(), Block2); + PHI->addIncoming(Addr1.emitRawPointer(CGF), Block1); + PHI->addIncoming(Addr2.emitRawPointer(CGF), Block2); CharUnits Align = std::min(Addr1.getAlignment(), Addr2.getAlignment()); return Address(PHI, Addr1.getElementType(), Align); } @@ -400,7 +400,7 @@ Address CodeGen::EmitVAArgInstr(CodeGenFunction &CGF, Address VAListAddr, llvm::Type *ElementTy = CGF.ConvertTypeForMem(Ty); llvm::Type *BaseTy = llvm::PointerType::getUnqual(ElementTy); llvm::Value *Addr = - CGF.Builder.CreateVAArg(VAListAddr.getPointer(), BaseTy); + CGF.Builder.CreateVAArg(VAListAddr.emitRawPointer(CGF), BaseTy); return Address(Addr, ElementTy, TyAlignForABI); } else { assert((AI.isDirect() || AI.isExtend()) && @@ -416,7 +416,7 @@ Address CodeGen::EmitVAArgInstr(CodeGenFunction &CGF, Address VAListAddr, "Unexpected CoerceToType seen in arginfo in generic VAArg emitter!"); Address Temp = CGF.CreateMemTemp(Ty, "varet"); - Val = CGF.Builder.CreateVAArg(VAListAddr.getPointer(), + Val = CGF.Builder.CreateVAArg(VAListAddr.emitRawPointer(CGF), CGF.ConvertTypeForMem(Ty)); CGF.Builder.CreateStore(Val, Temp); return Temp; diff --git a/clang/lib/CodeGen/Address.h b/clang/lib/CodeGen/Address.h index cf48df8f5e73..35ec370a139c 100644 --- a/clang/lib/CodeGen/Address.h +++ b/clang/lib/CodeGen/Address.h @@ -15,6 +15,7 @@ #define LLVM_CLANG_LIB_CODEGEN_ADDRESS_H #include "clang/AST/CharUnits.h" +#include "clang/AST/Type.h" #include "llvm/ADT/PointerIntPair.h" #include "llvm/IR/Constants.h" #include "llvm/Support/MathExtras.h" @@ -22,28 +23,41 @@ namespace clang { namespace CodeGen { +class Address; +class CGBuilderTy; +class CodeGenFunction; +class CodeGenModule; + // Indicates whether a pointer is known not to be null. enum KnownNonNull_t { NotKnownNonNull, KnownNonNull }; -/// An aligned address. -class Address { +/// An abstract representation of an aligned address. This is designed to be an +/// IR-level abstraction, carrying just the information necessary to perform IR +/// operations on an address like loads and stores. In particular, it doesn't +/// carry C type information or allow the representation of things like +/// bit-fields; clients working at that level should generally be using +/// `LValue`. +/// The pointer contained in this class is known to be unsigned. +class RawAddress { llvm::PointerIntPair PointerAndKnownNonNull; llvm::Type *ElementType; CharUnits Alignment; protected: - Address(std::nullptr_t) : ElementType(nullptr) {} + RawAddress(std::nullptr_t) : ElementType(nullptr) {} public: - Address(llvm::Value *Pointer, llvm::Type *ElementType, CharUnits Alignment, - KnownNonNull_t IsKnownNonNull = NotKnownNonNull) + RawAddress(llvm::Value *Pointer, llvm::Type *ElementType, CharUnits Alignment, + KnownNonNull_t IsKnownNonNull = NotKnownNonNull) : PointerAndKnownNonNull(Pointer, IsKnownNonNull), ElementType(ElementType), Alignment(Alignment) { assert(Pointer != nullptr && "Pointer cannot be null"); assert(ElementType != nullptr && "Element type cannot be null"); } - static Address invalid() { return Address(nullptr); } + inline RawAddress(Address Addr); + + static RawAddress invalid() { return RawAddress(nullptr); } bool isValid() const { return PointerAndKnownNonNull.getPointer() != nullptr; } @@ -80,6 +94,133 @@ public: return Alignment; } + /// Return address with different element type, but same pointer and + /// alignment. + RawAddress withElementType(llvm::Type *ElemTy) const { + return RawAddress(getPointer(), ElemTy, getAlignment(), isKnownNonNull()); + } + + KnownNonNull_t isKnownNonNull() const { + assert(isValid()); + return (KnownNonNull_t)PointerAndKnownNonNull.getInt(); + } +}; + +/// Like RawAddress, an abstract representation of an aligned address, but the +/// pointer contained in this class is possibly signed. +class Address { + friend class CGBuilderTy; + + // The boolean flag indicates whether the pointer is known to be non-null. + llvm::PointerIntPair Pointer; + + /// The expected IR type of the pointer. Carrying accurate element type + /// information in Address makes it more convenient to work with Address + /// values and allows frontend assertions to catch simple mistakes. + llvm::Type *ElementType = nullptr; + + CharUnits Alignment; + + /// Offset from the base pointer. + llvm::Value *Offset = nullptr; + + llvm::Value *emitRawPointerSlow(CodeGenFunction &CGF) const; + +protected: + Address(std::nullptr_t) : ElementType(nullptr) {} + +public: + Address(llvm::Value *pointer, llvm::Type *elementType, CharUnits alignment, + KnownNonNull_t IsKnownNonNull = NotKnownNonNull) + : Pointer(pointer, IsKnownNonNull), ElementType(elementType), + Alignment(alignment) { + assert(pointer != nullptr && "Pointer cannot be null"); + assert(elementType != nullptr && "Element type cannot be null"); + assert(!alignment.isZero() && "Alignment cannot be zero"); + } + + Address(llvm::Value *BasePtr, llvm::Type *ElementType, CharUnits Alignment, + llvm::Value *Offset, KnownNonNull_t IsKnownNonNull = NotKnownNonNull) + : Pointer(BasePtr, IsKnownNonNull), ElementType(ElementType), + Alignment(Alignment), Offset(Offset) {} + + Address(RawAddress RawAddr) + : Pointer(RawAddr.isValid() ? RawAddr.getPointer() : nullptr), + ElementType(RawAddr.isValid() ? RawAddr.getElementType() : nullptr), + Alignment(RawAddr.isValid() ? RawAddr.getAlignment() + : CharUnits::Zero()) {} + + static Address invalid() { return Address(nullptr); } + bool isValid() const { return Pointer.getPointer() != nullptr; } + + /// This function is used in situations where the caller is doing some sort of + /// opaque "laundering" of the pointer. + void replaceBasePointer(llvm::Value *P) { + assert(isValid() && "pointer isn't valid"); + assert(P->getType() == Pointer.getPointer()->getType() && + "Pointer's type changed"); + Pointer.setPointer(P); + assert(isValid() && "pointer is invalid after replacement"); + } + + CharUnits getAlignment() const { return Alignment; } + + void setAlignment(CharUnits Value) { Alignment = Value; } + + llvm::Value *getBasePointer() const { + assert(isValid() && "pointer isn't valid"); + return Pointer.getPointer(); + } + + /// Return the type of the pointer value. + llvm::PointerType *getType() const { + return llvm::PointerType::get( + ElementType, + llvm::cast(Pointer.getPointer()->getType()) + ->getAddressSpace()); + } + + /// Return the type of the values stored in this address. + llvm::Type *getElementType() const { + assert(isValid()); + return ElementType; + } + + /// Return the address space that this address resides in. + unsigned getAddressSpace() const { return getType()->getAddressSpace(); } + + /// Return the IR name of the pointer value. + llvm::StringRef getName() const { return Pointer.getPointer()->getName(); } + + // This function is called only in CGBuilderBaseTy::CreateElementBitCast. + void setElementType(llvm::Type *Ty) { + assert(hasOffset() && + "this funcion shouldn't be called when there is no offset"); + ElementType = Ty; + } + + /// Whether the pointer is known not to be null. + KnownNonNull_t isKnownNonNull() const { + assert(isValid()); + return (KnownNonNull_t)Pointer.getInt(); + } + + Address setKnownNonNull() { + assert(isValid()); + Pointer.setInt(KnownNonNull); + return *this; + } + + bool hasOffset() const { return Offset; } + + llvm::Value *getOffset() const { return Offset; } + + /// Return the pointer contained in this class after authenticating it and + /// adding offset to it if necessary. + llvm::Value *emitRawPointer(CodeGenFunction &CGF) const { + return getBasePointer(); + } + /// Return address with different pointer, but same element type and /// alignment. Address withPointer(llvm::Value *NewPointer, @@ -91,61 +232,59 @@ public: /// Return address with different alignment, but same pointer and element /// type. Address withAlignment(CharUnits NewAlignment) const { - return Address(getPointer(), getElementType(), NewAlignment, + return Address(Pointer.getPointer(), getElementType(), NewAlignment, isKnownNonNull()); } /// Return address with different element type, but same pointer and /// alignment. Address withElementType(llvm::Type *ElemTy) const { - return Address(getPointer(), ElemTy, getAlignment(), isKnownNonNull()); - } - - /// Whether the pointer is known not to be null. - KnownNonNull_t isKnownNonNull() const { - assert(isValid()); - return (KnownNonNull_t)PointerAndKnownNonNull.getInt(); - } - - /// Set the non-null bit. - Address setKnownNonNull() { - assert(isValid()); - PointerAndKnownNonNull.setInt(true); - return *this; + if (!hasOffset()) + return Address(getBasePointer(), ElemTy, getAlignment(), nullptr, + isKnownNonNull()); + Address A(*this); + A.ElementType = ElemTy; + return A; } }; +inline RawAddress::RawAddress(Address Addr) + : PointerAndKnownNonNull(Addr.isValid() ? Addr.getBasePointer() : nullptr, + Addr.isValid() ? Addr.isKnownNonNull() + : NotKnownNonNull), + ElementType(Addr.isValid() ? Addr.getElementType() : nullptr), + Alignment(Addr.isValid() ? Addr.getAlignment() : CharUnits::Zero()) {} + /// A specialization of Address that requires the address to be an /// LLVM Constant. -class ConstantAddress : public Address { - ConstantAddress(std::nullptr_t) : Address(nullptr) {} +class ConstantAddress : public RawAddress { + ConstantAddress(std::nullptr_t) : RawAddress(nullptr) {} public: ConstantAddress(llvm::Constant *pointer, llvm::Type *elementType, CharUnits alignment) - : Address(pointer, elementType, alignment) {} + : RawAddress(pointer, elementType, alignment) {} static ConstantAddress invalid() { return ConstantAddress(nullptr); } llvm::Constant *getPointer() const { - return llvm::cast(Address::getPointer()); + return llvm::cast(RawAddress::getPointer()); } ConstantAddress withElementType(llvm::Type *ElemTy) const { return ConstantAddress(getPointer(), ElemTy, getAlignment()); } - static bool isaImpl(Address addr) { + static bool isaImpl(RawAddress addr) { return llvm::isa(addr.getPointer()); } - static ConstantAddress castImpl(Address addr) { + static ConstantAddress castImpl(RawAddress addr) { return ConstantAddress(llvm::cast(addr.getPointer()), addr.getElementType(), addr.getAlignment()); } }; - } // Present a minimal LLVM-like casting interface. diff --git a/clang/lib/CodeGen/CGAtomic.cpp b/clang/lib/CodeGen/CGAtomic.cpp index fb03d013e8af..56198385de9d 100644 --- a/clang/lib/CodeGen/CGAtomic.cpp +++ b/clang/lib/CodeGen/CGAtomic.cpp @@ -80,7 +80,7 @@ namespace { AtomicSizeInBits = C.toBits( C.toCharUnitsFromBits(Offset + OrigBFI.Size + C.getCharWidth() - 1) .alignTo(lvalue.getAlignment())); - llvm::Value *BitFieldPtr = lvalue.getBitFieldPointer(); + llvm::Value *BitFieldPtr = lvalue.getRawBitFieldPointer(CGF); auto OffsetInChars = (C.toCharUnitsFromBits(OrigBFI.Offset) / lvalue.getAlignment()) * lvalue.getAlignment(); @@ -139,13 +139,13 @@ namespace { const LValue &getAtomicLValue() const { return LVal; } llvm::Value *getAtomicPointer() const { if (LVal.isSimple()) - return LVal.getPointer(CGF); + return LVal.emitRawPointer(CGF); else if (LVal.isBitField()) - return LVal.getBitFieldPointer(); + return LVal.getRawBitFieldPointer(CGF); else if (LVal.isVectorElt()) - return LVal.getVectorPointer(); + return LVal.getRawVectorPointer(CGF); assert(LVal.isExtVectorElt()); - return LVal.getExtVectorPointer(); + return LVal.getRawExtVectorPointer(CGF); } Address getAtomicAddress() const { llvm::Type *ElTy; @@ -368,7 +368,7 @@ bool AtomicInfo::emitMemSetZeroIfNecessary() const { return false; CGF.Builder.CreateMemSet( - addr.getPointer(), llvm::ConstantInt::get(CGF.Int8Ty, 0), + addr.emitRawPointer(CGF), llvm::ConstantInt::get(CGF.Int8Ty, 0), CGF.getContext().toCharUnitsFromBits(AtomicSizeInBits).getQuantity(), LVal.getAlignment().getAsAlign()); return true; @@ -1055,7 +1055,8 @@ RValue CodeGenFunction::EmitAtomicExpr(AtomicExpr *E) { return getTargetHooks().performAddrSpaceCast( *this, V, AS, LangAS::opencl_generic, DestType, false); }; - Args.add(RValue::get(CastToGenericAddrSpace(Ptr.getPointer(), + + Args.add(RValue::get(CastToGenericAddrSpace(Ptr.emitRawPointer(*this), E->getPtr()->getType())), getContext().VoidPtrTy); @@ -1086,10 +1087,10 @@ RValue CodeGenFunction::EmitAtomicExpr(AtomicExpr *E) { LibCallName = "__atomic_compare_exchange"; RetTy = getContext().BoolTy; HaveRetTy = true; - Args.add(RValue::get(CastToGenericAddrSpace(Val1.getPointer(), + Args.add(RValue::get(CastToGenericAddrSpace(Val1.emitRawPointer(*this), E->getVal1()->getType())), getContext().VoidPtrTy); - Args.add(RValue::get(CastToGenericAddrSpace(Val2.getPointer(), + Args.add(RValue::get(CastToGenericAddrSpace(Val2.emitRawPointer(*this), E->getVal2()->getType())), getContext().VoidPtrTy); Args.add(RValue::get(Order), getContext().IntTy); @@ -1105,7 +1106,7 @@ RValue CodeGenFunction::EmitAtomicExpr(AtomicExpr *E) { case AtomicExpr::AO__scoped_atomic_exchange: case AtomicExpr::AO__scoped_atomic_exchange_n: LibCallName = "__atomic_exchange"; - Args.add(RValue::get(CastToGenericAddrSpace(Val1.getPointer(), + Args.add(RValue::get(CastToGenericAddrSpace(Val1.emitRawPointer(*this), E->getVal1()->getType())), getContext().VoidPtrTy); break; @@ -1120,7 +1121,7 @@ RValue CodeGenFunction::EmitAtomicExpr(AtomicExpr *E) { LibCallName = "__atomic_store"; RetTy = getContext().VoidTy; HaveRetTy = true; - Args.add(RValue::get(CastToGenericAddrSpace(Val1.getPointer(), + Args.add(RValue::get(CastToGenericAddrSpace(Val1.emitRawPointer(*this), E->getVal1()->getType())), getContext().VoidPtrTy); break; @@ -1199,7 +1200,8 @@ RValue CodeGenFunction::EmitAtomicExpr(AtomicExpr *E) { if (!HaveRetTy) { // Value is returned through parameter before the order. RetTy = getContext().VoidTy; - Args.add(RValue::get(CastToGenericAddrSpace(Dest.getPointer(), RetTy)), + Args.add(RValue::get( + CastToGenericAddrSpace(Dest.emitRawPointer(*this), RetTy)), getContext().VoidPtrTy); } // Order is always the last parameter. @@ -1513,7 +1515,7 @@ RValue AtomicInfo::EmitAtomicLoad(AggValueSlot ResultSlot, SourceLocation Loc, } else TempAddr = CreateTempAlloca(); - EmitAtomicLoadLibcall(TempAddr.getPointer(), AO, IsVolatile); + EmitAtomicLoadLibcall(TempAddr.emitRawPointer(CGF), AO, IsVolatile); // Okay, turn that back into the original value or whole atomic (for // non-simple lvalues) type. @@ -1673,9 +1675,9 @@ std::pair AtomicInfo::EmitAtomicCompareExchange( if (shouldUseLibcall()) { // Produce a source address. Address ExpectedAddr = materializeRValue(Expected); - Address DesiredAddr = materializeRValue(Desired); - auto *Res = EmitAtomicCompareExchangeLibcall(ExpectedAddr.getPointer(), - DesiredAddr.getPointer(), + llvm::Value *ExpectedPtr = ExpectedAddr.emitRawPointer(CGF); + llvm::Value *DesiredPtr = materializeRValue(Desired).emitRawPointer(CGF); + auto *Res = EmitAtomicCompareExchangeLibcall(ExpectedPtr, DesiredPtr, Success, Failure); return std::make_pair( convertAtomicTempToRValue(ExpectedAddr, AggValueSlot::ignored(), @@ -1757,7 +1759,7 @@ void AtomicInfo::EmitAtomicUpdateLibcall( Address ExpectedAddr = CreateTempAlloca(); - EmitAtomicLoadLibcall(ExpectedAddr.getPointer(), AO, IsVolatile); + EmitAtomicLoadLibcall(ExpectedAddr.emitRawPointer(CGF), AO, IsVolatile); auto *ContBB = CGF.createBasicBlock("atomic_cont"); auto *ExitBB = CGF.createBasicBlock("atomic_exit"); CGF.EmitBlock(ContBB); @@ -1771,10 +1773,10 @@ void AtomicInfo::EmitAtomicUpdateLibcall( AggValueSlot::ignored(), SourceLocation(), /*AsValue=*/false); EmitAtomicUpdateValue(CGF, *this, OldRVal, UpdateOp, DesiredAddr); + llvm::Value *ExpectedPtr = ExpectedAddr.emitRawPointer(CGF); + llvm::Value *DesiredPtr = DesiredAddr.emitRawPointer(CGF); auto *Res = - EmitAtomicCompareExchangeLibcall(ExpectedAddr.getPointer(), - DesiredAddr.getPointer(), - AO, Failure); + EmitAtomicCompareExchangeLibcall(ExpectedPtr, DesiredPtr, AO, Failure); CGF.Builder.CreateCondBr(Res, ExitBB, ContBB); CGF.EmitBlock(ExitBB, /*IsFinished=*/true); } @@ -1843,7 +1845,7 @@ void AtomicInfo::EmitAtomicUpdateLibcall(llvm::AtomicOrdering AO, Address ExpectedAddr = CreateTempAlloca(); - EmitAtomicLoadLibcall(ExpectedAddr.getPointer(), AO, IsVolatile); + EmitAtomicLoadLibcall(ExpectedAddr.emitRawPointer(CGF), AO, IsVolatile); auto *ContBB = CGF.createBasicBlock("atomic_cont"); auto *ExitBB = CGF.createBasicBlock("atomic_exit"); CGF.EmitBlock(ContBB); @@ -1854,10 +1856,10 @@ void AtomicInfo::EmitAtomicUpdateLibcall(llvm::AtomicOrdering AO, CGF.Builder.CreateStore(OldVal, DesiredAddr); } EmitAtomicUpdateValue(CGF, *this, UpdateRVal, DesiredAddr); + llvm::Value *ExpectedPtr = ExpectedAddr.emitRawPointer(CGF); + llvm::Value *DesiredPtr = DesiredAddr.emitRawPointer(CGF); auto *Res = - EmitAtomicCompareExchangeLibcall(ExpectedAddr.getPointer(), - DesiredAddr.getPointer(), - AO, Failure); + EmitAtomicCompareExchangeLibcall(ExpectedPtr, DesiredPtr, AO, Failure); CGF.Builder.CreateCondBr(Res, ExitBB, ContBB); CGF.EmitBlock(ExitBB, /*IsFinished=*/true); } @@ -1957,7 +1959,8 @@ void CodeGenFunction::EmitAtomicStore(RValue rvalue, LValue dest, args.add(RValue::get(atomics.getAtomicSizeValue()), getContext().getSizeType()); args.add(RValue::get(atomics.getAtomicPointer()), getContext().VoidPtrTy); - args.add(RValue::get(srcAddr.getPointer()), getContext().VoidPtrTy); + args.add(RValue::get(srcAddr.emitRawPointer(*this)), + getContext().VoidPtrTy); args.add( RValue::get(llvm::ConstantInt::get(IntTy, (int)llvm::toCABI(AO))), getContext().IntTy); diff --git a/clang/lib/CodeGen/CGBlocks.cpp b/clang/lib/CodeGen/CGBlocks.cpp index ad0b50d79961..a01f2c7c9798 100644 --- a/clang/lib/CodeGen/CGBlocks.cpp +++ b/clang/lib/CodeGen/CGBlocks.cpp @@ -36,7 +36,8 @@ CGBlockInfo::CGBlockInfo(const BlockDecl *block, StringRef name) : Name(name), CXXThisIndex(0), CanBeGlobal(false), NeedsCopyDispose(false), NoEscape(false), HasCXXObject(false), UsesStret(false), HasCapturedVariableLayout(false), CapturesNonExternalType(false), - LocalAddress(Address::invalid()), StructureType(nullptr), Block(block) { + LocalAddress(RawAddress::invalid()), StructureType(nullptr), + Block(block) { // Skip asm prefix, if any. 'name' is usually taken directly from // the mangled name of the enclosing function. @@ -794,7 +795,7 @@ llvm::Value *CodeGenFunction::EmitBlockLiteral(const CGBlockInfo &blockInfo) { // Otherwise, we have to emit this as a local block. - Address blockAddr = blockInfo.LocalAddress; + RawAddress blockAddr = blockInfo.LocalAddress; assert(blockAddr.isValid() && "block has no address!"); llvm::Constant *isa; @@ -939,7 +940,7 @@ llvm::Value *CodeGenFunction::EmitBlockLiteral(const CGBlockInfo &blockInfo) { if (CI.isNested()) byrefPointer = Builder.CreateLoad(src, "byref.capture"); else - byrefPointer = src.getPointer(); + byrefPointer = src.emitRawPointer(*this); // Write that void* into the capture field. Builder.CreateStore(byrefPointer, blockField); @@ -961,10 +962,10 @@ llvm::Value *CodeGenFunction::EmitBlockLiteral(const CGBlockInfo &blockInfo) { } // If it's a reference variable, copy the reference into the block field. - } else if (type->isReferenceType()) { - Builder.CreateStore(src.getPointer(), blockField); + } else if (auto refType = type->getAs()) { + Builder.CreateStore(src.emitRawPointer(*this), blockField); - // If type is const-qualified, copy the value into the block field. + // If type is const-qualified, copy the value into the block field. } else if (type.isConstQualified() && type.getObjCLifetime() == Qualifiers::OCL_Strong && CGM.getCodeGenOpts().OptimizationLevel != 0) { @@ -1377,7 +1378,7 @@ void CodeGenFunction::setBlockContextParameter(const ImplicitParamDecl *D, // Allocate a stack slot like for any local variable to guarantee optimal // debug info at -O0. The mem2reg pass will eliminate it when optimizing. - Address alloc = CreateMemTemp(D->getType(), D->getName() + ".addr"); + RawAddress alloc = CreateMemTemp(D->getType(), D->getName() + ".addr"); Builder.CreateStore(arg, alloc); if (CGDebugInfo *DI = getDebugInfo()) { if (CGM.getCodeGenOpts().hasReducedDebugInfo()) { @@ -1497,7 +1498,7 @@ llvm::Function *CodeGenFunction::GenerateBlockFunction( // frame setup instruction by llvm::DwarfDebug::beginFunction(). auto NL = ApplyDebugLocation::CreateEmpty(*this); Builder.CreateStore(BlockPointer, Alloca); - BlockPointerDbgLoc = Alloca.getPointer(); + BlockPointerDbgLoc = Alloca.emitRawPointer(*this); } // If we have a C++ 'this' reference, go ahead and force it into @@ -1557,8 +1558,8 @@ llvm::Function *CodeGenFunction::GenerateBlockFunction( const CGBlockInfo::Capture &capture = blockInfo.getCapture(variable); if (capture.isConstant()) { auto addr = LocalDeclMap.find(variable)->second; - (void)DI->EmitDeclareOfAutoVariable(variable, addr.getPointer(), - Builder); + (void)DI->EmitDeclareOfAutoVariable( + variable, addr.emitRawPointer(*this), Builder); continue; } @@ -1662,7 +1663,7 @@ struct CallBlockRelease final : EHScopeStack::Cleanup { if (LoadBlockVarAddr) { BlockVarAddr = CGF.Builder.CreateLoad(Addr); } else { - BlockVarAddr = Addr.getPointer(); + BlockVarAddr = Addr.emitRawPointer(CGF); } CGF.BuildBlockRelease(BlockVarAddr, FieldFlags, CanThrow); @@ -1962,13 +1963,15 @@ CodeGenFunction::GenerateCopyHelperFunction(const CGBlockInfo &blockInfo) { // it. It's not quite worth the annoyance to avoid creating it in the // first place. if (!needsEHCleanup(captureType.isDestructedType())) - cast(dstField.getPointer())->eraseFromParent(); + if (auto *I = + cast_or_null(dstField.getBasePointer())) + I->eraseFromParent(); } break; } case BlockCaptureEntityKind::BlockObject: { llvm::Value *srcValue = Builder.CreateLoad(srcField, "blockcopy.src"); - llvm::Value *dstAddr = dstField.getPointer(); + llvm::Value *dstAddr = dstField.emitRawPointer(*this); llvm::Value *args[] = { dstAddr, srcValue, llvm::ConstantInt::get(Int32Ty, flags.getBitMask()) }; @@ -2139,7 +2142,7 @@ public: llvm::Value *flagsVal = llvm::ConstantInt::get(CGF.Int32Ty, flags); llvm::FunctionCallee fn = CGF.CGM.getBlockObjectAssign(); - llvm::Value *args[] = { destField.getPointer(), srcValue, flagsVal }; + llvm::Value *args[] = {destField.emitRawPointer(CGF), srcValue, flagsVal}; CGF.EmitNounwindRuntimeCall(fn, args); } @@ -2696,7 +2699,8 @@ void CodeGenFunction::emitByrefStructureInit(const AutoVarEmission &emission) { storeHeaderField(V, getPointerSize(), "byref.isa"); // Store the address of the variable into its own forwarding pointer. - storeHeaderField(addr.getPointer(), getPointerSize(), "byref.forwarding"); + storeHeaderField(addr.emitRawPointer(*this), getPointerSize(), + "byref.forwarding"); // Blocks ABI: // c) the flags field is set to either 0 if no helper functions are diff --git a/clang/lib/CodeGen/CGBlocks.h b/clang/lib/CodeGen/CGBlocks.h index 4ef1ae9f3365..8d10c4f69b20 100644 --- a/clang/lib/CodeGen/CGBlocks.h +++ b/clang/lib/CodeGen/CGBlocks.h @@ -271,7 +271,8 @@ public: /// The block's captures. Non-constant captures are sorted by their offsets. llvm::SmallVector SortedCaptures; - Address LocalAddress; + // Currently we assume that block-pointer types are never signed. + RawAddress LocalAddress; llvm::StructType *StructureType; const BlockDecl *Block; const BlockExpr *BlockExpression; diff --git a/clang/lib/CodeGen/CGBuilder.h b/clang/lib/CodeGen/CGBuilder.h index bf5ab171d720..6dd9da7c4cad 100644 --- a/clang/lib/CodeGen/CGBuilder.h +++ b/clang/lib/CodeGen/CGBuilder.h @@ -10,7 +10,9 @@ #define LLVM_CLANG_LIB_CODEGEN_CGBUILDER_H #include "Address.h" +#include "CGValue.h" #include "CodeGenTypeCache.h" +#include "llvm/Analysis/Utils/Local.h" #include "llvm/IR/DataLayout.h" #include "llvm/IR/IRBuilder.h" #include "llvm/IR/Type.h" @@ -18,12 +20,15 @@ namespace clang { namespace CodeGen { +class CGBuilderTy; class CodeGenFunction; /// This is an IRBuilder insertion helper that forwards to /// CodeGenFunction::InsertHelper, which adds necessary metadata to /// instructions. class CGBuilderInserter final : public llvm::IRBuilderDefaultInserter { + friend CGBuilderTy; + public: CGBuilderInserter() = default; explicit CGBuilderInserter(CodeGenFunction *CGF) : CGF(CGF) {} @@ -43,10 +48,42 @@ typedef llvm::IRBuilder CGBuilderBaseTy; class CGBuilderTy : public CGBuilderBaseTy { + friend class Address; + /// Storing a reference to the type cache here makes it a lot easier /// to build natural-feeling, target-specific IR. const CodeGenTypeCache &TypeCache; + CodeGenFunction *getCGF() const { return getInserter().CGF; } + + llvm::Value *emitRawPointerFromAddress(Address Addr) const { + return Addr.getBasePointer(); + } + + template + Address createConstGEP2_32(Address Addr, unsigned Idx0, unsigned Idx1, + const llvm::Twine &Name) { + const llvm::DataLayout &DL = BB->getParent()->getParent()->getDataLayout(); + llvm::GetElementPtrInst *GEP; + if (IsInBounds) + GEP = cast(CreateConstInBoundsGEP2_32( + Addr.getElementType(), emitRawPointerFromAddress(Addr), Idx0, Idx1, + Name)); + else + GEP = cast(CreateConstGEP2_32( + Addr.getElementType(), emitRawPointerFromAddress(Addr), Idx0, Idx1, + Name)); + llvm::APInt Offset( + DL.getIndexSizeInBits(Addr.getType()->getPointerAddressSpace()), 0, + /*isSigned=*/true); + if (!GEP->accumulateConstantOffset(DL, Offset)) + llvm_unreachable("offset of GEP with constants is always computable"); + return Address(GEP, GEP->getResultElementType(), + Addr.getAlignment().alignmentAtOffset( + CharUnits::fromQuantity(Offset.getSExtValue())), + IsInBounds ? Addr.isKnownNonNull() : NotKnownNonNull); + } + public: CGBuilderTy(const CodeGenTypeCache &TypeCache, llvm::LLVMContext &C) : CGBuilderBaseTy(C), TypeCache(TypeCache) {} @@ -69,20 +106,22 @@ public: // Note that we intentionally hide the CreateLoad APIs that don't // take an alignment. llvm::LoadInst *CreateLoad(Address Addr, const llvm::Twine &Name = "") { - return CreateAlignedLoad(Addr.getElementType(), Addr.getPointer(), + return CreateAlignedLoad(Addr.getElementType(), + emitRawPointerFromAddress(Addr), Addr.getAlignment().getAsAlign(), Name); } llvm::LoadInst *CreateLoad(Address Addr, const char *Name) { // This overload is required to prevent string literals from // ending up in the IsVolatile overload. - return CreateAlignedLoad(Addr.getElementType(), Addr.getPointer(), + return CreateAlignedLoad(Addr.getElementType(), + emitRawPointerFromAddress(Addr), Addr.getAlignment().getAsAlign(), Name); } llvm::LoadInst *CreateLoad(Address Addr, bool IsVolatile, const llvm::Twine &Name = "") { - return CreateAlignedLoad(Addr.getElementType(), Addr.getPointer(), - Addr.getAlignment().getAsAlign(), IsVolatile, - Name); + return CreateAlignedLoad( + Addr.getElementType(), emitRawPointerFromAddress(Addr), + Addr.getAlignment().getAsAlign(), IsVolatile, Name); } using CGBuilderBaseTy::CreateAlignedLoad; @@ -96,7 +135,7 @@ public: // take an alignment. llvm::StoreInst *CreateStore(llvm::Value *Val, Address Addr, bool IsVolatile = false) { - return CreateAlignedStore(Val, Addr.getPointer(), + return CreateAlignedStore(Val, emitRawPointerFromAddress(Addr), Addr.getAlignment().getAsAlign(), IsVolatile); } @@ -132,33 +171,41 @@ public: llvm::AtomicOrdering FailureOrdering, llvm::SyncScope::ID SSID = llvm::SyncScope::System) { return CGBuilderBaseTy::CreateAtomicCmpXchg( - Addr.getPointer(), Cmp, New, Addr.getAlignment().getAsAlign(), - SuccessOrdering, FailureOrdering, SSID); + Addr.emitRawPointer(*getCGF()), Cmp, New, + Addr.getAlignment().getAsAlign(), SuccessOrdering, FailureOrdering, + SSID); } llvm::AtomicRMWInst * CreateAtomicRMW(llvm::AtomicRMWInst::BinOp Op, Address Addr, llvm::Value *Val, llvm::AtomicOrdering Ordering, llvm::SyncScope::ID SSID = llvm::SyncScope::System) { - return CGBuilderBaseTy::CreateAtomicRMW(Op, Addr.getPointer(), Val, - Addr.getAlignment().getAsAlign(), - Ordering, SSID); + return CGBuilderBaseTy::CreateAtomicRMW( + Op, Addr.emitRawPointer(*getCGF()), Val, + Addr.getAlignment().getAsAlign(), Ordering, SSID); } using CGBuilderBaseTy::CreateAddrSpaceCast; Address CreateAddrSpaceCast(Address Addr, llvm::Type *Ty, + llvm::Type *ElementTy, const llvm::Twine &Name = "") { - return Addr.withPointer(CreateAddrSpaceCast(Addr.getPointer(), Ty, Name), - Addr.isKnownNonNull()); + if (!Addr.hasOffset()) + return Address(CreateAddrSpaceCast(Addr.getBasePointer(), Ty, Name), + ElementTy, Addr.getAlignment(), nullptr, + Addr.isKnownNonNull()); + // Eagerly force a raw address if these is an offset. + return RawAddress( + CreateAddrSpaceCast(Addr.emitRawPointer(*getCGF()), Ty, Name), + ElementTy, Addr.getAlignment(), Addr.isKnownNonNull()); } using CGBuilderBaseTy::CreatePointerBitCastOrAddrSpaceCast; Address CreatePointerBitCastOrAddrSpaceCast(Address Addr, llvm::Type *Ty, llvm::Type *ElementTy, const llvm::Twine &Name = "") { - llvm::Value *Ptr = - CreatePointerBitCastOrAddrSpaceCast(Addr.getPointer(), Ty, Name); - return Address(Ptr, ElementTy, Addr.getAlignment(), Addr.isKnownNonNull()); + if (Addr.getType()->getAddressSpace() == Ty->getPointerAddressSpace()) + return Addr.withElementType(ElementTy); + return CreateAddrSpaceCast(Addr, Ty, ElementTy, Name); } /// Given @@ -176,10 +223,11 @@ public: const llvm::StructLayout *Layout = DL.getStructLayout(ElTy); auto Offset = CharUnits::fromQuantity(Layout->getElementOffset(Index)); - return Address( - CreateStructGEP(Addr.getElementType(), Addr.getPointer(), Index, Name), - ElTy->getElementType(Index), - Addr.getAlignment().alignmentAtOffset(Offset), Addr.isKnownNonNull()); + return Address(CreateStructGEP(Addr.getElementType(), Addr.getBasePointer(), + Index, Name), + ElTy->getElementType(Index), + Addr.getAlignment().alignmentAtOffset(Offset), + Addr.isKnownNonNull()); } /// Given @@ -198,7 +246,7 @@ public: CharUnits::fromQuantity(DL.getTypeAllocSize(ElTy->getElementType())); return Address( - CreateInBoundsGEP(Addr.getElementType(), Addr.getPointer(), + CreateInBoundsGEP(Addr.getElementType(), Addr.getBasePointer(), {getSize(CharUnits::Zero()), getSize(Index)}, Name), ElTy->getElementType(), Addr.getAlignment().alignmentAtOffset(Index * EltSize), @@ -216,10 +264,10 @@ public: const llvm::DataLayout &DL = BB->getParent()->getParent()->getDataLayout(); CharUnits EltSize = CharUnits::fromQuantity(DL.getTypeAllocSize(ElTy)); - return Address(CreateInBoundsGEP(Addr.getElementType(), Addr.getPointer(), - getSize(Index), Name), - ElTy, Addr.getAlignment().alignmentAtOffset(Index * EltSize), - Addr.isKnownNonNull()); + return Address( + CreateInBoundsGEP(ElTy, Addr.getBasePointer(), getSize(Index), Name), + ElTy, Addr.getAlignment().alignmentAtOffset(Index * EltSize), + Addr.isKnownNonNull()); } /// Given @@ -229,110 +277,133 @@ public: /// where i64 is actually the target word size. Address CreateConstGEP(Address Addr, uint64_t Index, const llvm::Twine &Name = "") { + llvm::Type *ElTy = Addr.getElementType(); const llvm::DataLayout &DL = BB->getParent()->getParent()->getDataLayout(); - CharUnits EltSize = - CharUnits::fromQuantity(DL.getTypeAllocSize(Addr.getElementType())); + CharUnits EltSize = CharUnits::fromQuantity(DL.getTypeAllocSize(ElTy)); - return Address(CreateGEP(Addr.getElementType(), Addr.getPointer(), - getSize(Index), Name), + return Address(CreateGEP(ElTy, Addr.getBasePointer(), getSize(Index), Name), Addr.getElementType(), - Addr.getAlignment().alignmentAtOffset(Index * EltSize), - NotKnownNonNull); + Addr.getAlignment().alignmentAtOffset(Index * EltSize)); } /// Create GEP with single dynamic index. The address alignment is reduced /// according to the element size. using CGBuilderBaseTy::CreateGEP; - Address CreateGEP(Address Addr, llvm::Value *Index, + Address CreateGEP(CodeGenFunction &CGF, Address Addr, llvm::Value *Index, const llvm::Twine &Name = "") { const llvm::DataLayout &DL = BB->getParent()->getParent()->getDataLayout(); CharUnits EltSize = CharUnits::fromQuantity(DL.getTypeAllocSize(Addr.getElementType())); return Address( - CreateGEP(Addr.getElementType(), Addr.getPointer(), Index, Name), + CreateGEP(Addr.getElementType(), Addr.emitRawPointer(CGF), Index, Name), Addr.getElementType(), - Addr.getAlignment().alignmentOfArrayElement(EltSize), NotKnownNonNull); + Addr.getAlignment().alignmentOfArrayElement(EltSize)); } /// Given a pointer to i8, adjust it by a given constant offset. Address CreateConstInBoundsByteGEP(Address Addr, CharUnits Offset, const llvm::Twine &Name = "") { assert(Addr.getElementType() == TypeCache.Int8Ty); - return Address(CreateInBoundsGEP(Addr.getElementType(), Addr.getPointer(), - getSize(Offset), Name), - Addr.getElementType(), - Addr.getAlignment().alignmentAtOffset(Offset), - Addr.isKnownNonNull()); + return Address( + CreateInBoundsGEP(Addr.getElementType(), Addr.getBasePointer(), + getSize(Offset), Name), + Addr.getElementType(), Addr.getAlignment().alignmentAtOffset(Offset), + Addr.isKnownNonNull()); } + Address CreateConstByteGEP(Address Addr, CharUnits Offset, const llvm::Twine &Name = "") { assert(Addr.getElementType() == TypeCache.Int8Ty); - return Address(CreateGEP(Addr.getElementType(), Addr.getPointer(), + return Address(CreateGEP(Addr.getElementType(), Addr.getBasePointer(), getSize(Offset), Name), Addr.getElementType(), - Addr.getAlignment().alignmentAtOffset(Offset), - NotKnownNonNull); + Addr.getAlignment().alignmentAtOffset(Offset)); } using CGBuilderBaseTy::CreateConstInBoundsGEP2_32; Address CreateConstInBoundsGEP2_32(Address Addr, unsigned Idx0, unsigned Idx1, const llvm::Twine &Name = "") { - const llvm::DataLayout &DL = BB->getParent()->getParent()->getDataLayout(); + return createConstGEP2_32(Addr, Idx0, Idx1, Name); + } - auto *GEP = cast(CreateConstInBoundsGEP2_32( - Addr.getElementType(), Addr.getPointer(), Idx0, Idx1, Name)); - llvm::APInt Offset( - DL.getIndexSizeInBits(Addr.getType()->getPointerAddressSpace()), 0, - /*isSigned=*/true); - if (!GEP->accumulateConstantOffset(DL, Offset)) - llvm_unreachable("offset of GEP with constants is always computable"); - return Address(GEP, GEP->getResultElementType(), - Addr.getAlignment().alignmentAtOffset( - CharUnits::fromQuantity(Offset.getSExtValue())), - Addr.isKnownNonNull()); + using CGBuilderBaseTy::CreateConstGEP2_32; + Address CreateConstGEP2_32(Address Addr, unsigned Idx0, unsigned Idx1, + const llvm::Twine &Name = "") { + return createConstGEP2_32(Addr, Idx0, Idx1, Name); + } + + Address CreateGEP(Address Addr, ArrayRef IdxList, + llvm::Type *ElementType, CharUnits Align, + const Twine &Name = "") { + llvm::Value *Ptr = emitRawPointerFromAddress(Addr); + return RawAddress(CreateGEP(Addr.getElementType(), Ptr, IdxList, Name), + ElementType, Align); + } + + using CGBuilderBaseTy::CreateInBoundsGEP; + Address CreateInBoundsGEP(Address Addr, ArrayRef IdxList, + llvm::Type *ElementType, CharUnits Align, + const Twine &Name = "") { + return RawAddress(CreateInBoundsGEP(Addr.getElementType(), + emitRawPointerFromAddress(Addr), + IdxList, Name), + ElementType, Align, Addr.isKnownNonNull()); + } + + using CGBuilderBaseTy::CreateIsNull; + llvm::Value *CreateIsNull(Address Addr, const Twine &Name = "") { + if (!Addr.hasOffset()) + return CreateIsNull(Addr.getBasePointer(), Name); + // The pointer isn't null if Addr has an offset since offsets can always + // be applied inbound. + return llvm::ConstantInt::getFalse(Context); } using CGBuilderBaseTy::CreateMemCpy; llvm::CallInst *CreateMemCpy(Address Dest, Address Src, llvm::Value *Size, bool IsVolatile = false) { - return CreateMemCpy(Dest.getPointer(), Dest.getAlignment().getAsAlign(), - Src.getPointer(), Src.getAlignment().getAsAlign(), Size, - IsVolatile); + llvm::Value *DestPtr = emitRawPointerFromAddress(Dest); + llvm::Value *SrcPtr = emitRawPointerFromAddress(Src); + return CreateMemCpy(DestPtr, Dest.getAlignment().getAsAlign(), SrcPtr, + Src.getAlignment().getAsAlign(), Size, IsVolatile); } llvm::CallInst *CreateMemCpy(Address Dest, Address Src, uint64_t Size, bool IsVolatile = false) { - return CreateMemCpy(Dest.getPointer(), Dest.getAlignment().getAsAlign(), - Src.getPointer(), Src.getAlignment().getAsAlign(), Size, - IsVolatile); + llvm::Value *DestPtr = emitRawPointerFromAddress(Dest); + llvm::Value *SrcPtr = emitRawPointerFromAddress(Src); + return CreateMemCpy(DestPtr, Dest.getAlignment().getAsAlign(), SrcPtr, + Src.getAlignment().getAsAlign(), Size, IsVolatile); } using CGBuilderBaseTy::CreateMemCpyInline; llvm::CallInst *CreateMemCpyInline(Address Dest, Address Src, uint64_t Size) { - return CreateMemCpyInline( - Dest.getPointer(), Dest.getAlignment().getAsAlign(), Src.getPointer(), - Src.getAlignment().getAsAlign(), getInt64(Size)); + llvm::Value *DestPtr = emitRawPointerFromAddress(Dest); + llvm::Value *SrcPtr = emitRawPointerFromAddress(Src); + return CreateMemCpyInline(DestPtr, Dest.getAlignment().getAsAlign(), SrcPtr, + Src.getAlignment().getAsAlign(), getInt64(Size)); } using CGBuilderBaseTy::CreateMemMove; llvm::CallInst *CreateMemMove(Address Dest, Address Src, llvm::Value *Size, bool IsVolatile = false) { - return CreateMemMove(Dest.getPointer(), Dest.getAlignment().getAsAlign(), - Src.getPointer(), Src.getAlignment().getAsAlign(), - Size, IsVolatile); + llvm::Value *DestPtr = emitRawPointerFromAddress(Dest); + llvm::Value *SrcPtr = emitRawPointerFromAddress(Src); + return CreateMemMove(DestPtr, Dest.getAlignment().getAsAlign(), SrcPtr, + Src.getAlignment().getAsAlign(), Size, IsVolatile); } using CGBuilderBaseTy::CreateMemSet; llvm::CallInst *CreateMemSet(Address Dest, llvm::Value *Value, llvm::Value *Size, bool IsVolatile = false) { - return CreateMemSet(Dest.getPointer(), Value, Size, + return CreateMemSet(emitRawPointerFromAddress(Dest), Value, Size, Dest.getAlignment().getAsAlign(), IsVolatile); } using CGBuilderBaseTy::CreateMemSetInline; llvm::CallInst *CreateMemSetInline(Address Dest, llvm::Value *Value, uint64_t Size) { - return CreateMemSetInline(Dest.getPointer(), + return CreateMemSetInline(emitRawPointerFromAddress(Dest), Dest.getAlignment().getAsAlign(), Value, getInt64(Size)); } @@ -346,16 +417,31 @@ public: const llvm::StructLayout *Layout = DL.getStructLayout(ElTy); auto Offset = CharUnits::fromQuantity(Layout->getElementOffset(Index)); - return Address(CreatePreserveStructAccessIndex(ElTy, Addr.getPointer(), - Index, FieldIndex, DbgInfo), - ElTy->getElementType(Index), - Addr.getAlignment().alignmentAtOffset(Offset)); + return Address( + CreatePreserveStructAccessIndex(ElTy, emitRawPointerFromAddress(Addr), + Index, FieldIndex, DbgInfo), + ElTy->getElementType(Index), + Addr.getAlignment().alignmentAtOffset(Offset)); + } + + using CGBuilderBaseTy::CreatePreserveUnionAccessIndex; + Address CreatePreserveUnionAccessIndex(Address Addr, unsigned FieldIndex, + llvm::MDNode *DbgInfo) { + Addr.replaceBasePointer(CreatePreserveUnionAccessIndex( + Addr.getBasePointer(), FieldIndex, DbgInfo)); + return Addr; } using CGBuilderBaseTy::CreateLaunderInvariantGroup; Address CreateLaunderInvariantGroup(Address Addr) { - return Addr.withPointer(CreateLaunderInvariantGroup(Addr.getPointer()), - Addr.isKnownNonNull()); + Addr.replaceBasePointer(CreateLaunderInvariantGroup(Addr.getBasePointer())); + return Addr; + } + + using CGBuilderBaseTy::CreateStripInvariantGroup; + Address CreateStripInvariantGroup(Address Addr) { + Addr.replaceBasePointer(CreateStripInvariantGroup(Addr.getBasePointer())); + return Addr; } }; diff --git a/clang/lib/CodeGen/CGBuiltin.cpp b/clang/lib/CodeGen/CGBuiltin.cpp index fdb517eb254d..5ab5917c0c8d 100644 --- a/clang/lib/CodeGen/CGBuiltin.cpp +++ b/clang/lib/CodeGen/CGBuiltin.cpp @@ -2117,9 +2117,9 @@ llvm::Function *CodeGenFunction::generateBuiltinOSLogHelperFunction( auto AL = ApplyDebugLocation::CreateArtificial(*this); CharUnits Offset; - Address BufAddr = - Address(Builder.CreateLoad(GetAddrOfLocalVar(Args[0]), "buf"), Int8Ty, - BufferAlignment); + Address BufAddr = makeNaturalAddressForPointer( + Builder.CreateLoad(GetAddrOfLocalVar(Args[0]), "buf"), Ctx.VoidTy, + BufferAlignment); Builder.CreateStore(Builder.getInt8(Layout.getSummaryByte()), Builder.CreateConstByteGEP(BufAddr, Offset++, "summary")); Builder.CreateStore(Builder.getInt8(Layout.getNumArgsByte()), @@ -2162,7 +2162,7 @@ RValue CodeGenFunction::emitBuiltinOSLogFormat(const CallExpr &E) { // Ignore argument 1, the format string. It is not currently used. CallArgList Args; - Args.add(RValue::get(BufAddr.getPointer()), Ctx.VoidPtrTy); + Args.add(RValue::get(BufAddr.emitRawPointer(*this)), Ctx.VoidPtrTy); for (const auto &Item : Layout.Items) { int Size = Item.getSizeByte(); @@ -2202,8 +2202,8 @@ RValue CodeGenFunction::emitBuiltinOSLogFormat(const CallExpr &E) { if (!isa(ArgVal)) { CleanupKind Cleanup = getARCCleanupKind(); QualType Ty = TheExpr->getType(); - Address Alloca = Address::invalid(); - Address Addr = CreateMemTemp(Ty, "os.log.arg", &Alloca); + RawAddress Alloca = RawAddress::invalid(); + RawAddress Addr = CreateMemTemp(Ty, "os.log.arg", &Alloca); ArgVal = EmitARCRetain(Ty, ArgVal); Builder.CreateStore(ArgVal, Addr); pushLifetimeExtendedDestroy(Cleanup, Alloca, Ty, @@ -2236,7 +2236,7 @@ RValue CodeGenFunction::emitBuiltinOSLogFormat(const CallExpr &E) { llvm::Function *F = CodeGenFunction(CGM).generateBuiltinOSLogHelperFunction( Layout, BufAddr.getAlignment()); EmitCall(FI, CGCallee::forDirect(F), ReturnValueSlot(), Args); - return RValue::get(BufAddr.getPointer()); + return RValue::get(BufAddr, *this); } static bool isSpecialUnsignedMultiplySignedResult( @@ -2984,7 +2984,7 @@ RValue CodeGenFunction::EmitBuiltinExpr(const GlobalDecl GD, unsigned BuiltinID, // Check NonnullAttribute/NullabilityArg and Alignment. auto EmitArgCheck = [&](TypeCheckKind Kind, Address A, const Expr *Arg, unsigned ParmNum) { - Value *Val = A.getPointer(); + Value *Val = A.emitRawPointer(*this); EmitNonNullArgCheck(RValue::get(Val), Arg->getType(), Arg->getExprLoc(), FD, ParmNum); @@ -3013,12 +3013,12 @@ RValue CodeGenFunction::EmitBuiltinExpr(const GlobalDecl GD, unsigned BuiltinID, case Builtin::BI__builtin_va_end: EmitVAStartEnd(BuiltinID == Builtin::BI__va_start ? EmitScalarExpr(E->getArg(0)) - : EmitVAListRef(E->getArg(0)).getPointer(), + : EmitVAListRef(E->getArg(0)).emitRawPointer(*this), BuiltinID != Builtin::BI__builtin_va_end); return RValue::get(nullptr); case Builtin::BI__builtin_va_copy: { - Value *DstPtr = EmitVAListRef(E->getArg(0)).getPointer(); - Value *SrcPtr = EmitVAListRef(E->getArg(1)).getPointer(); + Value *DstPtr = EmitVAListRef(E->getArg(0)).emitRawPointer(*this); + Value *SrcPtr = EmitVAListRef(E->getArg(1)).emitRawPointer(*this); Builder.CreateCall(CGM.getIntrinsic(Intrinsic::vacopy, {DstPtr->getType()}), {DstPtr, SrcPtr}); return RValue::get(nullptr); @@ -3849,13 +3849,13 @@ RValue CodeGenFunction::EmitBuiltinExpr(const GlobalDecl GD, unsigned BuiltinID, bool IsVolatile = PtrTy->getPointeeType().isVolatileQualified(); Address Src = EmitPointerWithAlignment(E->getArg(0)); - EmitNonNullArgCheck(RValue::get(Src.getPointer()), E->getArg(0)->getType(), - E->getArg(0)->getExprLoc(), FD, 0); + EmitNonNullArgCheck(RValue::get(Src.emitRawPointer(*this)), + E->getArg(0)->getType(), E->getArg(0)->getExprLoc(), FD, + 0); Value *Result = MB.CreateColumnMajorLoad( - Src.getElementType(), Src.getPointer(), + Src.getElementType(), Src.emitRawPointer(*this), Align(Src.getAlignment().getQuantity()), Stride, IsVolatile, - ResultTy->getNumRows(), ResultTy->getNumColumns(), - "matrix"); + ResultTy->getNumRows(), ResultTy->getNumColumns(), "matrix"); return RValue::get(Result); } @@ -3870,11 +3870,13 @@ RValue CodeGenFunction::EmitBuiltinExpr(const GlobalDecl GD, unsigned BuiltinID, assert(PtrTy && "arg1 must be of pointer type"); bool IsVolatile = PtrTy->getPointeeType().isVolatileQualified(); - EmitNonNullArgCheck(RValue::get(Dst.getPointer()), E->getArg(1)->getType(), - E->getArg(1)->getExprLoc(), FD, 0); + EmitNonNullArgCheck(RValue::get(Dst.emitRawPointer(*this)), + E->getArg(1)->getType(), E->getArg(1)->getExprLoc(), FD, + 0); Value *Result = MB.CreateColumnMajorStore( - Matrix, Dst.getPointer(), Align(Dst.getAlignment().getQuantity()), - Stride, IsVolatile, MatrixTy->getNumRows(), MatrixTy->getNumColumns()); + Matrix, Dst.emitRawPointer(*this), + Align(Dst.getAlignment().getQuantity()), Stride, IsVolatile, + MatrixTy->getNumRows(), MatrixTy->getNumColumns()); return RValue::get(Result); } @@ -4033,7 +4035,7 @@ RValue CodeGenFunction::EmitBuiltinExpr(const GlobalDecl GD, unsigned BuiltinID, case Builtin::BI__builtin_bzero: { Address Dest = EmitPointerWithAlignment(E->getArg(0)); Value *SizeVal = EmitScalarExpr(E->getArg(1)); - EmitNonNullArgCheck(RValue::get(Dest.getPointer()), E->getArg(0)->getType(), + EmitNonNullArgCheck(Dest, E->getArg(0)->getType(), E->getArg(0)->getExprLoc(), FD, 0); Builder.CreateMemSet(Dest, Builder.getInt8(0), SizeVal, false); return RValue::get(nullptr); @@ -4044,10 +4046,12 @@ RValue CodeGenFunction::EmitBuiltinExpr(const GlobalDecl GD, unsigned BuiltinID, Address Src = EmitPointerWithAlignment(E->getArg(0)); Address Dest = EmitPointerWithAlignment(E->getArg(1)); Value *SizeVal = EmitScalarExpr(E->getArg(2)); - EmitNonNullArgCheck(RValue::get(Src.getPointer()), E->getArg(0)->getType(), - E->getArg(0)->getExprLoc(), FD, 0); - EmitNonNullArgCheck(RValue::get(Dest.getPointer()), E->getArg(1)->getType(), - E->getArg(1)->getExprLoc(), FD, 0); + EmitNonNullArgCheck(RValue::get(Src.emitRawPointer(*this)), + E->getArg(0)->getType(), E->getArg(0)->getExprLoc(), FD, + 0); + EmitNonNullArgCheck(RValue::get(Dest.emitRawPointer(*this)), + E->getArg(1)->getType(), E->getArg(1)->getExprLoc(), FD, + 0); Builder.CreateMemMove(Dest, Src, SizeVal, false); return RValue::get(nullptr); } @@ -4064,10 +4068,10 @@ RValue CodeGenFunction::EmitBuiltinExpr(const GlobalDecl GD, unsigned BuiltinID, Builder.CreateMemCpy(Dest, Src, SizeVal, false); if (BuiltinID == Builtin::BImempcpy || BuiltinID == Builtin::BI__builtin_mempcpy) - return RValue::get(Builder.CreateInBoundsGEP(Dest.getElementType(), - Dest.getPointer(), SizeVal)); + return RValue::get(Builder.CreateInBoundsGEP( + Dest.getElementType(), Dest.emitRawPointer(*this), SizeVal)); else - return RValue::get(Dest.getPointer()); + return RValue::get(Dest, *this); } case Builtin::BI__builtin_memcpy_inline: { @@ -4099,7 +4103,7 @@ RValue CodeGenFunction::EmitBuiltinExpr(const GlobalDecl GD, unsigned BuiltinID, Address Src = EmitPointerWithAlignment(E->getArg(1)); Value *SizeVal = llvm::ConstantInt::get(Builder.getContext(), Size); Builder.CreateMemCpy(Dest, Src, SizeVal, false); - return RValue::get(Dest.getPointer()); + return RValue::get(Dest, *this); } case Builtin::BI__builtin_objc_memmove_collectable: { @@ -4108,7 +4112,7 @@ RValue CodeGenFunction::EmitBuiltinExpr(const GlobalDecl GD, unsigned BuiltinID, Value *SizeVal = EmitScalarExpr(E->getArg(2)); CGM.getObjCRuntime().EmitGCMemmoveCollectable(*this, DestAddr, SrcAddr, SizeVal); - return RValue::get(DestAddr.getPointer()); + return RValue::get(DestAddr, *this); } case Builtin::BI__builtin___memmove_chk: { @@ -4125,7 +4129,7 @@ RValue CodeGenFunction::EmitBuiltinExpr(const GlobalDecl GD, unsigned BuiltinID, Address Src = EmitPointerWithAlignment(E->getArg(1)); Value *SizeVal = llvm::ConstantInt::get(Builder.getContext(), Size); Builder.CreateMemMove(Dest, Src, SizeVal, false); - return RValue::get(Dest.getPointer()); + return RValue::get(Dest, *this); } case Builtin::BImemmove: @@ -4136,7 +4140,7 @@ RValue CodeGenFunction::EmitBuiltinExpr(const GlobalDecl GD, unsigned BuiltinID, EmitArgCheck(TCK_Store, Dest, E->getArg(0), 0); EmitArgCheck(TCK_Load, Src, E->getArg(1), 1); Builder.CreateMemMove(Dest, Src, SizeVal, false); - return RValue::get(Dest.getPointer()); + return RValue::get(Dest, *this); } case Builtin::BImemset: case Builtin::BI__builtin_memset: { @@ -4144,10 +4148,10 @@ RValue CodeGenFunction::EmitBuiltinExpr(const GlobalDecl GD, unsigned BuiltinID, Value *ByteVal = Builder.CreateTrunc(EmitScalarExpr(E->getArg(1)), Builder.getInt8Ty()); Value *SizeVal = EmitScalarExpr(E->getArg(2)); - EmitNonNullArgCheck(RValue::get(Dest.getPointer()), E->getArg(0)->getType(), + EmitNonNullArgCheck(Dest, E->getArg(0)->getType(), E->getArg(0)->getExprLoc(), FD, 0); Builder.CreateMemSet(Dest, ByteVal, SizeVal, false); - return RValue::get(Dest.getPointer()); + return RValue::get(Dest, *this); } case Builtin::BI__builtin_memset_inline: { Address Dest = EmitPointerWithAlignment(E->getArg(0)); @@ -4155,8 +4159,9 @@ RValue CodeGenFunction::EmitBuiltinExpr(const GlobalDecl GD, unsigned BuiltinID, Builder.CreateTrunc(EmitScalarExpr(E->getArg(1)), Builder.getInt8Ty()); uint64_t Size = E->getArg(2)->EvaluateKnownConstInt(getContext()).getZExtValue(); - EmitNonNullArgCheck(RValue::get(Dest.getPointer()), E->getArg(0)->getType(), - E->getArg(0)->getExprLoc(), FD, 0); + EmitNonNullArgCheck(RValue::get(Dest.emitRawPointer(*this)), + E->getArg(0)->getType(), E->getArg(0)->getExprLoc(), FD, + 0); Builder.CreateMemSetInline(Dest, ByteVal, Size); return RValue::get(nullptr); } @@ -4175,7 +4180,7 @@ RValue CodeGenFunction::EmitBuiltinExpr(const GlobalDecl GD, unsigned BuiltinID, Builder.getInt8Ty()); Value *SizeVal = llvm::ConstantInt::get(Builder.getContext(), Size); Builder.CreateMemSet(Dest, ByteVal, SizeVal, false); - return RValue::get(Dest.getPointer()); + return RValue::get(Dest, *this); } case Builtin::BI__builtin_wmemchr: { // The MSVC runtime library does not provide a definition of wmemchr, so we @@ -4397,14 +4402,14 @@ RValue CodeGenFunction::EmitBuiltinExpr(const GlobalDecl GD, unsigned BuiltinID, // Store the stack pointer to the setjmp buffer. Value *StackAddr = Builder.CreateStackSave(); - assert(Buf.getPointer()->getType() == StackAddr->getType()); + assert(Buf.emitRawPointer(*this)->getType() == StackAddr->getType()); Address StackSaveSlot = Builder.CreateConstInBoundsGEP(Buf, 2); Builder.CreateStore(StackAddr, StackSaveSlot); // Call LLVM's EH setjmp, which is lightweight. Function *F = CGM.getIntrinsic(Intrinsic::eh_sjlj_setjmp); - return RValue::get(Builder.CreateCall(F, Buf.getPointer())); + return RValue::get(Builder.CreateCall(F, Buf.emitRawPointer(*this))); } case Builtin::BI__builtin_longjmp: { Value *Buf = EmitScalarExpr(E->getArg(0)); @@ -5577,7 +5582,7 @@ RValue CodeGenFunction::EmitBuiltinExpr(const GlobalDecl GD, unsigned BuiltinID, llvm::Value *Queue = EmitScalarExpr(E->getArg(0)); llvm::Value *Flags = EmitScalarExpr(E->getArg(1)); LValue NDRangeL = EmitAggExprToLValue(E->getArg(2)); - llvm::Value *Range = NDRangeL.getAddress(*this).getPointer(); + llvm::Value *Range = NDRangeL.getAddress(*this).emitRawPointer(*this); llvm::Type *RangeTy = NDRangeL.getAddress(*this).getType(); if (NumArgs == 4) { @@ -5686,9 +5691,10 @@ RValue CodeGenFunction::EmitBuiltinExpr(const GlobalDecl GD, unsigned BuiltinID, getContext(), Expr::NPC_ValueDependentIsNotNull)) { EventWaitList = llvm::ConstantPointerNull::get(PtrTy); } else { - EventWaitList = E->getArg(4)->getType()->isArrayType() - ? EmitArrayToPointerDecay(E->getArg(4)).getPointer() - : EmitScalarExpr(E->getArg(4)); + EventWaitList = + E->getArg(4)->getType()->isArrayType() + ? EmitArrayToPointerDecay(E->getArg(4)).emitRawPointer(*this) + : EmitScalarExpr(E->getArg(4)); // Convert to generic address space. EventWaitList = Builder.CreatePointerCast(EventWaitList, PtrTy); } @@ -5784,7 +5790,7 @@ RValue CodeGenFunction::EmitBuiltinExpr(const GlobalDecl GD, unsigned BuiltinID, llvm::Type *GenericVoidPtrTy = Builder.getPtrTy( getContext().getTargetAddressSpace(LangAS::opencl_generic)); LValue NDRangeL = EmitAggExprToLValue(E->getArg(0)); - llvm::Value *NDRange = NDRangeL.getAddress(*this).getPointer(); + llvm::Value *NDRange = NDRangeL.getAddress(*this).emitRawPointer(*this); auto Info = CGM.getOpenCLRuntime().emitOpenCLEnqueuedBlock(*this, E->getArg(1)); Value *Kernel = @@ -5869,7 +5875,7 @@ RValue CodeGenFunction::EmitBuiltinExpr(const GlobalDecl GD, unsigned BuiltinID, auto PTy0 = FTy->getParamType(0); if (PTy0 != Arg0Val->getType()) { if (Arg0Ty->isArrayType()) - Arg0Val = EmitArrayToPointerDecay(Arg0).getPointer(); + Arg0Val = EmitArrayToPointerDecay(Arg0).emitRawPointer(*this); else Arg0Val = Builder.CreatePointerCast(Arg0Val, PTy0); } @@ -5907,7 +5913,7 @@ RValue CodeGenFunction::EmitBuiltinExpr(const GlobalDecl GD, unsigned BuiltinID, auto PTy1 = FTy->getParamType(1); if (PTy1 != Arg1Val->getType()) { if (Arg1Ty->isArrayType()) - Arg1Val = EmitArrayToPointerDecay(Arg1).getPointer(); + Arg1Val = EmitArrayToPointerDecay(Arg1).emitRawPointer(*this); else Arg1Val = Builder.CreatePointerCast(Arg1Val, PTy1); } @@ -5921,7 +5927,7 @@ RValue CodeGenFunction::EmitBuiltinExpr(const GlobalDecl GD, unsigned BuiltinID, case Builtin::BI__builtin_ms_va_start: case Builtin::BI__builtin_ms_va_end: return RValue::get( - EmitVAStartEnd(EmitMSVAListRef(E->getArg(0)).getPointer(), + EmitVAStartEnd(EmitMSVAListRef(E->getArg(0)).emitRawPointer(*this), BuiltinID == Builtin::BI__builtin_ms_va_start)); case Builtin::BI__builtin_ms_va_copy: { @@ -5963,8 +5969,8 @@ RValue CodeGenFunction::EmitBuiltinExpr(const GlobalDecl GD, unsigned BuiltinID, // If this is a predefined lib function (e.g. malloc), emit the call // using exactly the normal call path. if (getContext().BuiltinInfo.isPredefinedLibFunction(BuiltinID)) - return emitLibraryCall(*this, FD, E, - cast(EmitScalarExpr(E->getCallee()))); + return emitLibraryCall( + *this, FD, E, cast(EmitScalarExpr(E->getCallee()))); // Check that a call to a target specific builtin has the correct target // features. @@ -6081,7 +6087,7 @@ RValue CodeGenFunction::EmitBuiltinExpr(const GlobalDecl GD, unsigned BuiltinID, return RValue::get(nullptr); return RValue::get(V); case TEK_Aggregate: - return RValue::getAggregate(ReturnValue.getValue(), + return RValue::getAggregate(ReturnValue.getAddress(), ReturnValue.isVolatile()); case TEK_Complex: llvm_unreachable("No current target builtin returns complex"); @@ -8851,7 +8857,7 @@ Value *CodeGenFunction::EmitARMBuiltinExpr(unsigned BuiltinID, // Get the alignment for the argument in addition to the value; // we'll use it later. PtrOp0 = EmitPointerWithAlignment(E->getArg(0)); - Ops.push_back(PtrOp0.getPointer()); + Ops.push_back(PtrOp0.emitRawPointer(*this)); continue; } } @@ -8878,7 +8884,7 @@ Value *CodeGenFunction::EmitARMBuiltinExpr(unsigned BuiltinID, // Get the alignment for the argument in addition to the value; // we'll use it later. PtrOp1 = EmitPointerWithAlignment(E->getArg(1)); - Ops.push_back(PtrOp1.getPointer()); + Ops.push_back(PtrOp1.emitRawPointer(*this)); continue; } } @@ -9299,7 +9305,7 @@ Value *CodeGenFunction::EmitARMMVEBuiltinExpr(unsigned BuiltinID, if (ReturnValue.isNull()) return MvecOut; else - return Builder.CreateStore(MvecOut, ReturnValue.getValue()); + return Builder.CreateStore(MvecOut, ReturnValue.getAddress()); } case CustomCodeGen::VST24: { @@ -11479,7 +11485,7 @@ Value *CodeGenFunction::EmitAArch64BuiltinExpr(unsigned BuiltinID, // Get the alignment for the argument in addition to the value; // we'll use it later. PtrOp0 = EmitPointerWithAlignment(E->getArg(0)); - Ops.push_back(PtrOp0.getPointer()); + Ops.push_back(PtrOp0.emitRawPointer(*this)); continue; } } @@ -13345,15 +13351,15 @@ Value *CodeGenFunction::EmitBPFBuiltinExpr(unsigned BuiltinID, if (!getDebugInfo()) { CGM.Error(E->getExprLoc(), "using __builtin_preserve_field_info() without -g"); - return IsBitField ? EmitLValue(Arg).getBitFieldPointer() - : EmitLValue(Arg).getPointer(*this); + return IsBitField ? EmitLValue(Arg).getRawBitFieldPointer(*this) + : EmitLValue(Arg).emitRawPointer(*this); } // Enable underlying preserve_*_access_index() generation. bool OldIsInPreservedAIRegion = IsInPreservedAIRegion; IsInPreservedAIRegion = true; - Value *FieldAddr = IsBitField ? EmitLValue(Arg).getBitFieldPointer() - : EmitLValue(Arg).getPointer(*this); + Value *FieldAddr = IsBitField ? EmitLValue(Arg).getRawBitFieldPointer(*this) + : EmitLValue(Arg).emitRawPointer(*this); IsInPreservedAIRegion = OldIsInPreservedAIRegion; ConstantInt *C = cast(EmitScalarExpr(E->getArg(1))); @@ -14345,14 +14351,14 @@ Value *CodeGenFunction::EmitX86BuiltinExpr(unsigned BuiltinID, } case X86::BI_mm_setcsr: case X86::BI__builtin_ia32_ldmxcsr: { - Address Tmp = CreateMemTemp(E->getArg(0)->getType()); + RawAddress Tmp = CreateMemTemp(E->getArg(0)->getType()); Builder.CreateStore(Ops[0], Tmp); return Builder.CreateCall(CGM.getIntrinsic(Intrinsic::x86_sse_ldmxcsr), Tmp.getPointer()); } case X86::BI_mm_getcsr: case X86::BI__builtin_ia32_stmxcsr: { - Address Tmp = CreateMemTemp(E->getType()); + RawAddress Tmp = CreateMemTemp(E->getType()); Builder.CreateCall(CGM.getIntrinsic(Intrinsic::x86_sse_stmxcsr), Tmp.getPointer()); return Builder.CreateLoad(Tmp, "stmxcsr"); @@ -17627,7 +17633,8 @@ Value *CodeGenFunction::EmitPPCBuiltinExpr(unsigned BuiltinID, SmallVector Ops; for (unsigned i = 0, e = E->getNumArgs(); i != e; i++) if (E->getArg(i)->getType()->isArrayType()) - Ops.push_back(EmitArrayToPointerDecay(E->getArg(i)).getPointer()); + Ops.push_back( + EmitArrayToPointerDecay(E->getArg(i)).emitRawPointer(*this)); else Ops.push_back(EmitScalarExpr(E->getArg(i))); // The first argument of these two builtins is a pointer used to store their @@ -20089,14 +20096,14 @@ Value *CodeGenFunction::EmitNVPTXBuiltinExpr(unsigned BuiltinID, // Save returned values. assert(II.NumResults); if (II.NumResults == 1) { - Builder.CreateAlignedStore(Result, Dst.getPointer(), + Builder.CreateAlignedStore(Result, Dst.emitRawPointer(*this), CharUnits::fromQuantity(4)); } else { for (unsigned i = 0; i < II.NumResults; ++i) { Builder.CreateAlignedStore( Builder.CreateBitCast(Builder.CreateExtractValue(Result, i), Dst.getElementType()), - Builder.CreateGEP(Dst.getElementType(), Dst.getPointer(), + Builder.CreateGEP(Dst.getElementType(), Dst.emitRawPointer(*this), llvm::ConstantInt::get(IntTy, i)), CharUnits::fromQuantity(4)); } @@ -20136,7 +20143,7 @@ Value *CodeGenFunction::EmitNVPTXBuiltinExpr(unsigned BuiltinID, for (unsigned i = 0; i < II.NumResults; ++i) { Value *V = Builder.CreateAlignedLoad( Src.getElementType(), - Builder.CreateGEP(Src.getElementType(), Src.getPointer(), + Builder.CreateGEP(Src.getElementType(), Src.emitRawPointer(*this), llvm::ConstantInt::get(IntTy, i)), CharUnits::fromQuantity(4)); Values.push_back(Builder.CreateBitCast(V, ParamType)); @@ -20208,7 +20215,7 @@ Value *CodeGenFunction::EmitNVPTXBuiltinExpr(unsigned BuiltinID, for (unsigned i = 0; i < MI.NumEltsA; ++i) { Value *V = Builder.CreateAlignedLoad( SrcA.getElementType(), - Builder.CreateGEP(SrcA.getElementType(), SrcA.getPointer(), + Builder.CreateGEP(SrcA.getElementType(), SrcA.emitRawPointer(*this), llvm::ConstantInt::get(IntTy, i)), CharUnits::fromQuantity(4)); Values.push_back(Builder.CreateBitCast(V, AType)); @@ -20218,7 +20225,7 @@ Value *CodeGenFunction::EmitNVPTXBuiltinExpr(unsigned BuiltinID, for (unsigned i = 0; i < MI.NumEltsB; ++i) { Value *V = Builder.CreateAlignedLoad( SrcB.getElementType(), - Builder.CreateGEP(SrcB.getElementType(), SrcB.getPointer(), + Builder.CreateGEP(SrcB.getElementType(), SrcB.emitRawPointer(*this), llvm::ConstantInt::get(IntTy, i)), CharUnits::fromQuantity(4)); Values.push_back(Builder.CreateBitCast(V, BType)); @@ -20229,7 +20236,7 @@ Value *CodeGenFunction::EmitNVPTXBuiltinExpr(unsigned BuiltinID, for (unsigned i = 0; i < MI.NumEltsC; ++i) { Value *V = Builder.CreateAlignedLoad( SrcC.getElementType(), - Builder.CreateGEP(SrcC.getElementType(), SrcC.getPointer(), + Builder.CreateGEP(SrcC.getElementType(), SrcC.emitRawPointer(*this), llvm::ConstantInt::get(IntTy, i)), CharUnits::fromQuantity(4)); Values.push_back(Builder.CreateBitCast(V, CType)); @@ -20239,7 +20246,7 @@ Value *CodeGenFunction::EmitNVPTXBuiltinExpr(unsigned BuiltinID, for (unsigned i = 0; i < MI.NumEltsD; ++i) Builder.CreateAlignedStore( Builder.CreateBitCast(Builder.CreateExtractValue(Result, i), DType), - Builder.CreateGEP(Dst.getElementType(), Dst.getPointer(), + Builder.CreateGEP(Dst.getElementType(), Dst.emitRawPointer(*this), llvm::ConstantInt::get(IntTy, i)), CharUnits::fromQuantity(4)); return Result; @@ -20497,7 +20504,7 @@ struct BuiltinAlignArgs { BuiltinAlignArgs(const CallExpr *E, CodeGenFunction &CGF) { QualType AstType = E->getArg(0)->getType(); if (AstType->isArrayType()) - Src = CGF.EmitArrayToPointerDecay(E->getArg(0)).getPointer(); + Src = CGF.EmitArrayToPointerDecay(E->getArg(0)).emitRawPointer(CGF); else Src = CGF.EmitScalarExpr(E->getArg(0)); SrcType = Src->getType(); @@ -21115,7 +21122,7 @@ Value *CodeGenFunction::EmitWebAssemblyBuiltinExpr(unsigned BuiltinID, } case WebAssembly::BI__builtin_wasm_table_get: { assert(E->getArg(0)->getType()->isArrayType()); - Value *Table = EmitArrayToPointerDecay(E->getArg(0)).getPointer(); + Value *Table = EmitArrayToPointerDecay(E->getArg(0)).emitRawPointer(*this); Value *Index = EmitScalarExpr(E->getArg(1)); Function *Callee; if (E->getType().isWebAssemblyExternrefType()) @@ -21129,7 +21136,7 @@ Value *CodeGenFunction::EmitWebAssemblyBuiltinExpr(unsigned BuiltinID, } case WebAssembly::BI__builtin_wasm_table_set: { assert(E->getArg(0)->getType()->isArrayType()); - Value *Table = EmitArrayToPointerDecay(E->getArg(0)).getPointer(); + Value *Table = EmitArrayToPointerDecay(E->getArg(0)).emitRawPointer(*this); Value *Index = EmitScalarExpr(E->getArg(1)); Value *Val = EmitScalarExpr(E->getArg(2)); Function *Callee; @@ -21144,13 +21151,13 @@ Value *CodeGenFunction::EmitWebAssemblyBuiltinExpr(unsigned BuiltinID, } case WebAssembly::BI__builtin_wasm_table_size: { assert(E->getArg(0)->getType()->isArrayType()); - Value *Value = EmitArrayToPointerDecay(E->getArg(0)).getPointer(); + Value *Value = EmitArrayToPointerDecay(E->getArg(0)).emitRawPointer(*this); Function *Callee = CGM.getIntrinsic(Intrinsic::wasm_table_size); return Builder.CreateCall(Callee, Value); } case WebAssembly::BI__builtin_wasm_table_grow: { assert(E->getArg(0)->getType()->isArrayType()); - Value *Table = EmitArrayToPointerDecay(E->getArg(0)).getPointer(); + Value *Table = EmitArrayToPointerDecay(E->getArg(0)).emitRawPointer(*this); Value *Val = EmitScalarExpr(E->getArg(1)); Value *NElems = EmitScalarExpr(E->getArg(2)); @@ -21167,7 +21174,7 @@ Value *CodeGenFunction::EmitWebAssemblyBuiltinExpr(unsigned BuiltinID, } case WebAssembly::BI__builtin_wasm_table_fill: { assert(E->getArg(0)->getType()->isArrayType()); - Value *Table = EmitArrayToPointerDecay(E->getArg(0)).getPointer(); + Value *Table = EmitArrayToPointerDecay(E->getArg(0)).emitRawPointer(*this); Value *Index = EmitScalarExpr(E->getArg(1)); Value *Val = EmitScalarExpr(E->getArg(2)); Value *NElems = EmitScalarExpr(E->getArg(3)); @@ -21185,8 +21192,8 @@ Value *CodeGenFunction::EmitWebAssemblyBuiltinExpr(unsigned BuiltinID, } case WebAssembly::BI__builtin_wasm_table_copy: { assert(E->getArg(0)->getType()->isArrayType()); - Value *TableX = EmitArrayToPointerDecay(E->getArg(0)).getPointer(); - Value *TableY = EmitArrayToPointerDecay(E->getArg(1)).getPointer(); + Value *TableX = EmitArrayToPointerDecay(E->getArg(0)).emitRawPointer(*this); + Value *TableY = EmitArrayToPointerDecay(E->getArg(1)).emitRawPointer(*this); Value *DstIdx = EmitScalarExpr(E->getArg(2)); Value *SrcIdx = EmitScalarExpr(E->getArg(3)); Value *NElems = EmitScalarExpr(E->getArg(4)); @@ -21265,7 +21272,7 @@ Value *CodeGenFunction::EmitHexagonBuiltinExpr(unsigned BuiltinID, auto MakeCircOp = [this, E](unsigned IntID, bool IsLoad) { // The base pointer is passed by address, so it needs to be loaded. Address A = EmitPointerWithAlignment(E->getArg(0)); - Address BP = Address(A.getPointer(), Int8PtrTy, A.getAlignment()); + Address BP = Address(A.emitRawPointer(*this), Int8PtrTy, A.getAlignment()); llvm::Value *Base = Builder.CreateLoad(BP); // The treatment of both loads and stores is the same: the arguments for // the builtin are the same as the arguments for the intrinsic. @@ -21306,8 +21313,8 @@ Value *CodeGenFunction::EmitHexagonBuiltinExpr(unsigned BuiltinID, // EmitPointerWithAlignment and EmitScalarExpr evaluates the expression // per call. Address DestAddr = EmitPointerWithAlignment(E->getArg(1)); - DestAddr = Address(DestAddr.getPointer(), Int8Ty, DestAddr.getAlignment()); - llvm::Value *DestAddress = DestAddr.getPointer(); + DestAddr = DestAddr.withElementType(Int8Ty); + llvm::Value *DestAddress = DestAddr.emitRawPointer(*this); // Operands are Base, Dest, Modifier. // The intrinsic format in LLVM IR is defined as @@ -21358,8 +21365,8 @@ Value *CodeGenFunction::EmitHexagonBuiltinExpr(unsigned BuiltinID, {EmitScalarExpr(E->getArg(0)), EmitScalarExpr(E->getArg(1)), PredIn}); llvm::Value *PredOut = Builder.CreateExtractValue(Result, 1); - Builder.CreateAlignedStore(Q2V(PredOut), PredAddr.getPointer(), - PredAddr.getAlignment()); + Builder.CreateAlignedStore(Q2V(PredOut), PredAddr.emitRawPointer(*this), + PredAddr.getAlignment()); return Builder.CreateExtractValue(Result, 0); } // These are identical to the builtins above, except they don't consume @@ -21377,8 +21384,8 @@ Value *CodeGenFunction::EmitHexagonBuiltinExpr(unsigned BuiltinID, {EmitScalarExpr(E->getArg(0)), EmitScalarExpr(E->getArg(1))}); llvm::Value *PredOut = Builder.CreateExtractValue(Result, 1); - Builder.CreateAlignedStore(Q2V(PredOut), PredAddr.getPointer(), - PredAddr.getAlignment()); + Builder.CreateAlignedStore(Q2V(PredOut), PredAddr.emitRawPointer(*this), + PredAddr.getAlignment()); return Builder.CreateExtractValue(Result, 0); } diff --git a/clang/lib/CodeGen/CGCUDANV.cpp b/clang/lib/CodeGen/CGCUDANV.cpp index b756318c46a9..0cb5b06a519c 100644 --- a/clang/lib/CodeGen/CGCUDANV.cpp +++ b/clang/lib/CodeGen/CGCUDANV.cpp @@ -331,11 +331,11 @@ void CGNVCUDARuntime::emitDeviceStubBodyNew(CodeGenFunction &CGF, llvm::ConstantInt::get(SizeTy, std::max(1, Args.size()))); // Store pointers to the arguments in a locally allocated launch_args. for (unsigned i = 0; i < Args.size(); ++i) { - llvm::Value* VarPtr = CGF.GetAddrOfLocalVar(Args[i]).getPointer(); + llvm::Value *VarPtr = CGF.GetAddrOfLocalVar(Args[i]).emitRawPointer(CGF); llvm::Value *VoidVarPtr = CGF.Builder.CreatePointerCast(VarPtr, PtrTy); CGF.Builder.CreateDefaultAlignedStore( - VoidVarPtr, - CGF.Builder.CreateConstGEP1_32(PtrTy, KernelArgs.getPointer(), i)); + VoidVarPtr, CGF.Builder.CreateConstGEP1_32( + PtrTy, KernelArgs.emitRawPointer(CGF), i)); } llvm::BasicBlock *EndBlock = CGF.createBasicBlock("setup.end"); @@ -393,9 +393,10 @@ void CGNVCUDARuntime::emitDeviceStubBodyNew(CodeGenFunction &CGF, /*isVarArg=*/false), addUnderscoredPrefixToName("PopCallConfiguration")); - CGF.EmitRuntimeCallOrInvoke(cudaPopConfigFn, - {GridDim.getPointer(), BlockDim.getPointer(), - ShmemSize.getPointer(), Stream.getPointer()}); + CGF.EmitRuntimeCallOrInvoke(cudaPopConfigFn, {GridDim.emitRawPointer(CGF), + BlockDim.emitRawPointer(CGF), + ShmemSize.emitRawPointer(CGF), + Stream.emitRawPointer(CGF)}); // Emit the call to cudaLaunch llvm::Value *Kernel = @@ -405,7 +406,7 @@ void CGNVCUDARuntime::emitDeviceStubBodyNew(CodeGenFunction &CGF, cudaLaunchKernelFD->getParamDecl(0)->getType()); LaunchKernelArgs.add(RValue::getAggregate(GridDim), Dim3Ty); LaunchKernelArgs.add(RValue::getAggregate(BlockDim), Dim3Ty); - LaunchKernelArgs.add(RValue::get(KernelArgs.getPointer()), + LaunchKernelArgs.add(RValue::get(KernelArgs, CGF), cudaLaunchKernelFD->getParamDecl(3)->getType()); LaunchKernelArgs.add(RValue::get(CGF.Builder.CreateLoad(ShmemSize)), cudaLaunchKernelFD->getParamDecl(4)->getType()); @@ -438,8 +439,8 @@ void CGNVCUDARuntime::emitDeviceStubBodyLegacy(CodeGenFunction &CGF, auto TInfo = CGM.getContext().getTypeInfoInChars(A->getType()); Offset = Offset.alignTo(TInfo.Align); llvm::Value *Args[] = { - CGF.Builder.CreatePointerCast(CGF.GetAddrOfLocalVar(A).getPointer(), - PtrTy), + CGF.Builder.CreatePointerCast( + CGF.GetAddrOfLocalVar(A).emitRawPointer(CGF), PtrTy), llvm::ConstantInt::get(SizeTy, TInfo.Width.getQuantity()), llvm::ConstantInt::get(SizeTy, Offset.getQuantity()), }; diff --git a/clang/lib/CodeGen/CGCXXABI.cpp b/clang/lib/CodeGen/CGCXXABI.cpp index a8bf57a277e9..7c6dfc3e59d8 100644 --- a/clang/lib/CodeGen/CGCXXABI.cpp +++ b/clang/lib/CodeGen/CGCXXABI.cpp @@ -20,6 +20,12 @@ using namespace CodeGen; CGCXXABI::~CGCXXABI() { } +Address CGCXXABI::getThisAddress(CodeGenFunction &CGF) { + return CGF.makeNaturalAddressForPointer( + CGF.CXXABIThisValue, CGF.CXXABIThisDecl->getType()->getPointeeType(), + CGF.CXXABIThisAlignment); +} + void CGCXXABI::ErrorUnsupportedABI(CodeGenFunction &CGF, StringRef S) { DiagnosticsEngine &Diags = CGF.CGM.getDiags(); unsigned DiagID = Diags.getCustomDiagID(DiagnosticsEngine::Error, @@ -44,8 +50,12 @@ CGCallee CGCXXABI::EmitLoadOfMemberFunctionPointer( llvm::Value *MemPtr, const MemberPointerType *MPT) { ErrorUnsupportedABI(CGF, "calls through member pointers"); - ThisPtrForCall = This.getPointer(); - const auto *FPT = MPT->getPointeeType()->castAs(); + const auto *RD = + cast(MPT->getClass()->castAs()->getDecl()); + ThisPtrForCall = + CGF.getAsNaturalPointerTo(This, CGF.getContext().getRecordType(RD)); + const FunctionProtoType *FPT = + MPT->getPointeeType()->getAs(); llvm::Constant *FnPtr = llvm::Constant::getNullValue( llvm::PointerType::getUnqual(CGM.getLLVMContext())); return CGCallee::forDirect(FnPtr, FPT); @@ -251,16 +261,15 @@ void CGCXXABI::ReadArrayCookie(CodeGenFunction &CGF, Address ptr, // If we don't need an array cookie, bail out early. if (!requiresArrayCookie(expr, eltTy)) { - allocPtr = ptr.getPointer(); + allocPtr = ptr.emitRawPointer(CGF); numElements = nullptr; cookieSize = CharUnits::Zero(); return; } cookieSize = getArrayCookieSizeImpl(eltTy); - Address allocAddr = - CGF.Builder.CreateConstInBoundsByteGEP(ptr, -cookieSize); - allocPtr = allocAddr.getPointer(); + Address allocAddr = CGF.Builder.CreateConstInBoundsByteGEP(ptr, -cookieSize); + allocPtr = allocAddr.emitRawPointer(CGF); numElements = readArrayCookieImpl(CGF, allocAddr, cookieSize); } diff --git a/clang/lib/CodeGen/CGCXXABI.h b/clang/lib/CodeGen/CGCXXABI.h index ad1ad08d0856..c7eccbd0095a 100644 --- a/clang/lib/CodeGen/CGCXXABI.h +++ b/clang/lib/CodeGen/CGCXXABI.h @@ -57,12 +57,8 @@ protected: llvm::Value *getThisValue(CodeGenFunction &CGF) { return CGF.CXXABIThisValue; } - Address getThisAddress(CodeGenFunction &CGF) { - return Address( - CGF.CXXABIThisValue, - CGF.ConvertTypeForMem(CGF.CXXABIThisDecl->getType()->getPointeeType()), - CGF.CXXABIThisAlignment); - } + + Address getThisAddress(CodeGenFunction &CGF); /// Issue a diagnostic about unsupported features in the ABI. void ErrorUnsupportedABI(CodeGenFunction &CGF, StringRef S); @@ -475,12 +471,6 @@ public: BaseSubobject Base, const CXXRecordDecl *NearestVBase) = 0; - /// Get the address point of the vtable for the given base subobject while - /// building a constexpr. - virtual llvm::Constant * - getVTableAddressPointForConstExpr(BaseSubobject Base, - const CXXRecordDecl *VTableClass) = 0; - /// Get the address of the vtable for the given record decl which should be /// used for the vptr at the given offset in RD. virtual llvm::GlobalVariable *getAddrOfVTable(const CXXRecordDecl *RD, diff --git a/clang/lib/CodeGen/CGCall.cpp b/clang/lib/CodeGen/CGCall.cpp index b8adf5c26b3a..fb0078214b07 100644 --- a/clang/lib/CodeGen/CGCall.cpp +++ b/clang/lib/CodeGen/CGCall.cpp @@ -1037,15 +1037,9 @@ static void forConstantArrayExpansion(CodeGenFunction &CGF, ConstantArrayExpansion *CAE, Address BaseAddr, llvm::function_ref Fn) { - CharUnits EltSize = CGF.getContext().getTypeSizeInChars(CAE->EltTy); - CharUnits EltAlign = - BaseAddr.getAlignment().alignmentOfArrayElement(EltSize); - llvm::Type *EltTy = CGF.ConvertTypeForMem(CAE->EltTy); - for (int i = 0, n = CAE->NumElts; i < n; i++) { - llvm::Value *EltAddr = CGF.Builder.CreateConstGEP2_32( - BaseAddr.getElementType(), BaseAddr.getPointer(), 0, i); - Fn(Address(EltAddr, EltTy, EltAlign)); + Address EltAddr = CGF.Builder.CreateConstGEP2_32(BaseAddr, 0, i); + Fn(EltAddr); } } @@ -1160,9 +1154,10 @@ void CodeGenFunction::ExpandTypeToArgs( } /// Create a temporary allocation for the purposes of coercion. -static Address CreateTempAllocaForCoercion(CodeGenFunction &CGF, llvm::Type *Ty, - CharUnits MinAlign, - const Twine &Name = "tmp") { +static RawAddress CreateTempAllocaForCoercion(CodeGenFunction &CGF, + llvm::Type *Ty, + CharUnits MinAlign, + const Twine &Name = "tmp") { // Don't use an alignment that's worse than what LLVM would prefer. auto PrefAlign = CGF.CGM.getDataLayout().getPrefTypeAlign(Ty); CharUnits Align = std::max(MinAlign, CharUnits::fromQuantity(PrefAlign)); @@ -1332,11 +1327,11 @@ static llvm::Value *CreateCoercedLoad(Address Src, llvm::Type *Ty, } // Otherwise do coercion through memory. This is stupid, but simple. - Address Tmp = + RawAddress Tmp = CreateTempAllocaForCoercion(CGF, Ty, Src.getAlignment(), Src.getName()); CGF.Builder.CreateMemCpy( - Tmp.getPointer(), Tmp.getAlignment().getAsAlign(), Src.getPointer(), - Src.getAlignment().getAsAlign(), + Tmp.getPointer(), Tmp.getAlignment().getAsAlign(), + Src.emitRawPointer(CGF), Src.getAlignment().getAsAlign(), llvm::ConstantInt::get(CGF.IntPtrTy, SrcSize.getKnownMinValue())); return CGF.Builder.CreateLoad(Tmp); } @@ -1420,11 +1415,12 @@ static void CreateCoercedStore(llvm::Value *Src, // // FIXME: Assert that we aren't truncating non-padding bits when have access // to that information. - Address Tmp = CreateTempAllocaForCoercion(CGF, SrcTy, Dst.getAlignment()); + RawAddress Tmp = + CreateTempAllocaForCoercion(CGF, SrcTy, Dst.getAlignment()); CGF.Builder.CreateStore(Src, Tmp); CGF.Builder.CreateMemCpy( - Dst.getPointer(), Dst.getAlignment().getAsAlign(), Tmp.getPointer(), - Tmp.getAlignment().getAsAlign(), + Dst.emitRawPointer(CGF), Dst.getAlignment().getAsAlign(), + Tmp.getPointer(), Tmp.getAlignment().getAsAlign(), llvm::ConstantInt::get(CGF.IntPtrTy, DstSize.getFixedValue())); } } @@ -3024,17 +3020,17 @@ void CodeGenFunction::EmitFunctionProlog(const CGFunctionInfo &FI, case ABIArgInfo::Indirect: case ABIArgInfo::IndirectAliased: { assert(NumIRArgs == 1); - Address ParamAddr = Address(Fn->getArg(FirstIRArg), ConvertTypeForMem(Ty), - ArgI.getIndirectAlign(), KnownNonNull); + Address ParamAddr = makeNaturalAddressForPointer( + Fn->getArg(FirstIRArg), Ty, ArgI.getIndirectAlign(), false, nullptr, + nullptr, KnownNonNull); if (!hasScalarEvaluationKind(Ty)) { // Aggregates and complex variables are accessed by reference. All we // need to do is realign the value, if requested. Also, if the address // may be aliased, copy it to ensure that the parameter variable is // mutable and has a unique adress, as C requires. - Address V = ParamAddr; if (ArgI.getIndirectRealign() || ArgI.isIndirectAliased()) { - Address AlignedTemp = CreateMemTemp(Ty, "coerce"); + RawAddress AlignedTemp = CreateMemTemp(Ty, "coerce"); // Copy from the incoming argument pointer to the temporary with the // appropriate alignment. @@ -3044,11 +3040,12 @@ void CodeGenFunction::EmitFunctionProlog(const CGFunctionInfo &FI, CharUnits Size = getContext().getTypeSizeInChars(Ty); Builder.CreateMemCpy( AlignedTemp.getPointer(), AlignedTemp.getAlignment().getAsAlign(), - ParamAddr.getPointer(), ParamAddr.getAlignment().getAsAlign(), + ParamAddr.emitRawPointer(*this), + ParamAddr.getAlignment().getAsAlign(), llvm::ConstantInt::get(IntPtrTy, Size.getQuantity())); - V = AlignedTemp; + ParamAddr = AlignedTemp; } - ArgVals.push_back(ParamValue::forIndirect(V)); + ArgVals.push_back(ParamValue::forIndirect(ParamAddr)); } else { // Load scalar value from indirect argument. llvm::Value *V = @@ -3162,10 +3159,10 @@ void CodeGenFunction::EmitFunctionProlog(const CGFunctionInfo &FI, == ParameterABI::SwiftErrorResult) { QualType pointeeTy = Ty->getPointeeType(); assert(pointeeTy->isPointerType()); - Address temp = - CreateMemTemp(pointeeTy, getPointerAlign(), "swifterror.temp"); - Address arg(V, ConvertTypeForMem(pointeeTy), - getContext().getTypeAlignInChars(pointeeTy)); + RawAddress temp = + CreateMemTemp(pointeeTy, getPointerAlign(), "swifterror.temp"); + Address arg = makeNaturalAddressForPointer( + V, pointeeTy, getContext().getTypeAlignInChars(pointeeTy)); llvm::Value *incomingErrorValue = Builder.CreateLoad(arg); Builder.CreateStore(incomingErrorValue, temp); V = temp.getPointer(); @@ -3502,7 +3499,7 @@ static llvm::Value *tryRemoveRetainOfSelf(CodeGenFunction &CGF, llvm::LoadInst *load = dyn_cast(retainedValue->stripPointerCasts()); if (!load || load->isAtomic() || load->isVolatile() || - load->getPointerOperand() != CGF.GetAddrOfLocalVar(self).getPointer()) + load->getPointerOperand() != CGF.GetAddrOfLocalVar(self).getBasePointer()) return nullptr; // Okay! Burn it all down. This relies for correctness on the @@ -3539,12 +3536,15 @@ static llvm::Value *emitAutoreleaseOfResult(CodeGenFunction &CGF, /// Heuristically search for a dominating store to the return-value slot. static llvm::StoreInst *findDominatingStoreToReturnValue(CodeGenFunction &CGF) { + llvm::Value *ReturnValuePtr = CGF.ReturnValue.getBasePointer(); + // Check if a User is a store which pointerOperand is the ReturnValue. // We are looking for stores to the ReturnValue, not for stores of the // ReturnValue to some other location. - auto GetStoreIfValid = [&CGF](llvm::User *U) -> llvm::StoreInst * { + auto GetStoreIfValid = [&CGF, + ReturnValuePtr](llvm::User *U) -> llvm::StoreInst * { auto *SI = dyn_cast(U); - if (!SI || SI->getPointerOperand() != CGF.ReturnValue.getPointer() || + if (!SI || SI->getPointerOperand() != ReturnValuePtr || SI->getValueOperand()->getType() != CGF.ReturnValue.getElementType()) return nullptr; // These aren't actually possible for non-coerced returns, and we @@ -3558,7 +3558,7 @@ static llvm::StoreInst *findDominatingStoreToReturnValue(CodeGenFunction &CGF) { // for something immediately preceding the IP. Sometimes this can // happen with how we generate implicit-returns; it can also happen // with noreturn cleanups. - if (!CGF.ReturnValue.getPointer()->hasOneUse()) { + if (!ReturnValuePtr->hasOneUse()) { llvm::BasicBlock *IP = CGF.Builder.GetInsertBlock(); if (IP->empty()) return nullptr; @@ -3576,8 +3576,7 @@ static llvm::StoreInst *findDominatingStoreToReturnValue(CodeGenFunction &CGF) { return nullptr; } - llvm::StoreInst *store = - GetStoreIfValid(CGF.ReturnValue.getPointer()->user_back()); + llvm::StoreInst *store = GetStoreIfValid(ReturnValuePtr->user_back()); if (!store) return nullptr; // Now do a first-and-dirty dominance check: just walk up the @@ -4121,7 +4120,11 @@ void CodeGenFunction::EmitDelegateCallArg(CallArgList &args, } static bool isProvablyNull(llvm::Value *addr) { - return isa(addr); + return llvm::isa_and_nonnull(addr); +} + +static bool isProvablyNonNull(Address Addr, CodeGenFunction &CGF) { + return llvm::isKnownNonZero(Addr.getBasePointer(), CGF.CGM.getDataLayout()); } /// Emit the actual writing-back of a writeback. @@ -4129,21 +4132,20 @@ static void emitWriteback(CodeGenFunction &CGF, const CallArgList::Writeback &writeback) { const LValue &srcLV = writeback.Source; Address srcAddr = srcLV.getAddress(CGF); - assert(!isProvablyNull(srcAddr.getPointer()) && + assert(!isProvablyNull(srcAddr.getBasePointer()) && "shouldn't have writeback for provably null argument"); llvm::BasicBlock *contBB = nullptr; // If the argument wasn't provably non-null, we need to null check // before doing the store. - bool provablyNonNull = llvm::isKnownNonZero(srcAddr.getPointer(), - CGF.CGM.getDataLayout()); + bool provablyNonNull = isProvablyNonNull(srcAddr, CGF); + if (!provablyNonNull) { llvm::BasicBlock *writebackBB = CGF.createBasicBlock("icr.writeback"); contBB = CGF.createBasicBlock("icr.done"); - llvm::Value *isNull = - CGF.Builder.CreateIsNull(srcAddr.getPointer(), "icr.isnull"); + llvm::Value *isNull = CGF.Builder.CreateIsNull(srcAddr, "icr.isnull"); CGF.Builder.CreateCondBr(isNull, contBB, writebackBB); CGF.EmitBlock(writebackBB); } @@ -4247,7 +4249,7 @@ static void emitWritebackArg(CodeGenFunction &CGF, CallArgList &args, CGF.ConvertTypeForMem(CRE->getType()->getPointeeType()); // If the address is a constant null, just pass the appropriate null. - if (isProvablyNull(srcAddr.getPointer())) { + if (isProvablyNull(srcAddr.getBasePointer())) { args.add(RValue::get(llvm::ConstantPointerNull::get(destType)), CRE->getType()); return; @@ -4276,17 +4278,16 @@ static void emitWritebackArg(CodeGenFunction &CGF, CallArgList &args, // If the address is *not* known to be non-null, we need to switch. llvm::Value *finalArgument; - bool provablyNonNull = llvm::isKnownNonZero(srcAddr.getPointer(), - CGF.CGM.getDataLayout()); + bool provablyNonNull = isProvablyNonNull(srcAddr, CGF); + if (provablyNonNull) { - finalArgument = temp.getPointer(); + finalArgument = temp.emitRawPointer(CGF); } else { - llvm::Value *isNull = - CGF.Builder.CreateIsNull(srcAddr.getPointer(), "icr.isnull"); + llvm::Value *isNull = CGF.Builder.CreateIsNull(srcAddr, "icr.isnull"); - finalArgument = CGF.Builder.CreateSelect(isNull, - llvm::ConstantPointerNull::get(destType), - temp.getPointer(), "icr.argument"); + finalArgument = CGF.Builder.CreateSelect( + isNull, llvm::ConstantPointerNull::get(destType), + temp.emitRawPointer(CGF), "icr.argument"); // If we need to copy, then the load has to be conditional, which // means we need control flow. @@ -4410,6 +4411,16 @@ void CodeGenFunction::EmitNonNullArgCheck(RValue RV, QualType ArgType, EmitCheck(std::make_pair(Cond, CheckKind), Handler, StaticData, std::nullopt); } +void CodeGenFunction::EmitNonNullArgCheck(Address Addr, QualType ArgType, + SourceLocation ArgLoc, + AbstractCallee AC, unsigned ParmNum) { + if (!AC.getDecl() || !(SanOpts.has(SanitizerKind::NonnullAttribute) || + SanOpts.has(SanitizerKind::NullabilityArg))) + return; + + EmitNonNullArgCheck(RValue::get(Addr, *this), ArgType, ArgLoc, AC, ParmNum); +} + // Check if the call is going to use the inalloca convention. This needs to // agree with CGFunctionInfo::usesInAlloca. The CGFunctionInfo is arranged // later, so we can't check it directly. @@ -4750,10 +4761,20 @@ CodeGenFunction::AddObjCARCExceptionMetadata(llvm::Instruction *Inst) { llvm::CallInst * CodeGenFunction::EmitNounwindRuntimeCall(llvm::FunctionCallee callee, const llvm::Twine &name) { - return EmitNounwindRuntimeCall(callee, std::nullopt, name); + return EmitNounwindRuntimeCall(callee, ArrayRef(), name); } /// Emits a call to the given nounwind runtime function. +llvm::CallInst * +CodeGenFunction::EmitNounwindRuntimeCall(llvm::FunctionCallee callee, + ArrayRef
args, + const llvm::Twine &name) { + SmallVector values; + for (auto arg : args) + values.push_back(arg.emitRawPointer(*this)); + return EmitNounwindRuntimeCall(callee, values, name); +} + llvm::CallInst * CodeGenFunction::EmitNounwindRuntimeCall(llvm::FunctionCallee callee, ArrayRef args, @@ -5032,7 +5053,7 @@ RValue CodeGenFunction::EmitCall(const CGFunctionInfo &CallInfo, // If we're using inalloca, insert the allocation after the stack save. // FIXME: Do this earlier rather than hacking it in here! - Address ArgMemory = Address::invalid(); + RawAddress ArgMemory = RawAddress::invalid(); if (llvm::StructType *ArgStruct = CallInfo.getArgStruct()) { const llvm::DataLayout &DL = CGM.getDataLayout(); llvm::Instruction *IP = CallArgs.getStackBase(); @@ -5048,7 +5069,7 @@ RValue CodeGenFunction::EmitCall(const CGFunctionInfo &CallInfo, AI->setAlignment(Align.getAsAlign()); AI->setUsedWithInAlloca(true); assert(AI->isUsedWithInAlloca() && !AI->isStaticAlloca()); - ArgMemory = Address(AI, ArgStruct, Align); + ArgMemory = RawAddress(AI, ArgStruct, Align); } ClangToLLVMArgMapping IRFunctionArgs(CGM.getContext(), CallInfo); @@ -5057,11 +5078,11 @@ RValue CodeGenFunction::EmitCall(const CGFunctionInfo &CallInfo, // If the call returns a temporary with struct return, create a temporary // alloca to hold the result, unless one is given to us. Address SRetPtr = Address::invalid(); - Address SRetAlloca = Address::invalid(); + RawAddress SRetAlloca = RawAddress::invalid(); llvm::Value *UnusedReturnSizePtr = nullptr; if (RetAI.isIndirect() || RetAI.isInAlloca() || RetAI.isCoerceAndExpand()) { if (!ReturnValue.isNull()) { - SRetPtr = ReturnValue.getValue(); + SRetPtr = ReturnValue.getAddress(); } else { SRetPtr = CreateMemTemp(RetTy, "tmp", &SRetAlloca); if (HaveInsertPoint() && ReturnValue.isUnused()) { @@ -5071,15 +5092,16 @@ RValue CodeGenFunction::EmitCall(const CGFunctionInfo &CallInfo, } } if (IRFunctionArgs.hasSRetArg()) { - IRCallArgs[IRFunctionArgs.getSRetArgNo()] = SRetPtr.getPointer(); + IRCallArgs[IRFunctionArgs.getSRetArgNo()] = + getAsNaturalPointerTo(SRetPtr, RetTy); } else if (RetAI.isInAlloca()) { Address Addr = Builder.CreateStructGEP(ArgMemory, RetAI.getInAllocaFieldIndex()); - Builder.CreateStore(SRetPtr.getPointer(), Addr); + Builder.CreateStore(getAsNaturalPointerTo(SRetPtr, RetTy), Addr); } } - Address swiftErrorTemp = Address::invalid(); + RawAddress swiftErrorTemp = RawAddress::invalid(); Address swiftErrorArg = Address::invalid(); // When passing arguments using temporary allocas, we need to add the @@ -5112,9 +5134,9 @@ RValue CodeGenFunction::EmitCall(const CGFunctionInfo &CallInfo, assert(NumIRArgs == 0); assert(getTarget().getTriple().getArch() == llvm::Triple::x86); if (I->isAggregate()) { - Address Addr = I->hasLValue() - ? I->getKnownLValue().getAddress(*this) - : I->getKnownRValue().getAggregateAddress(); + RawAddress Addr = I->hasLValue() + ? I->getKnownLValue().getAddress(*this) + : I->getKnownRValue().getAggregateAddress(); llvm::Instruction *Placeholder = cast(Addr.getPointer()); @@ -5138,7 +5160,7 @@ RValue CodeGenFunction::EmitCall(const CGFunctionInfo &CallInfo, } else if (ArgInfo.getInAllocaIndirect()) { // Make a temporary alloca and store the address of it into the argument // struct. - Address Addr = CreateMemTempWithoutCast( + RawAddress Addr = CreateMemTempWithoutCast( I->Ty, getContext().getTypeAlignInChars(I->Ty), "indirect-arg-temp"); I->copyInto(*this, Addr); @@ -5160,12 +5182,12 @@ RValue CodeGenFunction::EmitCall(const CGFunctionInfo &CallInfo, assert(NumIRArgs == 1); if (!I->isAggregate()) { // Make a temporary alloca to pass the argument. - Address Addr = CreateMemTempWithoutCast( + RawAddress Addr = CreateMemTempWithoutCast( I->Ty, ArgInfo.getIndirectAlign(), "indirect-arg-temp"); - llvm::Value *Val = Addr.getPointer(); + llvm::Value *Val = getAsNaturalPointerTo(Addr, I->Ty); if (ArgHasMaybeUndefAttr) - Val = Builder.CreateFreeze(Addr.getPointer()); + Val = Builder.CreateFreeze(Val); IRCallArgs[FirstIRArg] = Val; I->copyInto(*this, Addr); @@ -5181,7 +5203,6 @@ RValue CodeGenFunction::EmitCall(const CGFunctionInfo &CallInfo, Address Addr = I->hasLValue() ? I->getKnownLValue().getAddress(*this) : I->getKnownRValue().getAggregateAddress(); - llvm::Value *V = Addr.getPointer(); CharUnits Align = ArgInfo.getIndirectAlign(); const llvm::DataLayout *TD = &CGM.getDataLayout(); @@ -5192,8 +5213,9 @@ RValue CodeGenFunction::EmitCall(const CGFunctionInfo &CallInfo, bool NeedCopy = false; if (Addr.getAlignment() < Align && - llvm::getOrEnforceKnownAlignment(V, Align.getAsAlign(), *TD) < - Align.getAsAlign()) { + llvm::getOrEnforceKnownAlignment(Addr.emitRawPointer(*this), + Align.getAsAlign(), + *TD) < Align.getAsAlign()) { NeedCopy = true; } else if (I->hasLValue()) { auto LV = I->getKnownLValue(); @@ -5224,11 +5246,11 @@ RValue CodeGenFunction::EmitCall(const CGFunctionInfo &CallInfo, if (NeedCopy) { // Create an aligned temporary, and copy to it. - Address AI = CreateMemTempWithoutCast( + RawAddress AI = CreateMemTempWithoutCast( I->Ty, ArgInfo.getIndirectAlign(), "byval-temp"); - llvm::Value *Val = AI.getPointer(); + llvm::Value *Val = getAsNaturalPointerTo(AI, I->Ty); if (ArgHasMaybeUndefAttr) - Val = Builder.CreateFreeze(AI.getPointer()); + Val = Builder.CreateFreeze(Val); IRCallArgs[FirstIRArg] = Val; // Emit lifetime markers for the temporary alloca. @@ -5245,6 +5267,7 @@ RValue CodeGenFunction::EmitCall(const CGFunctionInfo &CallInfo, I->copyInto(*this, AI); } else { // Skip the extra memcpy call. + llvm::Value *V = getAsNaturalPointerTo(Addr, I->Ty); auto *T = llvm::PointerType::get( CGM.getLLVMContext(), CGM.getDataLayout().getAllocaAddrSpace()); @@ -5284,8 +5307,8 @@ RValue CodeGenFunction::EmitCall(const CGFunctionInfo &CallInfo, assert(!swiftErrorTemp.isValid() && "multiple swifterror args"); QualType pointeeTy = I->Ty->getPointeeType(); - swiftErrorArg = Address(V, ConvertTypeForMem(pointeeTy), - getContext().getTypeAlignInChars(pointeeTy)); + swiftErrorArg = makeNaturalAddressForPointer( + V, pointeeTy, getContext().getTypeAlignInChars(pointeeTy)); swiftErrorTemp = CreateMemTemp(pointeeTy, getPointerAlign(), "swifterror.temp"); @@ -5422,7 +5445,7 @@ RValue CodeGenFunction::EmitCall(const CGFunctionInfo &CallInfo, llvm::Value *tempSize = nullptr; Address addr = Address::invalid(); - Address AllocaAddr = Address::invalid(); + RawAddress AllocaAddr = RawAddress::invalid(); if (I->isAggregate()) { addr = I->hasLValue() ? I->getKnownLValue().getAddress(*this) : I->getKnownRValue().getAggregateAddress(); @@ -5856,7 +5879,7 @@ RValue CodeGenFunction::EmitCall(const CGFunctionInfo &CallInfo, return RValue::getComplex(std::make_pair(Real, Imag)); } case TEK_Aggregate: { - Address DestPtr = ReturnValue.getValue(); + Address DestPtr = ReturnValue.getAddress(); bool DestIsVolatile = ReturnValue.isVolatile(); if (!DestPtr.isValid()) { diff --git a/clang/lib/CodeGen/CGCall.h b/clang/lib/CodeGen/CGCall.h index 1bd48a072593..6b676ac196db 100644 --- a/clang/lib/CodeGen/CGCall.h +++ b/clang/lib/CodeGen/CGCall.h @@ -377,6 +377,7 @@ public: Address getValue() const { return Addr; } bool isUnused() const { return IsUnused; } bool isExternallyDestructed() const { return IsExternallyDestructed; } + Address getAddress() const { return Addr; } }; /// Adds attributes to \p F according to our \p CodeGenOpts and \p LangOpts, as diff --git a/clang/lib/CodeGen/CGClass.cpp b/clang/lib/CodeGen/CGClass.cpp index 34319381901a..8c1c8ee455d2 100644 --- a/clang/lib/CodeGen/CGClass.cpp +++ b/clang/lib/CodeGen/CGClass.cpp @@ -139,8 +139,9 @@ Address CodeGenFunction::LoadCXXThisAddress() { CXXThisAlignment = CGM.getClassPointerAlignment(MD->getParent()); } - llvm::Type *Ty = ConvertType(MD->getFunctionObjectParameterType()); - return Address(LoadCXXThis(), Ty, CXXThisAlignment, KnownNonNull); + return makeNaturalAddressForPointer( + LoadCXXThis(), MD->getFunctionObjectParameterType(), CXXThisAlignment, + false, nullptr, nullptr, KnownNonNull); } /// Emit the address of a field using a member data pointer. @@ -270,7 +271,7 @@ ApplyNonVirtualAndVirtualOffset(CodeGenFunction &CGF, Address addr, } // Apply the base offset. - llvm::Value *ptr = addr.getPointer(); + llvm::Value *ptr = addr.emitRawPointer(CGF); ptr = CGF.Builder.CreateInBoundsGEP(CGF.Int8Ty, ptr, baseOffset, "add.ptr"); // If we have a virtual component, the alignment of the result will @@ -338,8 +339,8 @@ Address CodeGenFunction::GetAddressOfBaseClass( if (sanitizePerformTypeCheck()) { SanitizerSet SkippedChecks; SkippedChecks.set(SanitizerKind::Null, !NullCheckValue); - EmitTypeCheck(TCK_Upcast, Loc, Value.getPointer(), - DerivedTy, DerivedAlign, SkippedChecks); + EmitTypeCheck(TCK_Upcast, Loc, Value.emitRawPointer(*this), DerivedTy, + DerivedAlign, SkippedChecks); } return Value.withElementType(BaseValueTy); } @@ -354,7 +355,7 @@ Address CodeGenFunction::GetAddressOfBaseClass( llvm::BasicBlock *notNullBB = createBasicBlock("cast.notnull"); endBB = createBasicBlock("cast.end"); - llvm::Value *isNull = Builder.CreateIsNull(Value.getPointer()); + llvm::Value *isNull = Builder.CreateIsNull(Value); Builder.CreateCondBr(isNull, endBB, notNullBB); EmitBlock(notNullBB); } @@ -363,14 +364,15 @@ Address CodeGenFunction::GetAddressOfBaseClass( SanitizerSet SkippedChecks; SkippedChecks.set(SanitizerKind::Null, true); EmitTypeCheck(VBase ? TCK_UpcastToVirtualBase : TCK_Upcast, Loc, - Value.getPointer(), DerivedTy, DerivedAlign, SkippedChecks); + Value.emitRawPointer(*this), DerivedTy, DerivedAlign, + SkippedChecks); } // Compute the virtual offset. llvm::Value *VirtualOffset = nullptr; if (VBase) { VirtualOffset = - CGM.getCXXABI().GetVirtualBaseClassOffset(*this, Value, Derived, VBase); + CGM.getCXXABI().GetVirtualBaseClassOffset(*this, Value, Derived, VBase); } // Apply both offsets. @@ -387,7 +389,7 @@ Address CodeGenFunction::GetAddressOfBaseClass( EmitBlock(endBB); llvm::PHINode *PHI = Builder.CreatePHI(PtrTy, 2, "cast.result"); - PHI->addIncoming(Value.getPointer(), notNullBB); + PHI->addIncoming(Value.emitRawPointer(*this), notNullBB); PHI->addIncoming(llvm::Constant::getNullValue(PtrTy), origBB); Value = Value.withPointer(PHI, NotKnownNonNull); } @@ -424,15 +426,19 @@ CodeGenFunction::GetAddressOfDerivedClass(Address BaseAddr, CastNotNull = createBasicBlock("cast.notnull"); CastEnd = createBasicBlock("cast.end"); - llvm::Value *IsNull = Builder.CreateIsNull(BaseAddr.getPointer()); + llvm::Value *IsNull = Builder.CreateIsNull(BaseAddr); Builder.CreateCondBr(IsNull, CastNull, CastNotNull); EmitBlock(CastNotNull); } // Apply the offset. - llvm::Value *Value = BaseAddr.getPointer(); - Value = Builder.CreateInBoundsGEP( - Int8Ty, Value, Builder.CreateNeg(NonVirtualOffset), "sub.ptr"); + Address Addr = BaseAddr.withElementType(Int8Ty); + Addr = Builder.CreateInBoundsGEP( + Addr, Builder.CreateNeg(NonVirtualOffset), Int8Ty, + CGM.getClassPointerAlignment(Derived), "sub.ptr"); + + // Just cast. + Addr = Addr.withElementType(DerivedValueTy); // Produce a PHI if we had a null-check. if (NullCheckValue) { @@ -441,13 +447,15 @@ CodeGenFunction::GetAddressOfDerivedClass(Address BaseAddr, Builder.CreateBr(CastEnd); EmitBlock(CastEnd); + llvm::Value *Value = Addr.emitRawPointer(*this); llvm::PHINode *PHI = Builder.CreatePHI(Value->getType(), 2); PHI->addIncoming(Value, CastNotNull); PHI->addIncoming(llvm::Constant::getNullValue(Value->getType()), CastNull); - Value = PHI; + return Address(PHI, Addr.getElementType(), + CGM.getClassPointerAlignment(Derived)); } - return Address(Value, DerivedValueTy, CGM.getClassPointerAlignment(Derived)); + return Addr; } llvm::Value *CodeGenFunction::GetVTTParameter(GlobalDecl GD, @@ -1719,7 +1727,7 @@ namespace { // Use the base class declaration location as inline DebugLocation. All // fields of the class are destroyed. DeclAsInlineDebugLocation InlineHere(CGF, *BaseClass); - EmitSanitizerDtorFieldsCallback(CGF, Addr.getPointer(), + EmitSanitizerDtorFieldsCallback(CGF, Addr.emitRawPointer(CGF), BaseSize.getQuantity()); // Prevent the current stack frame from disappearing from the stack trace. @@ -2022,7 +2030,7 @@ void CodeGenFunction::EmitCXXAggrConstructorCall(const CXXConstructorDecl *ctor, // Find the end of the array. llvm::Type *elementType = arrayBase.getElementType(); - llvm::Value *arrayBegin = arrayBase.getPointer(); + llvm::Value *arrayBegin = arrayBase.emitRawPointer(*this); llvm::Value *arrayEnd = Builder.CreateInBoundsGEP( elementType, arrayBegin, numElements, "arrayctor.end"); @@ -2118,14 +2126,15 @@ void CodeGenFunction::EmitCXXConstructorCall(const CXXConstructorDecl *D, Address This = ThisAVS.getAddress(); LangAS SlotAS = ThisAVS.getQualifiers().getAddressSpace(); LangAS ThisAS = D->getFunctionObjectParameterType().getAddressSpace(); - llvm::Value *ThisPtr = This.getPointer(); + llvm::Value *ThisPtr = + getAsNaturalPointerTo(This, D->getThisType()->getPointeeType()); if (SlotAS != ThisAS) { unsigned TargetThisAS = getContext().getTargetAddressSpace(ThisAS); llvm::Type *NewType = llvm::PointerType::get(getLLVMContext(), TargetThisAS); - ThisPtr = getTargetHooks().performAddrSpaceCast(*this, This.getPointer(), - ThisAS, SlotAS, NewType); + ThisPtr = getTargetHooks().performAddrSpaceCast(*this, ThisPtr, ThisAS, + SlotAS, NewType); } // Push the this ptr. @@ -2194,7 +2203,7 @@ void CodeGenFunction::EmitCXXConstructorCall(const CXXConstructorDecl *D, const CXXRecordDecl *ClassDecl = D->getParent(); if (!NewPointerIsChecked) - EmitTypeCheck(CodeGenFunction::TCK_ConstructorCall, Loc, This.getPointer(), + EmitTypeCheck(CodeGenFunction::TCK_ConstructorCall, Loc, This, getContext().getRecordType(ClassDecl), CharUnits::Zero()); if (D->isTrivial() && D->isDefaultConstructor()) { @@ -2207,10 +2216,9 @@ void CodeGenFunction::EmitCXXConstructorCall(const CXXConstructorDecl *D, // model that copy. if (isMemcpyEquivalentSpecialMember(D)) { assert(Args.size() == 2 && "unexpected argcount for trivial ctor"); - QualType SrcTy = D->getParamDecl(0)->getType().getNonReferenceType(); - Address Src = Address(Args[1].getRValue(*this).getScalarVal(), ConvertTypeForMem(SrcTy), - CGM.getNaturalTypeAlignment(SrcTy)); + Address Src = makeNaturalAddressForPointer( + Args[1].getRValue(*this).getScalarVal(), SrcTy); LValue SrcLVal = MakeAddrLValue(Src, SrcTy); QualType DestTy = getContext().getTypeDeclType(ClassDecl); LValue DestLVal = MakeAddrLValue(This, DestTy); @@ -2263,7 +2271,9 @@ void CodeGenFunction::EmitInheritedCXXConstructorCall( const CXXConstructorDecl *D, bool ForVirtualBase, Address This, bool InheritedFromVBase, const CXXInheritedCtorInitExpr *E) { CallArgList Args; - CallArg ThisArg(RValue::get(This.getPointer()), D->getThisType()); + CallArg ThisArg(RValue::get(getAsNaturalPointerTo( + This, D->getThisType()->getPointeeType())), + D->getThisType()); // Forward the parameters. if (InheritedFromVBase && @@ -2388,12 +2398,14 @@ CodeGenFunction::EmitSynthesizedCXXCopyCtorCall(const CXXConstructorDecl *D, CallArgList Args; // Push the this ptr. - Args.add(RValue::get(This.getPointer()), D->getThisType()); + Args.add(RValue::get(getAsNaturalPointerTo(This, D->getThisType())), + D->getThisType()); // Push the src ptr. QualType QT = *(FPT->param_type_begin()); llvm::Type *t = CGM.getTypes().ConvertType(QT); - llvm::Value *SrcVal = Builder.CreateBitCast(Src.getPointer(), t); + llvm::Value *Val = getAsNaturalPointerTo(Src, D->getThisType()); + llvm::Value *SrcVal = Builder.CreateBitCast(Val, t); Args.add(RValue::get(SrcVal), QT); // Skip over first argument (Src). @@ -2418,7 +2430,9 @@ CodeGenFunction::EmitDelegateCXXConstructorCall(const CXXConstructorDecl *Ctor, // this Address This = LoadCXXThisAddress(); - DelegateArgs.add(RValue::get(This.getPointer()), (*I)->getType()); + DelegateArgs.add(RValue::get(getAsNaturalPointerTo( + This, (*I)->getType()->getPointeeType())), + (*I)->getType()); ++I; // FIXME: The location of the VTT parameter in the parameter list is @@ -2775,7 +2789,7 @@ void CodeGenFunction::EmitVTablePtrCheckForCast(QualType T, Address Derived, if (MayBeNull) { llvm::Value *DerivedNotNull = - Builder.CreateIsNotNull(Derived.getPointer(), "cast.nonnull"); + Builder.CreateIsNotNull(Derived.emitRawPointer(*this), "cast.nonnull"); llvm::BasicBlock *CheckBlock = createBasicBlock("cast.check"); ContBlock = createBasicBlock("cast.cont"); @@ -2976,7 +2990,7 @@ void CodeGenFunction::EmitLambdaBlockInvokeBody() { QualType ThisType = getContext().getPointerType(getContext().getRecordType(Lambda)); Address ThisPtr = GetAddrOfBlockDecl(variable); - CallArgs.add(RValue::get(ThisPtr.getPointer()), ThisType); + CallArgs.add(RValue::get(getAsNaturalPointerTo(ThisPtr, ThisType)), ThisType); // Add the rest of the parameters. for (auto *param : BD->parameters()) @@ -3004,7 +3018,7 @@ void CodeGenFunction::EmitLambdaStaticInvokeBody(const CXXMethodDecl *MD) { QualType LambdaType = getContext().getRecordType(Lambda); QualType ThisType = getContext().getPointerType(LambdaType); Address ThisPtr = CreateMemTemp(LambdaType, "unused.capture"); - CallArgs.add(RValue::get(ThisPtr.getPointer()), ThisType); + CallArgs.add(RValue::get(ThisPtr.emitRawPointer(*this)), ThisType); EmitLambdaDelegatingInvokeBody(MD, CallArgs); } diff --git a/clang/lib/CodeGen/CGCleanup.cpp b/clang/lib/CodeGen/CGCleanup.cpp index f87caf050eea..e6f8e6873004 100644 --- a/clang/lib/CodeGen/CGCleanup.cpp +++ b/clang/lib/CodeGen/CGCleanup.cpp @@ -27,7 +27,7 @@ bool DominatingValue::saved_type::needsSaving(RValue rv) { if (rv.isScalar()) return DominatingLLVMValue::needsSaving(rv.getScalarVal()); if (rv.isAggregate()) - return DominatingLLVMValue::needsSaving(rv.getAggregatePointer()); + return DominatingValue
::needsSaving(rv.getAggregateAddress()); return true; } @@ -35,69 +35,40 @@ DominatingValue::saved_type DominatingValue::saved_type::save(CodeGenFunction &CGF, RValue rv) { if (rv.isScalar()) { llvm::Value *V = rv.getScalarVal(); - - // These automatically dominate and don't need to be saved. - if (!DominatingLLVMValue::needsSaving(V)) - return saved_type(V, nullptr, ScalarLiteral); - - // Everything else needs an alloca. - Address addr = - CGF.CreateDefaultAlignTempAlloca(V->getType(), "saved-rvalue"); - CGF.Builder.CreateStore(V, addr); - return saved_type(addr.getPointer(), nullptr, ScalarAddress); + return saved_type(DominatingLLVMValue::save(CGF, V), + DominatingLLVMValue::needsSaving(V) ? ScalarAddress + : ScalarLiteral); } if (rv.isComplex()) { CodeGenFunction::ComplexPairTy V = rv.getComplexVal(); - llvm::Type *ComplexTy = - llvm::StructType::get(V.first->getType(), V.second->getType()); - Address addr = CGF.CreateDefaultAlignTempAlloca(ComplexTy, "saved-complex"); - CGF.Builder.CreateStore(V.first, CGF.Builder.CreateStructGEP(addr, 0)); - CGF.Builder.CreateStore(V.second, CGF.Builder.CreateStructGEP(addr, 1)); - return saved_type(addr.getPointer(), nullptr, ComplexAddress); + return saved_type(DominatingLLVMValue::save(CGF, V.first), + DominatingLLVMValue::save(CGF, V.second)); } assert(rv.isAggregate()); - Address V = rv.getAggregateAddress(); // TODO: volatile? - if (!DominatingLLVMValue::needsSaving(V.getPointer())) - return saved_type(V.getPointer(), V.getElementType(), AggregateLiteral, - V.getAlignment().getQuantity()); - - Address addr = - CGF.CreateTempAlloca(V.getType(), CGF.getPointerAlign(), "saved-rvalue"); - CGF.Builder.CreateStore(V.getPointer(), addr); - return saved_type(addr.getPointer(), V.getElementType(), AggregateAddress, - V.getAlignment().getQuantity()); + Address V = rv.getAggregateAddress(); + return saved_type( + DominatingValue
::save(CGF, V), rv.isVolatileQualified(), + DominatingValue
::needsSaving(V) ? AggregateAddress + : AggregateLiteral); } /// Given a saved r-value produced by SaveRValue, perform the code /// necessary to restore it to usability at the current insertion /// point. RValue DominatingValue::saved_type::restore(CodeGenFunction &CGF) { - auto getSavingAddress = [&](llvm::Value *value) { - auto *AI = cast(value); - return Address(value, AI->getAllocatedType(), - CharUnits::fromQuantity(AI->getAlign().value())); - }; switch (K) { case ScalarLiteral: - return RValue::get(Value); case ScalarAddress: - return RValue::get(CGF.Builder.CreateLoad(getSavingAddress(Value))); + return RValue::get(DominatingLLVMValue::restore(CGF, Vals.first)); case AggregateLiteral: + case AggregateAddress: return RValue::getAggregate( - Address(Value, ElementType, CharUnits::fromQuantity(Align))); - case AggregateAddress: { - auto addr = CGF.Builder.CreateLoad(getSavingAddress(Value)); - return RValue::getAggregate( - Address(addr, ElementType, CharUnits::fromQuantity(Align))); - } + DominatingValue
::restore(CGF, AggregateAddr), IsVolatile); case ComplexAddress: { - Address address = getSavingAddress(Value); - llvm::Value *real = - CGF.Builder.CreateLoad(CGF.Builder.CreateStructGEP(address, 0)); - llvm::Value *imag = - CGF.Builder.CreateLoad(CGF.Builder.CreateStructGEP(address, 1)); + llvm::Value *real = DominatingLLVMValue::restore(CGF, Vals.first); + llvm::Value *imag = DominatingLLVMValue::restore(CGF, Vals.second); return RValue::getComplex(real, imag); } } @@ -294,14 +265,14 @@ void EHScopeStack::popNullFixups() { BranchFixups.pop_back(); } -Address CodeGenFunction::createCleanupActiveFlag() { +RawAddress CodeGenFunction::createCleanupActiveFlag() { // Create a variable to decide whether the cleanup needs to be run. - Address active = CreateTempAllocaWithoutCast( + RawAddress active = CreateTempAllocaWithoutCast( Builder.getInt1Ty(), CharUnits::One(), "cleanup.cond"); // Initialize it to false at a site that's guaranteed to be run // before each evaluation. - setBeforeOutermostConditional(Builder.getFalse(), active); + setBeforeOutermostConditional(Builder.getFalse(), active, *this); // Initialize it to true at the current location. Builder.CreateStore(Builder.getTrue(), active); @@ -309,7 +280,7 @@ Address CodeGenFunction::createCleanupActiveFlag() { return active; } -void CodeGenFunction::initFullExprCleanupWithFlag(Address ActiveFlag) { +void CodeGenFunction::initFullExprCleanupWithFlag(RawAddress ActiveFlag) { // Set that as the active flag in the cleanup. EHCleanupScope &cleanup = cast(*EHStack.begin()); assert(!cleanup.hasActiveFlag() && "cleanup already has active flag?"); @@ -322,15 +293,17 @@ void CodeGenFunction::initFullExprCleanupWithFlag(Address ActiveFlag) { void EHScopeStack::Cleanup::anchor() {} static void createStoreInstBefore(llvm::Value *value, Address addr, - llvm::Instruction *beforeInst) { - auto store = new llvm::StoreInst(value, addr.getPointer(), beforeInst); + llvm::Instruction *beforeInst, + CodeGenFunction &CGF) { + auto store = new llvm::StoreInst(value, addr.emitRawPointer(CGF), beforeInst); store->setAlignment(addr.getAlignment().getAsAlign()); } static llvm::LoadInst *createLoadInstBefore(Address addr, const Twine &name, - llvm::Instruction *beforeInst) { - return new llvm::LoadInst(addr.getElementType(), addr.getPointer(), name, - false, addr.getAlignment().getAsAlign(), + llvm::Instruction *beforeInst, + CodeGenFunction &CGF) { + return new llvm::LoadInst(addr.getElementType(), addr.emitRawPointer(CGF), + name, false, addr.getAlignment().getAsAlign(), beforeInst); } @@ -357,8 +330,8 @@ static void ResolveAllBranchFixups(CodeGenFunction &CGF, // entry which we're currently popping. if (Fixup.OptimisticBranchBlock == nullptr) { createStoreInstBefore(CGF.Builder.getInt32(Fixup.DestinationIndex), - CGF.getNormalCleanupDestSlot(), - Fixup.InitialBranch); + CGF.getNormalCleanupDestSlot(), Fixup.InitialBranch, + CGF); Fixup.InitialBranch->setSuccessor(0, CleanupEntry); } @@ -385,7 +358,7 @@ static llvm::SwitchInst *TransitionToCleanupSwitch(CodeGenFunction &CGF, if (llvm::BranchInst *Br = dyn_cast(Term)) { assert(Br->isUnconditional()); auto Load = createLoadInstBefore(CGF.getNormalCleanupDestSlot(), - "cleanup.dest", Term); + "cleanup.dest", Term, CGF); llvm::SwitchInst *Switch = llvm::SwitchInst::Create(Load, Br->getSuccessor(0), 4, Block); Br->eraseFromParent(); @@ -513,8 +486,8 @@ void CodeGenFunction::PopCleanupBlocks( I += Header.getSize(); if (Header.isConditional()) { - Address ActiveFlag = - reinterpret_cast
(LifetimeExtendedCleanupStack[I]); + RawAddress ActiveFlag = + reinterpret_cast(LifetimeExtendedCleanupStack[I]); initFullExprCleanupWithFlag(ActiveFlag); I += sizeof(ActiveFlag); } @@ -888,7 +861,7 @@ void CodeGenFunction::PopCleanupBlock(bool FallthroughIsBranchThrough) { if (NormalCleanupDestSlot->hasOneUse()) { NormalCleanupDestSlot->user_back()->eraseFromParent(); NormalCleanupDestSlot->eraseFromParent(); - NormalCleanupDest = Address::invalid(); + NormalCleanupDest = RawAddress::invalid(); } llvm::BasicBlock *BranchAfter = Scope.getBranchAfterBlock(0); @@ -912,9 +885,8 @@ void CodeGenFunction::PopCleanupBlock(bool FallthroughIsBranchThrough) { // pass the abnormal exit flag to Fn (SEH cleanup) cleanupFlags.setHasExitSwitch(); - llvm::LoadInst *Load = - createLoadInstBefore(getNormalCleanupDestSlot(), "cleanup.dest", - nullptr); + llvm::LoadInst *Load = createLoadInstBefore( + getNormalCleanupDestSlot(), "cleanup.dest", nullptr, *this); llvm::SwitchInst *Switch = llvm::SwitchInst::Create(Load, Default, SwitchCapacity); @@ -961,8 +933,8 @@ void CodeGenFunction::PopCleanupBlock(bool FallthroughIsBranchThrough) { if (!Fixup.Destination) continue; if (!Fixup.OptimisticBranchBlock) { createStoreInstBefore(Builder.getInt32(Fixup.DestinationIndex), - getNormalCleanupDestSlot(), - Fixup.InitialBranch); + getNormalCleanupDestSlot(), Fixup.InitialBranch, + *this); Fixup.InitialBranch->setSuccessor(0, NormalEntry); } Fixup.OptimisticBranchBlock = NormalExit; @@ -1135,7 +1107,7 @@ void CodeGenFunction::EmitBranchThroughCleanup(JumpDest Dest) { // Store the index at the start. llvm::ConstantInt *Index = Builder.getInt32(Dest.getDestIndex()); - createStoreInstBefore(Index, getNormalCleanupDestSlot(), BI); + createStoreInstBefore(Index, getNormalCleanupDestSlot(), BI, *this); // Adjust BI to point to the first cleanup block. { @@ -1269,9 +1241,9 @@ static void SetupCleanupBlockActivation(CodeGenFunction &CGF, // If we're in a conditional block, ignore the dominating IP and // use the outermost conditional branch. if (CGF.isInConditionalBranch()) { - CGF.setBeforeOutermostConditional(value, var); + CGF.setBeforeOutermostConditional(value, var, CGF); } else { - createStoreInstBefore(value, var, dominatingIP); + createStoreInstBefore(value, var, dominatingIP, CGF); } } @@ -1321,7 +1293,7 @@ void CodeGenFunction::DeactivateCleanupBlock(EHScopeStack::stable_iterator C, Scope.setActive(false); } -Address CodeGenFunction::getNormalCleanupDestSlot() { +RawAddress CodeGenFunction::getNormalCleanupDestSlot() { if (!NormalCleanupDest.isValid()) NormalCleanupDest = CreateDefaultAlignTempAlloca(Builder.getInt32Ty(), "cleanup.dest.slot"); diff --git a/clang/lib/CodeGen/CGCleanup.h b/clang/lib/CodeGen/CGCleanup.h index 7a7344c07160..03e4a29d7b3d 100644 --- a/clang/lib/CodeGen/CGCleanup.h +++ b/clang/lib/CodeGen/CGCleanup.h @@ -333,7 +333,7 @@ public: Address getActiveFlag() const { return ActiveFlag; } - void setActiveFlag(Address Var) { + void setActiveFlag(RawAddress Var) { assert(Var.getAlignment().isOne()); ActiveFlag = Var; } diff --git a/clang/lib/CodeGen/CGCoroutine.cpp b/clang/lib/CodeGen/CGCoroutine.cpp index b7142ec08af9..93ca711f716f 100644 --- a/clang/lib/CodeGen/CGCoroutine.cpp +++ b/clang/lib/CodeGen/CGCoroutine.cpp @@ -867,8 +867,8 @@ void CodeGenFunction::EmitCoroutineBody(const CoroutineBodyStmt &S) { EmitStmt(S.getPromiseDeclStmt()); Address PromiseAddr = GetAddrOfLocalVar(S.getPromiseDecl()); - auto *PromiseAddrVoidPtr = - new llvm::BitCastInst(PromiseAddr.getPointer(), VoidPtrTy, "", CoroId); + auto *PromiseAddrVoidPtr = new llvm::BitCastInst( + PromiseAddr.emitRawPointer(*this), VoidPtrTy, "", CoroId); // Update CoroId to refer to the promise. We could not do it earlier because // promise local variable was not emitted yet. CoroId->setArgOperand(1, PromiseAddrVoidPtr); diff --git a/clang/lib/CodeGen/CGDecl.cpp b/clang/lib/CodeGen/CGDecl.cpp index 2ef5ed04af30..267f2e40a7bb 100644 --- a/clang/lib/CodeGen/CGDecl.cpp +++ b/clang/lib/CodeGen/CGDecl.cpp @@ -1461,7 +1461,7 @@ CodeGenFunction::EmitAutoVarAlloca(const VarDecl &D) { bool EmitDebugInfo = DI && CGM.getCodeGenOpts().hasReducedDebugInfo(); Address address = Address::invalid(); - Address AllocaAddr = Address::invalid(); + RawAddress AllocaAddr = RawAddress::invalid(); Address OpenMPLocalAddr = Address::invalid(); if (CGM.getLangOpts().OpenMPIRBuilder) OpenMPLocalAddr = OMPBuilderCBHelpers::getAddressOfLocalVariable(*this, &D); @@ -1524,7 +1524,10 @@ CodeGenFunction::EmitAutoVarAlloca(const VarDecl &D) { // return slot, so that we can elide the copy when returning this // variable (C++0x [class.copy]p34). address = ReturnValue; - AllocaAddr = ReturnValue; + AllocaAddr = + RawAddress(ReturnValue.emitRawPointer(*this), + ReturnValue.getElementType(), ReturnValue.getAlignment()); + ; if (const RecordType *RecordTy = Ty->getAs()) { const auto *RD = RecordTy->getDecl(); @@ -1535,7 +1538,7 @@ CodeGenFunction::EmitAutoVarAlloca(const VarDecl &D) { // to this variable. Set it to zero to indicate that NRVO was not // applied. llvm::Value *Zero = Builder.getFalse(); - Address NRVOFlag = + RawAddress NRVOFlag = CreateTempAlloca(Zero->getType(), CharUnits::One(), "nrvo"); EnsureInsertPoint(); Builder.CreateStore(Zero, NRVOFlag); @@ -1678,7 +1681,7 @@ CodeGenFunction::EmitAutoVarAlloca(const VarDecl &D) { } if (D.hasAttr() && HaveInsertPoint()) - EmitVarAnnotations(&D, address.getPointer()); + EmitVarAnnotations(&D, address.emitRawPointer(*this)); // Make sure we call @llvm.lifetime.end. if (emission.useLifetimeMarkers()) @@ -1851,12 +1854,13 @@ void CodeGenFunction::emitZeroOrPatternForAutoVarInit(QualType type, llvm::Value *BaseSizeInChars = llvm::ConstantInt::get(IntPtrTy, EltSize.getQuantity()); Address Begin = Loc.withElementType(Int8Ty); - llvm::Value *End = Builder.CreateInBoundsGEP( - Begin.getElementType(), Begin.getPointer(), SizeVal, "vla.end"); + llvm::Value *End = Builder.CreateInBoundsGEP(Begin.getElementType(), + Begin.emitRawPointer(*this), + SizeVal, "vla.end"); llvm::BasicBlock *OriginBB = Builder.GetInsertBlock(); EmitBlock(LoopBB); llvm::PHINode *Cur = Builder.CreatePHI(Begin.getType(), 2, "vla.cur"); - Cur->addIncoming(Begin.getPointer(), OriginBB); + Cur->addIncoming(Begin.emitRawPointer(*this), OriginBB); CharUnits CurAlign = Loc.getAlignment().alignmentOfArrayElement(EltSize); auto *I = Builder.CreateMemCpy(Address(Cur, Int8Ty, CurAlign), @@ -2283,7 +2287,7 @@ void CodeGenFunction::emitDestroy(Address addr, QualType type, checkZeroLength = false; } - llvm::Value *begin = addr.getPointer(); + llvm::Value *begin = addr.emitRawPointer(*this); llvm::Value *end = Builder.CreateInBoundsGEP(addr.getElementType(), begin, length); emitArrayDestroy(begin, end, type, elementAlign, destroyer, @@ -2543,7 +2547,7 @@ void CodeGenFunction::EmitParmDecl(const VarDecl &D, ParamValue Arg, } Address DeclPtr = Address::invalid(); - Address AllocaPtr = Address::invalid(); + RawAddress AllocaPtr = Address::invalid(); bool DoStore = false; bool IsScalar = hasScalarEvaluationKind(Ty); bool UseIndirectDebugAddress = false; @@ -2555,8 +2559,8 @@ void CodeGenFunction::EmitParmDecl(const VarDecl &D, ParamValue Arg, // Indirect argument is in alloca address space, which may be different // from the default address space. auto AllocaAS = CGM.getASTAllocaAddressSpace(); - auto *V = DeclPtr.getPointer(); - AllocaPtr = DeclPtr; + auto *V = DeclPtr.emitRawPointer(*this); + AllocaPtr = RawAddress(V, DeclPtr.getElementType(), DeclPtr.getAlignment()); // For truly ABI indirect arguments -- those that are not `byval` -- store // the address of the argument on the stack to preserve debug information. @@ -2695,7 +2699,7 @@ void CodeGenFunction::EmitParmDecl(const VarDecl &D, ParamValue Arg, } if (D.hasAttr()) - EmitVarAnnotations(&D, DeclPtr.getPointer()); + EmitVarAnnotations(&D, DeclPtr.emitRawPointer(*this)); // We can only check return value nullability if all arguments to the // function satisfy their nullability preconditions. This makes it necessary diff --git a/clang/lib/CodeGen/CGException.cpp b/clang/lib/CodeGen/CGException.cpp index 5a9d06da12de..34f289334a7d 100644 --- a/clang/lib/CodeGen/CGException.cpp +++ b/clang/lib/CodeGen/CGException.cpp @@ -397,7 +397,7 @@ namespace { void CodeGenFunction::EmitAnyExprToExn(const Expr *e, Address addr) { // Make sure the exception object is cleaned up if there's an // exception during initialization. - pushFullExprCleanup(EHCleanup, addr.getPointer()); + pushFullExprCleanup(EHCleanup, addr.emitRawPointer(*this)); EHScopeStack::stable_iterator cleanup = EHStack.stable_begin(); // __cxa_allocate_exception returns a void*; we need to cast this @@ -416,8 +416,8 @@ void CodeGenFunction::EmitAnyExprToExn(const Expr *e, Address addr) { /*IsInit*/ true); // Deactivate the cleanup block. - DeactivateCleanupBlock(cleanup, - cast(typedAddr.getPointer())); + DeactivateCleanupBlock( + cleanup, cast(typedAddr.emitRawPointer(*this))); } Address CodeGenFunction::getExceptionSlot() { @@ -1834,7 +1834,8 @@ Address CodeGenFunction::recoverAddrOfEscapedLocal(CodeGenFunction &ParentCGF, llvm::Value *ParentFP) { llvm::CallInst *RecoverCall = nullptr; CGBuilderTy Builder(*this, AllocaInsertPt); - if (auto *ParentAlloca = dyn_cast(ParentVar.getPointer())) { + if (auto *ParentAlloca = + dyn_cast_or_null(ParentVar.getBasePointer())) { // Mark the variable escaped if nobody else referenced it and compute the // localescape index. auto InsertPair = ParentCGF.EscapedLocals.insert( @@ -1851,8 +1852,8 @@ Address CodeGenFunction::recoverAddrOfEscapedLocal(CodeGenFunction &ParentCGF, // If the parent didn't have an alloca, we're doing some nested outlining. // Just clone the existing localrecover call, but tweak the FP argument to // use our FP value. All other arguments are constants. - auto *ParentRecover = - cast(ParentVar.getPointer()->stripPointerCasts()); + auto *ParentRecover = cast( + ParentVar.emitRawPointer(*this)->stripPointerCasts()); assert(ParentRecover->getIntrinsicID() == llvm::Intrinsic::localrecover && "expected alloca or localrecover in parent LocalDeclMap"); RecoverCall = cast(ParentRecover->clone()); @@ -1925,7 +1926,8 @@ void CodeGenFunction::EmitCapturedLocals(CodeGenFunction &ParentCGF, if (isa(D) && D->getType() == getContext().VoidPtrTy) { assert(D->getName().starts_with("frame_pointer")); - FramePtrAddrAlloca = cast(I.second.getPointer()); + FramePtrAddrAlloca = + cast(I.second.getBasePointer()); break; } } @@ -1986,7 +1988,8 @@ void CodeGenFunction::EmitCapturedLocals(CodeGenFunction &ParentCGF, LValue ThisFieldLValue = EmitLValueForLambdaField(LambdaThisCaptureField); if (!LambdaThisCaptureField->getType()->isPointerType()) { - CXXThisValue = ThisFieldLValue.getAddress(*this).getPointer(); + CXXThisValue = + ThisFieldLValue.getAddress(*this).emitRawPointer(*this); } else { CXXThisValue = EmitLoadOfLValue(ThisFieldLValue, SourceLocation()) .getScalarVal(); diff --git a/clang/lib/CodeGen/CGExpr.cpp b/clang/lib/CodeGen/CGExpr.cpp index 6491835cf8ef..36872c0fedb7 100644 --- a/clang/lib/CodeGen/CGExpr.cpp +++ b/clang/lib/CodeGen/CGExpr.cpp @@ -65,21 +65,21 @@ static llvm::cl::opt ClSanitizeDebugDeoptimization( /// CreateTempAlloca - This creates a alloca and inserts it into the entry /// block. -Address CodeGenFunction::CreateTempAllocaWithoutCast(llvm::Type *Ty, - CharUnits Align, - const Twine &Name, - llvm::Value *ArraySize) { +RawAddress +CodeGenFunction::CreateTempAllocaWithoutCast(llvm::Type *Ty, CharUnits Align, + const Twine &Name, + llvm::Value *ArraySize) { auto Alloca = CreateTempAlloca(Ty, Name, ArraySize); Alloca->setAlignment(Align.getAsAlign()); - return Address(Alloca, Ty, Align, KnownNonNull); + return RawAddress(Alloca, Ty, Align, KnownNonNull); } /// CreateTempAlloca - This creates a alloca and inserts it into the entry /// block. The alloca is casted to default address space if necessary. -Address CodeGenFunction::CreateTempAlloca(llvm::Type *Ty, CharUnits Align, - const Twine &Name, - llvm::Value *ArraySize, - Address *AllocaAddr) { +RawAddress CodeGenFunction::CreateTempAlloca(llvm::Type *Ty, CharUnits Align, + const Twine &Name, + llvm::Value *ArraySize, + RawAddress *AllocaAddr) { auto Alloca = CreateTempAllocaWithoutCast(Ty, Align, Name, ArraySize); if (AllocaAddr) *AllocaAddr = Alloca; @@ -101,7 +101,7 @@ Address CodeGenFunction::CreateTempAlloca(llvm::Type *Ty, CharUnits Align, Ty->getPointerTo(DestAddrSpace), /*non-null*/ true); } - return Address(V, Ty, Align, KnownNonNull); + return RawAddress(V, Ty, Align, KnownNonNull); } /// CreateTempAlloca - This creates an alloca and inserts it into the entry @@ -120,28 +120,29 @@ llvm::AllocaInst *CodeGenFunction::CreateTempAlloca(llvm::Type *Ty, /// default alignment of the corresponding LLVM type, which is *not* /// guaranteed to be related in any way to the expected alignment of /// an AST type that might have been lowered to Ty. -Address CodeGenFunction::CreateDefaultAlignTempAlloca(llvm::Type *Ty, - const Twine &Name) { +RawAddress CodeGenFunction::CreateDefaultAlignTempAlloca(llvm::Type *Ty, + const Twine &Name) { CharUnits Align = CharUnits::fromQuantity(CGM.getDataLayout().getPrefTypeAlign(Ty)); return CreateTempAlloca(Ty, Align, Name); } -Address CodeGenFunction::CreateIRTemp(QualType Ty, const Twine &Name) { +RawAddress CodeGenFunction::CreateIRTemp(QualType Ty, const Twine &Name) { CharUnits Align = getContext().getTypeAlignInChars(Ty); return CreateTempAlloca(ConvertType(Ty), Align, Name); } -Address CodeGenFunction::CreateMemTemp(QualType Ty, const Twine &Name, - Address *Alloca) { +RawAddress CodeGenFunction::CreateMemTemp(QualType Ty, const Twine &Name, + RawAddress *Alloca) { // FIXME: Should we prefer the preferred type alignment here? return CreateMemTemp(Ty, getContext().getTypeAlignInChars(Ty), Name, Alloca); } -Address CodeGenFunction::CreateMemTemp(QualType Ty, CharUnits Align, - const Twine &Name, Address *Alloca) { - Address Result = CreateTempAlloca(ConvertTypeForMem(Ty), Align, Name, - /*ArraySize=*/nullptr, Alloca); +RawAddress CodeGenFunction::CreateMemTemp(QualType Ty, CharUnits Align, + const Twine &Name, + RawAddress *Alloca) { + RawAddress Result = CreateTempAlloca(ConvertTypeForMem(Ty), Align, Name, + /*ArraySize=*/nullptr, Alloca); if (Ty->isConstantMatrixType()) { auto *ArrayTy = cast(Result.getElementType()); @@ -154,13 +155,14 @@ Address CodeGenFunction::CreateMemTemp(QualType Ty, CharUnits Align, return Result; } -Address CodeGenFunction::CreateMemTempWithoutCast(QualType Ty, CharUnits Align, - const Twine &Name) { +RawAddress CodeGenFunction::CreateMemTempWithoutCast(QualType Ty, + CharUnits Align, + const Twine &Name) { return CreateTempAllocaWithoutCast(ConvertTypeForMem(Ty), Align, Name); } -Address CodeGenFunction::CreateMemTempWithoutCast(QualType Ty, - const Twine &Name) { +RawAddress CodeGenFunction::CreateMemTempWithoutCast(QualType Ty, + const Twine &Name) { return CreateMemTempWithoutCast(Ty, getContext().getTypeAlignInChars(Ty), Name); } @@ -359,7 +361,7 @@ pushTemporaryCleanup(CodeGenFunction &CGF, const MaterializeTemporaryExpr *M, } else { CleanupFn = CGF.CGM.getAddrAndTypeOfCXXStructor( GlobalDecl(ReferenceTemporaryDtor, Dtor_Complete)); - CleanupArg = cast(ReferenceTemporary.getPointer()); + CleanupArg = cast(ReferenceTemporary.emitRawPointer(CGF)); } CGF.CGM.getCXXABI().registerGlobalDtor( CGF, *cast(M->getExtendingDecl()), CleanupFn, CleanupArg); @@ -384,10 +386,10 @@ pushTemporaryCleanup(CodeGenFunction &CGF, const MaterializeTemporaryExpr *M, } } -static Address createReferenceTemporary(CodeGenFunction &CGF, - const MaterializeTemporaryExpr *M, - const Expr *Inner, - Address *Alloca = nullptr) { +static RawAddress createReferenceTemporary(CodeGenFunction &CGF, + const MaterializeTemporaryExpr *M, + const Expr *Inner, + RawAddress *Alloca = nullptr) { auto &TCG = CGF.getTargetHooks(); switch (M->getStorageDuration()) { case SD_FullExpression: @@ -416,7 +418,7 @@ static Address createReferenceTemporary(CodeGenFunction &CGF, GV->getValueType()->getPointerTo( CGF.getContext().getTargetAddressSpace(LangAS::Default))); // FIXME: Should we put the new global into a COMDAT? - return Address(C, GV->getValueType(), alignment); + return RawAddress(C, GV->getValueType(), alignment); } return CGF.CreateMemTemp(Ty, "ref.tmp", Alloca); } @@ -448,7 +450,7 @@ EmitMaterializeTemporaryExpr(const MaterializeTemporaryExpr *M) { auto ownership = M->getType().getObjCLifetime(); if (ownership != Qualifiers::OCL_None && ownership != Qualifiers::OCL_ExplicitNone) { - Address Object = createReferenceTemporary(*this, M, E); + RawAddress Object = createReferenceTemporary(*this, M, E); if (auto *Var = dyn_cast(Object.getPointer())) { llvm::Type *Ty = ConvertTypeForMem(E->getType()); Object = Object.withElementType(Ty); @@ -502,8 +504,8 @@ EmitMaterializeTemporaryExpr(const MaterializeTemporaryExpr *M) { } // Create and initialize the reference temporary. - Address Alloca = Address::invalid(); - Address Object = createReferenceTemporary(*this, M, E, &Alloca); + RawAddress Alloca = Address::invalid(); + RawAddress Object = createReferenceTemporary(*this, M, E, &Alloca); if (auto *Var = dyn_cast( Object.getPointer()->stripPointerCasts())) { llvm::Type *TemporaryType = ConvertTypeForMem(E->getType()); @@ -1111,12 +1113,12 @@ llvm::Value *CodeGenFunction::EmitCountedByFieldExpr( } else if (const MemberExpr *ME = dyn_cast(StructBase)) { LValue LV = EmitMemberExpr(ME); Address Addr = LV.getAddress(*this); - Res = Addr.getPointer(); + Res = Addr.emitRawPointer(*this); } else if (StructBase->getType()->isPointerType()) { LValueBaseInfo BaseInfo; TBAAAccessInfo TBAAInfo; Address Addr = EmitPointerWithAlignment(StructBase, &BaseInfo, &TBAAInfo); - Res = Addr.getPointer(); + Res = Addr.emitRawPointer(*this); } else { return nullptr; } @@ -1282,8 +1284,7 @@ static Address EmitPointerWithAlignment(const Expr *E, LValueBaseInfo *BaseInfo, if (InnerBaseInfo.getAlignmentSource() != AlignmentSource::Decl) { if (BaseInfo) BaseInfo->mergeForCast(TargetTypeBaseInfo); - Addr = Address(Addr.getPointer(), Addr.getElementType(), Align, - IsKnownNonNull); + Addr.setAlignment(Align); } } @@ -1300,8 +1301,8 @@ static Address EmitPointerWithAlignment(const Expr *E, LValueBaseInfo *BaseInfo, CGF.ConvertTypeForMem(E->getType()->getPointeeType()); Addr = Addr.withElementType(ElemTy); if (CE->getCastKind() == CK_AddressSpaceConversion) - Addr = CGF.Builder.CreateAddrSpaceCast(Addr, - CGF.ConvertType(E->getType())); + Addr = CGF.Builder.CreateAddrSpaceCast( + Addr, CGF.ConvertType(E->getType()), ElemTy); return Addr; } break; @@ -1364,10 +1365,9 @@ static Address EmitPointerWithAlignment(const Expr *E, LValueBaseInfo *BaseInfo, // TODO: conditional operators, comma. // Otherwise, use the alignment of the type. - CharUnits Align = - CGF.CGM.getNaturalPointeeTypeAlignment(E->getType(), BaseInfo, TBAAInfo); - llvm::Type *ElemTy = CGF.ConvertTypeForMem(E->getType()->getPointeeType()); - return Address(CGF.EmitScalarExpr(E), ElemTy, Align, IsKnownNonNull); + return CGF.makeNaturalAddressForPointer( + CGF.EmitScalarExpr(E), E->getType()->getPointeeType(), CharUnits(), + /*ForPointeeType=*/true, BaseInfo, TBAAInfo, IsKnownNonNull); } /// EmitPointerWithAlignment - Given an expression of pointer type, try to @@ -1468,8 +1468,7 @@ LValue CodeGenFunction::EmitCheckedLValue(const Expr *E, TypeCheckKind TCK) { if (IsBaseCXXThis || isa(ME->getBase())) SkippedChecks.set(SanitizerKind::Null, true); } - EmitTypeCheck(TCK, E->getExprLoc(), LV.getPointer(*this), E->getType(), - LV.getAlignment(), SkippedChecks); + EmitTypeCheck(TCK, E->getExprLoc(), LV, E->getType(), SkippedChecks); } return LV; } @@ -1581,11 +1580,11 @@ LValue CodeGenFunction::EmitLValueHelper(const Expr *E, // Defend against branches out of gnu statement expressions surrounded by // cleanups. Address Addr = LV.getAddress(*this); - llvm::Value *V = Addr.getPointer(); + llvm::Value *V = Addr.getBasePointer(); Scope.ForceCleanup({&V}); - return LValue::MakeAddr(Addr.withPointer(V, Addr.isKnownNonNull()), - LV.getType(), getContext(), LV.getBaseInfo(), - LV.getTBAAInfo()); + Addr.replaceBasePointer(V); + return LValue::MakeAddr(Addr, LV.getType(), getContext(), + LV.getBaseInfo(), LV.getTBAAInfo()); } // FIXME: Is it possible to create an ExprWithCleanups that produces a // bitfield lvalue or some other non-simple lvalue? @@ -1929,7 +1928,7 @@ llvm::Value *CodeGenFunction::EmitLoadOfScalar(Address Addr, bool Volatile, LValueBaseInfo BaseInfo, TBAAAccessInfo TBAAInfo, bool isNontemporal) { - if (auto *GV = dyn_cast(Addr.getPointer())) + if (auto *GV = dyn_cast(Addr.getBasePointer())) if (GV->isThreadLocal()) Addr = Addr.withPointer(Builder.CreateThreadLocalAddress(GV), NotKnownNonNull); @@ -2039,8 +2038,9 @@ llvm::Value *CodeGenFunction::EmitFromMemory(llvm::Value *Value, QualType Ty) { // Convert the pointer of \p Addr to a pointer to a vector (the value type of // MatrixType), if it points to a array (the memory type of MatrixType). -static Address MaybeConvertMatrixAddress(Address Addr, CodeGenFunction &CGF, - bool IsVector = true) { +static RawAddress MaybeConvertMatrixAddress(RawAddress Addr, + CodeGenFunction &CGF, + bool IsVector = true) { auto *ArrayTy = dyn_cast(Addr.getElementType()); if (ArrayTy && IsVector) { auto *VectorTy = llvm::FixedVectorType::get(ArrayTy->getElementType(), @@ -2077,7 +2077,7 @@ void CodeGenFunction::EmitStoreOfScalar(llvm::Value *Value, Address Addr, LValueBaseInfo BaseInfo, TBAAAccessInfo TBAAInfo, bool isInit, bool isNontemporal) { - if (auto *GV = dyn_cast(Addr.getPointer())) + if (auto *GV = dyn_cast(Addr.getBasePointer())) if (GV->isThreadLocal()) Addr = Addr.withPointer(Builder.CreateThreadLocalAddress(GV), NotKnownNonNull); @@ -2432,14 +2432,12 @@ void CodeGenFunction::EmitStoreThroughLValue(RValue Src, LValue Dst, assert(Dst.getBaseIvarExp() && "BaseIvarExp is NULL"); llvm::Type *ResultType = IntPtrTy; Address dst = EmitPointerWithAlignment(Dst.getBaseIvarExp()); - llvm::Value *RHS = dst.getPointer(); + llvm::Value *RHS = dst.emitRawPointer(*this); RHS = Builder.CreatePtrToInt(RHS, ResultType, "sub.ptr.rhs.cast"); - llvm::Value *LHS = - Builder.CreatePtrToInt(LvalueDst.getPointer(), ResultType, - "sub.ptr.lhs.cast"); + llvm::Value *LHS = Builder.CreatePtrToInt(LvalueDst.emitRawPointer(*this), + ResultType, "sub.ptr.lhs.cast"); llvm::Value *BytesBetween = Builder.CreateSub(LHS, RHS, "ivar.offset"); - CGM.getObjCRuntime().EmitObjCIvarAssign(*this, src, dst, - BytesBetween); + CGM.getObjCRuntime().EmitObjCIvarAssign(*this, src, dst, BytesBetween); } else if (Dst.isGlobalObjCRef()) { CGM.getObjCRuntime().EmitObjCGlobalAssign(*this, src, LvalueDst, Dst.isThreadLocalRef()); @@ -2770,12 +2768,9 @@ CodeGenFunction::EmitLoadOfReference(LValue RefLVal, llvm::LoadInst *Load = Builder.CreateLoad(RefLVal.getAddress(*this), RefLVal.isVolatile()); CGM.DecorateInstructionWithTBAA(Load, RefLVal.getTBAAInfo()); - - QualType PointeeType = RefLVal.getType()->getPointeeType(); - CharUnits Align = CGM.getNaturalTypeAlignment( - PointeeType, PointeeBaseInfo, PointeeTBAAInfo, - /* forPointeeType= */ true); - return Address(Load, ConvertTypeForMem(PointeeType), Align); + return makeNaturalAddressForPointer(Load, RefLVal.getType()->getPointeeType(), + CharUnits(), /*ForPointeeType=*/true, + PointeeBaseInfo, PointeeTBAAInfo); } LValue CodeGenFunction::EmitLoadOfReferenceLValue(LValue RefLVal) { @@ -2792,10 +2787,9 @@ Address CodeGenFunction::EmitLoadOfPointer(Address Ptr, LValueBaseInfo *BaseInfo, TBAAAccessInfo *TBAAInfo) { llvm::Value *Addr = Builder.CreateLoad(Ptr); - return Address(Addr, ConvertTypeForMem(PtrTy->getPointeeType()), - CGM.getNaturalTypeAlignment(PtrTy->getPointeeType(), BaseInfo, - TBAAInfo, - /*forPointeeType=*/true)); + return makeNaturalAddressForPointer(Addr, PtrTy->getPointeeType(), + CharUnits(), /*ForPointeeType=*/true, + BaseInfo, TBAAInfo); } LValue CodeGenFunction::EmitLoadOfPointerLValue(Address PtrAddr, @@ -2991,7 +2985,7 @@ LValue CodeGenFunction::EmitDeclRefLValue(const DeclRefExpr *E) { /* BaseInfo= */ nullptr, /* TBAAInfo= */ nullptr, /* forPointeeType= */ true); - Addr = Address(Val, ConvertTypeForMem(E->getType()), Alignment); + Addr = makeNaturalAddressForPointer(Val, T, Alignment); } return MakeAddrLValue(Addr, T, AlignmentSource::Decl); } @@ -3023,11 +3017,12 @@ LValue CodeGenFunction::EmitDeclRefLValue(const DeclRefExpr *E) { EmitCapturedFieldLValue(*this, CapturedStmtInfo->lookup(VD), CapturedStmtInfo->getContextValue()); Address LValueAddress = CapLVal.getAddress(*this); - CapLVal = MakeAddrLValue( - Address(LValueAddress.getPointer(), LValueAddress.getElementType(), - getContext().getDeclAlign(VD)), - CapLVal.getType(), LValueBaseInfo(AlignmentSource::Decl), - CapLVal.getTBAAInfo()); + CapLVal = MakeAddrLValue(Address(LValueAddress.emitRawPointer(*this), + LValueAddress.getElementType(), + getContext().getDeclAlign(VD)), + CapLVal.getType(), + LValueBaseInfo(AlignmentSource::Decl), + CapLVal.getTBAAInfo()); // Mark lvalue as nontemporal if the variable is marked as nontemporal // in simd context. if (getLangOpts().OpenMP && @@ -3083,7 +3078,8 @@ LValue CodeGenFunction::EmitDeclRefLValue(const DeclRefExpr *E) { // Handle threadlocal function locals. if (VD->getTLSKind() != VarDecl::TLS_None) addr = addr.withPointer( - Builder.CreateThreadLocalAddress(addr.getPointer()), NotKnownNonNull); + Builder.CreateThreadLocalAddress(addr.getBasePointer()), + NotKnownNonNull); // Check for OpenMP threadprivate variables. if (getLangOpts().OpenMP && !getLangOpts().OpenMPSimd && @@ -3351,7 +3347,7 @@ llvm::Value *CodeGenFunction::EmitCheckValue(llvm::Value *V) { // Pointers are passed directly, everything else is passed by address. if (!V->getType()->isPointerTy()) { - Address Ptr = CreateDefaultAlignTempAlloca(V->getType()); + RawAddress Ptr = CreateDefaultAlignTempAlloca(V->getType()); Builder.CreateStore(V, Ptr); V = Ptr.getPointer(); } @@ -3924,6 +3920,21 @@ static llvm::Value *emitArraySubscriptGEP(CodeGenFunction &CGF, } } +static Address emitArraySubscriptGEP(CodeGenFunction &CGF, Address addr, + ArrayRef indices, + llvm::Type *elementType, bool inbounds, + bool signedIndices, SourceLocation loc, + CharUnits align, + const llvm::Twine &name = "arrayidx") { + if (inbounds) { + return CGF.EmitCheckedInBoundsGEP(addr, indices, elementType, signedIndices, + CodeGenFunction::NotSubtraction, loc, + align, name); + } else { + return CGF.Builder.CreateGEP(addr, indices, elementType, align, name); + } +} + static CharUnits getArrayElementAlign(CharUnits arrayAlign, llvm::Value *idx, CharUnits eltSize) { @@ -3971,7 +3982,7 @@ static Address wrapWithBPFPreserveStaticOffset(CodeGenFunction &CGF, llvm::Function *Fn = CGF.CGM.getIntrinsic(llvm::Intrinsic::preserve_static_offset); - llvm::CallInst *Call = CGF.Builder.CreateCall(Fn, {Addr.getPointer()}); + llvm::CallInst *Call = CGF.Builder.CreateCall(Fn, {Addr.emitRawPointer(CGF)}); return Address(Call, Addr.getElementType(), Addr.getAlignment()); } @@ -4034,7 +4045,7 @@ static Address emitArraySubscriptGEP(CodeGenFunction &CGF, Address addr, // We can use that to compute the best alignment of the element. CharUnits eltSize = CGF.getContext().getTypeSizeInChars(eltType); CharUnits eltAlign = - getArrayElementAlign(addr.getAlignment(), indices.back(), eltSize); + getArrayElementAlign(addr.getAlignment(), indices.back(), eltSize); if (hasBPFPreserveStaticOffset(Base)) addr = wrapWithBPFPreserveStaticOffset(CGF, addr); @@ -4043,19 +4054,19 @@ static Address emitArraySubscriptGEP(CodeGenFunction &CGF, Address addr, auto LastIndex = dyn_cast(indices.back()); if (!LastIndex || (!CGF.IsInPreservedAIRegion && !IsPreserveAIArrayBase(CGF, Base))) { - eltPtr = emitArraySubscriptGEP( - CGF, addr.getElementType(), addr.getPointer(), indices, inbounds, - signedIndices, loc, name); + addr = emitArraySubscriptGEP(CGF, addr, indices, + CGF.ConvertTypeForMem(eltType), inbounds, + signedIndices, loc, eltAlign, name); + return addr; } else { // Remember the original array subscript for bpf target unsigned idx = LastIndex->getZExtValue(); llvm::DIType *DbgInfo = nullptr; if (arrayType) DbgInfo = CGF.getDebugInfo()->getOrCreateStandaloneType(*arrayType, loc); - eltPtr = CGF.Builder.CreatePreserveArrayAccessIndex(addr.getElementType(), - addr.getPointer(), - indices.size() - 1, - idx, DbgInfo); + eltPtr = CGF.Builder.CreatePreserveArrayAccessIndex( + addr.getElementType(), addr.emitRawPointer(CGF), indices.size() - 1, + idx, DbgInfo); } return Address(eltPtr, CGF.ConvertTypeForMem(eltType), eltAlign); @@ -4224,8 +4235,8 @@ LValue CodeGenFunction::EmitArraySubscriptExpr(const ArraySubscriptExpr *E, CharUnits EltAlign = getArrayElementAlign(Addr.getAlignment(), Idx, InterfaceSize); llvm::Value *EltPtr = - emitArraySubscriptGEP(*this, Int8Ty, Addr.getPointer(), ScaledIdx, - false, SignedIndices, E->getExprLoc()); + emitArraySubscriptGEP(*this, Int8Ty, Addr.emitRawPointer(*this), + ScaledIdx, false, SignedIndices, E->getExprLoc()); Addr = Address(EltPtr, OrigBaseElemTy, EltAlign); } else if (const Expr *Array = isSimpleArrayDecayOperand(E->getBase())) { // If this is A[i] where A is an array, the frontend will have decayed the @@ -4271,7 +4282,7 @@ LValue CodeGenFunction::EmitArraySubscriptExpr(const ArraySubscriptExpr *E, llvm::Type *CountTy = ConvertType(CountFD->getType()); llvm::Value *Res = Builder.CreateInBoundsGEP( - Int8Ty, Addr.getPointer(), + Int8Ty, Addr.emitRawPointer(*this), Builder.getInt32(OffsetDiff.getQuantity()), ".counted_by.gep"); Res = Builder.CreateAlignedLoad(CountTy, Res, getIntAlign(), ".counted_by.load"); @@ -4517,9 +4528,9 @@ LValue CodeGenFunction::EmitOMPArraySectionExpr(const OMPArraySectionExpr *E, BaseInfo = ArrayLV.getBaseInfo(); TBAAInfo = CGM.getTBAAInfoForSubobject(ArrayLV, ResultExprTy); } else { - Address Base = emitOMPArraySectionBase(*this, E->getBase(), BaseInfo, - TBAAInfo, BaseTy, ResultExprTy, - IsLowerBound); + Address Base = + emitOMPArraySectionBase(*this, E->getBase(), BaseInfo, TBAAInfo, BaseTy, + ResultExprTy, IsLowerBound); EltPtr = emitArraySubscriptGEP(*this, Base, Idx, ResultExprTy, !getLangOpts().isSignedOverflowDefined(), /*signedIndices=*/false, E->getExprLoc()); @@ -4606,7 +4617,7 @@ LValue CodeGenFunction::EmitMemberExpr(const MemberExpr *E) { SkippedChecks.set(SanitizerKind::Alignment, true); if (IsBaseCXXThis || isa(BaseExpr)) SkippedChecks.set(SanitizerKind::Null, true); - EmitTypeCheck(TCK_MemberAccess, E->getExprLoc(), Addr.getPointer(), PtrTy, + EmitTypeCheck(TCK_MemberAccess, E->getExprLoc(), Addr, PtrTy, /*Alignment=*/CharUnits::Zero(), SkippedChecks); BaseLV = MakeAddrLValue(Addr, PtrTy, BaseInfo, TBAAInfo); } else @@ -4655,8 +4666,8 @@ LValue CodeGenFunction::EmitLValueForLambdaField(const FieldDecl *Field, LambdaLV = EmitLoadOfReferenceLValue(AddrOfExplicitObject, D->getType(), AlignmentSource::Decl); else - LambdaLV = MakeNaturalAlignAddrLValue(AddrOfExplicitObject.getPointer(), - D->getType().getNonReferenceType()); + LambdaLV = MakeAddrLValue(AddrOfExplicitObject, + D->getType().getNonReferenceType()); } else { QualType LambdaTagType = getContext().getTagDeclType(Field->getParent()); LambdaLV = MakeNaturalAlignAddrLValue(ThisValue, LambdaTagType); @@ -4846,7 +4857,8 @@ LValue CodeGenFunction::EmitLValueForField(LValue base, // information provided by invariant.group. This is because accessing // fields may leak the real address of dynamic object, which could result // in miscompilation when leaked pointer would be compared. - auto *stripped = Builder.CreateStripInvariantGroup(addr.getPointer()); + auto *stripped = + Builder.CreateStripInvariantGroup(addr.emitRawPointer(*this)); addr = Address(stripped, addr.getElementType(), addr.getAlignment()); } } @@ -4865,10 +4877,11 @@ LValue CodeGenFunction::EmitLValueForField(LValue base, // Remember the original union field index llvm::DIType *DbgInfo = getDebugInfo()->getOrCreateStandaloneType(base.getType(), rec->getLocation()); - addr = Address( - Builder.CreatePreserveUnionAccessIndex( - addr.getPointer(), getDebugInfoFIndex(rec, field->getFieldIndex()), DbgInfo), - addr.getElementType(), addr.getAlignment()); + addr = + Address(Builder.CreatePreserveUnionAccessIndex( + addr.emitRawPointer(*this), + getDebugInfoFIndex(rec, field->getFieldIndex()), DbgInfo), + addr.getElementType(), addr.getAlignment()); } if (FieldType->isReferenceType()) @@ -5105,11 +5118,9 @@ LValue CodeGenFunction::EmitConditionalOperatorLValue( if (Info.LHS && Info.RHS) { Address lhsAddr = Info.LHS->getAddress(*this); Address rhsAddr = Info.RHS->getAddress(*this); - llvm::PHINode *phi = Builder.CreatePHI(lhsAddr.getType(), 2, "cond-lvalue"); - phi->addIncoming(lhsAddr.getPointer(), Info.lhsBlock); - phi->addIncoming(rhsAddr.getPointer(), Info.rhsBlock); - Address result(phi, lhsAddr.getElementType(), - std::min(lhsAddr.getAlignment(), rhsAddr.getAlignment())); + Address result = mergeAddressesInConditionalExpr( + lhsAddr, rhsAddr, Info.lhsBlock, Info.rhsBlock, + Builder.GetInsertBlock(), expr->getType()); AlignmentSource alignSource = std::max(Info.LHS->getBaseInfo().getAlignmentSource(), Info.RHS->getBaseInfo().getAlignmentSource()); @@ -5196,7 +5207,7 @@ LValue CodeGenFunction::EmitCastLValue(const CastExpr *E) { LValue LV = EmitLValue(E->getSubExpr()); Address V = LV.getAddress(*this); const auto *DCE = cast(E); - return MakeNaturalAlignAddrLValue(EmitDynamicCast(V, DCE), E->getType()); + return MakeNaturalAlignRawAddrLValue(EmitDynamicCast(V, DCE), E->getType()); } case CK_ConstructorConversion: @@ -5261,8 +5272,8 @@ LValue CodeGenFunction::EmitCastLValue(const CastExpr *E) { // C++11 [expr.static.cast]p2: Behavior is undefined if a downcast is // performed and the object is not of the derived type. if (sanitizePerformTypeCheck()) - EmitTypeCheck(TCK_DowncastReference, E->getExprLoc(), - Derived.getPointer(), E->getType()); + EmitTypeCheck(TCK_DowncastReference, E->getExprLoc(), Derived, + E->getType()); if (SanOpts.has(SanitizerKind::CFIDerivedCast)) EmitVTablePtrCheckForCast(E->getType(), Derived, @@ -5618,7 +5629,7 @@ LValue CodeGenFunction::EmitCXXConstructLValue(const CXXConstructExpr *E) { LValue CodeGenFunction::EmitCXXTypeidLValue(const CXXTypeidExpr *E) { - return MakeNaturalAlignAddrLValue(EmitCXXTypeidExpr(E), E->getType()); + return MakeNaturalAlignRawAddrLValue(EmitCXXTypeidExpr(E), E->getType()); } Address CodeGenFunction::EmitCXXUuidofExpr(const CXXUuidofExpr *E) { diff --git a/clang/lib/CodeGen/CGExprAgg.cpp b/clang/lib/CodeGen/CGExprAgg.cpp index 5190b22bcc16..143855aa84ca 100644 --- a/clang/lib/CodeGen/CGExprAgg.cpp +++ b/clang/lib/CodeGen/CGExprAgg.cpp @@ -294,10 +294,10 @@ void AggExprEmitter::withReturnValueSlot( // Otherwise, EmitCall will emit its own, notice that it's "unused", and end // its lifetime before we have the chance to emit a proper destructor call. bool UseTemp = Dest.isPotentiallyAliased() || Dest.requiresGCollection() || - (RequiresDestruction && !Dest.getAddress().isValid()); + (RequiresDestruction && Dest.isIgnored()); Address RetAddr = Address::invalid(); - Address RetAllocaAddr = Address::invalid(); + RawAddress RetAllocaAddr = RawAddress::invalid(); EHScopeStack::stable_iterator LifetimeEndBlock; llvm::Value *LifetimeSizePtr = nullptr; @@ -329,7 +329,8 @@ void AggExprEmitter::withReturnValueSlot( if (!UseTemp) return; - assert(Dest.isIgnored() || Dest.getPointer() != Src.getAggregatePointer()); + assert(Dest.isIgnored() || Dest.emitRawPointer(CGF) != + Src.getAggregatePointer(E->getType(), CGF)); EmitFinalDestCopy(E->getType(), Src); if (!RequiresDestruction && LifetimeStartInst) { @@ -448,7 +449,8 @@ AggExprEmitter::VisitCXXStdInitializerListExpr(CXXStdInitializerListExpr *E) { llvm::Value *Zero = llvm::ConstantInt::get(CGF.PtrDiffTy, 0); llvm::Value *IdxStart[] = { Zero, Zero }; llvm::Value *ArrayStart = Builder.CreateInBoundsGEP( - ArrayPtr.getElementType(), ArrayPtr.getPointer(), IdxStart, "arraystart"); + ArrayPtr.getElementType(), ArrayPtr.emitRawPointer(CGF), IdxStart, + "arraystart"); CGF.EmitStoreThroughLValue(RValue::get(ArrayStart), Start); ++Field; @@ -465,7 +467,8 @@ AggExprEmitter::VisitCXXStdInitializerListExpr(CXXStdInitializerListExpr *E) { // End pointer. llvm::Value *IdxEnd[] = { Zero, Size }; llvm::Value *ArrayEnd = Builder.CreateInBoundsGEP( - ArrayPtr.getElementType(), ArrayPtr.getPointer(), IdxEnd, "arrayend"); + ArrayPtr.getElementType(), ArrayPtr.emitRawPointer(CGF), IdxEnd, + "arrayend"); CGF.EmitStoreThroughLValue(RValue::get(ArrayEnd), EndOrLength); } else if (Ctx.hasSameType(Field->getType(), Ctx.getSizeType())) { // Length. @@ -516,9 +519,9 @@ void AggExprEmitter::EmitArrayInit(Address DestPtr, llvm::ArrayType *AType, // down a level. llvm::Value *zero = llvm::ConstantInt::get(CGF.SizeTy, 0); llvm::Value *indices[] = { zero, zero }; - llvm::Value *begin = Builder.CreateInBoundsGEP( - DestPtr.getElementType(), DestPtr.getPointer(), indices, - "arrayinit.begin"); + llvm::Value *begin = Builder.CreateInBoundsGEP(DestPtr.getElementType(), + DestPtr.emitRawPointer(CGF), + indices, "arrayinit.begin"); CharUnits elementSize = CGF.getContext().getTypeSizeInChars(elementType); CharUnits elementAlign = @@ -1059,7 +1062,7 @@ void AggExprEmitter::VisitBinCmp(const BinaryOperator *E) { if (RV.isScalar()) return {RV.getScalarVal(), nullptr}; if (RV.isAggregate()) - return {RV.getAggregatePointer(), nullptr}; + return {RV.getAggregatePointer(E->getType(), CGF), nullptr}; assert(RV.isComplex()); return RV.getComplexVal(); }; @@ -1818,7 +1821,7 @@ void AggExprEmitter::VisitCXXParenListOrInitListExpr( // else, clean it up for -O0 builds and general tidiness. if (!pushedCleanup && LV.isSimple()) if (llvm::GetElementPtrInst *GEP = - dyn_cast(LV.getPointer(CGF))) + dyn_cast(LV.emitRawPointer(CGF))) if (GEP->use_empty()) GEP->eraseFromParent(); } @@ -1849,9 +1852,9 @@ void AggExprEmitter::VisitArrayInitLoopExpr(const ArrayInitLoopExpr *E, // destPtr is an array*. Construct an elementType* by drilling down a level. llvm::Value *zero = llvm::ConstantInt::get(CGF.SizeTy, 0); llvm::Value *indices[] = {zero, zero}; - llvm::Value *begin = Builder.CreateInBoundsGEP( - destPtr.getElementType(), destPtr.getPointer(), indices, - "arrayinit.begin"); + llvm::Value *begin = Builder.CreateInBoundsGEP(destPtr.getElementType(), + destPtr.emitRawPointer(CGF), + indices, "arrayinit.begin"); // Prepare to special-case multidimensional array initialization: we avoid // emitting multiple destructor loops in that case. diff --git a/clang/lib/CodeGen/CGExprCXX.cpp b/clang/lib/CodeGen/CGExprCXX.cpp index 35da0f1a89bc..a4fb673284ce 100644 --- a/clang/lib/CodeGen/CGExprCXX.cpp +++ b/clang/lib/CodeGen/CGExprCXX.cpp @@ -280,7 +280,8 @@ RValue CodeGenFunction::EmitCXXMemberOrOperatorMemberCallExpr( LValueBaseInfo BaseInfo; TBAAAccessInfo TBAAInfo; Address ThisValue = EmitPointerWithAlignment(Base, &BaseInfo, &TBAAInfo); - This = MakeAddrLValue(ThisValue, Base->getType(), BaseInfo, TBAAInfo); + This = MakeAddrLValue(ThisValue, Base->getType()->getPointeeType(), + BaseInfo, TBAAInfo); } else { This = EmitLValue(Base); } @@ -353,10 +354,12 @@ RValue CodeGenFunction::EmitCXXMemberOrOperatorMemberCallExpr( if (IsImplicitObjectCXXThis || isa(IOA)) SkippedChecks.set(SanitizerKind::Null, true); } - EmitTypeCheck(CodeGenFunction::TCK_MemberCall, CallLoc, - This.getPointer(*this), - C.getRecordType(CalleeDecl->getParent()), - /*Alignment=*/CharUnits::Zero(), SkippedChecks); + + if (sanitizePerformTypeCheck()) + EmitTypeCheck(CodeGenFunction::TCK_MemberCall, CallLoc, + This.emitRawPointer(*this), + C.getRecordType(CalleeDecl->getParent()), + /*Alignment=*/CharUnits::Zero(), SkippedChecks); // C++ [class.virtual]p12: // Explicit qualification with the scope operator (5.1) suppresses the @@ -455,7 +458,7 @@ CodeGenFunction::EmitCXXMemberPointerCallExpr(const CXXMemberCallExpr *E, else This = EmitLValue(BaseExpr, KnownNonNull).getAddress(*this); - EmitTypeCheck(TCK_MemberCall, E->getExprLoc(), This.getPointer(), + EmitTypeCheck(TCK_MemberCall, E->getExprLoc(), This.emitRawPointer(*this), QualType(MPT->getClass(), 0)); // Get the member function pointer. @@ -1109,9 +1112,10 @@ void CodeGenFunction::EmitNewArrayInitializer( // alloca. EndOfInit = CreateTempAlloca(BeginPtr.getType(), getPointerAlign(), "array.init.end"); - CleanupDominator = Builder.CreateStore(BeginPtr.getPointer(), EndOfInit); - pushIrregularPartialArrayCleanup(BeginPtr.getPointer(), EndOfInit, - ElementType, ElementAlign, + CleanupDominator = + Builder.CreateStore(BeginPtr.emitRawPointer(*this), EndOfInit); + pushIrregularPartialArrayCleanup(BeginPtr.emitRawPointer(*this), + EndOfInit, ElementType, ElementAlign, getDestroyer(DtorKind)); Cleanup = EHStack.stable_begin(); } @@ -1123,16 +1127,17 @@ void CodeGenFunction::EmitNewArrayInitializer( // element. TODO: some of these stores can be trivially // observed to be unnecessary. if (EndOfInit.isValid()) { - Builder.CreateStore(CurPtr.getPointer(), EndOfInit); + Builder.CreateStore(CurPtr.emitRawPointer(*this), EndOfInit); } // FIXME: If the last initializer is an incomplete initializer list for // an array, and we have an array filler, we can fold together the two // initialization loops. StoreAnyExprIntoOneUnit(*this, IE, IE->getType(), CurPtr, AggValueSlot::DoesNotOverlap); - CurPtr = Address(Builder.CreateInBoundsGEP( - CurPtr.getElementType(), CurPtr.getPointer(), - Builder.getSize(1), "array.exp.next"), + CurPtr = Address(Builder.CreateInBoundsGEP(CurPtr.getElementType(), + CurPtr.emitRawPointer(*this), + Builder.getSize(1), + "array.exp.next"), CurPtr.getElementType(), StartAlign.alignmentAtOffset((++i) * ElementSize)); } @@ -1186,7 +1191,7 @@ void CodeGenFunction::EmitNewArrayInitializer( // FIXME: Share this cleanup with the constructor call emission rather than // having it create a cleanup of its own. if (EndOfInit.isValid()) - Builder.CreateStore(CurPtr.getPointer(), EndOfInit); + Builder.CreateStore(CurPtr.emitRawPointer(*this), EndOfInit); // Emit a constructor call loop to initialize the remaining elements. if (InitListElements) @@ -1249,15 +1254,15 @@ void CodeGenFunction::EmitNewArrayInitializer( llvm::BasicBlock *ContBB = createBasicBlock("new.loop.end"); // Find the end of the array, hoisted out of the loop. - llvm::Value *EndPtr = - Builder.CreateInBoundsGEP(BeginPtr.getElementType(), BeginPtr.getPointer(), - NumElements, "array.end"); + llvm::Value *EndPtr = Builder.CreateInBoundsGEP( + BeginPtr.getElementType(), BeginPtr.emitRawPointer(*this), NumElements, + "array.end"); // If the number of elements isn't constant, we have to now check if there is // anything left to initialize. if (!ConstNum) { - llvm::Value *IsEmpty = - Builder.CreateICmpEQ(CurPtr.getPointer(), EndPtr, "array.isempty"); + llvm::Value *IsEmpty = Builder.CreateICmpEQ(CurPtr.emitRawPointer(*this), + EndPtr, "array.isempty"); Builder.CreateCondBr(IsEmpty, ContBB, LoopBB); } @@ -1267,19 +1272,20 @@ void CodeGenFunction::EmitNewArrayInitializer( // Set up the current-element phi. llvm::PHINode *CurPtrPhi = Builder.CreatePHI(CurPtr.getType(), 2, "array.cur"); - CurPtrPhi->addIncoming(CurPtr.getPointer(), EntryBB); + CurPtrPhi->addIncoming(CurPtr.emitRawPointer(*this), EntryBB); CurPtr = Address(CurPtrPhi, CurPtr.getElementType(), ElementAlign); // Store the new Cleanup position for irregular Cleanups. if (EndOfInit.isValid()) - Builder.CreateStore(CurPtr.getPointer(), EndOfInit); + Builder.CreateStore(CurPtr.emitRawPointer(*this), EndOfInit); // Enter a partial-destruction Cleanup if necessary. if (!CleanupDominator && needsEHCleanup(DtorKind)) { - pushRegularPartialArrayCleanup(BeginPtr.getPointer(), CurPtr.getPointer(), - ElementType, ElementAlign, - getDestroyer(DtorKind)); + llvm::Value *BeginPtrRaw = BeginPtr.emitRawPointer(*this); + llvm::Value *CurPtrRaw = CurPtr.emitRawPointer(*this); + pushRegularPartialArrayCleanup(BeginPtrRaw, CurPtrRaw, ElementType, + ElementAlign, getDestroyer(DtorKind)); Cleanup = EHStack.stable_begin(); CleanupDominator = Builder.CreateUnreachable(); } @@ -1295,9 +1301,8 @@ void CodeGenFunction::EmitNewArrayInitializer( } // Advance to the next element by adjusting the pointer type as necessary. - llvm::Value *NextPtr = - Builder.CreateConstInBoundsGEP1_32(ElementTy, CurPtr.getPointer(), 1, - "array.next"); + llvm::Value *NextPtr = Builder.CreateConstInBoundsGEP1_32( + ElementTy, CurPtr.emitRawPointer(*this), 1, "array.next"); // Check whether we've gotten to the end of the array and, if so, // exit the loop. @@ -1523,14 +1528,9 @@ static void EnterNewDeleteCleanup(CodeGenFunction &CGF, typedef CallDeleteDuringNew DirectCleanup; - DirectCleanup *Cleanup = CGF.EHStack - .pushCleanupWithExtra(EHCleanup, - E->getNumPlacementArgs(), - E->getOperatorDelete(), - NewPtr.getPointer(), - AllocSize, - E->passAlignment(), - AllocAlign); + DirectCleanup *Cleanup = CGF.EHStack.pushCleanupWithExtra( + EHCleanup, E->getNumPlacementArgs(), E->getOperatorDelete(), + NewPtr.emitRawPointer(CGF), AllocSize, E->passAlignment(), AllocAlign); for (unsigned I = 0, N = E->getNumPlacementArgs(); I != N; ++I) { auto &Arg = NewArgs[I + NumNonPlacementArgs]; Cleanup->setPlacementArg(I, Arg.getRValue(CGF), Arg.Ty); @@ -1541,7 +1541,7 @@ static void EnterNewDeleteCleanup(CodeGenFunction &CGF, // Otherwise, we need to save all this stuff. DominatingValue::saved_type SavedNewPtr = - DominatingValue::save(CGF, RValue::get(NewPtr.getPointer())); + DominatingValue::save(CGF, RValue::get(NewPtr, CGF)); DominatingValue::saved_type SavedAllocSize = DominatingValue::save(CGF, RValue::get(AllocSize)); @@ -1618,14 +1618,14 @@ llvm::Value *CodeGenFunction::EmitCXXNewExpr(const CXXNewExpr *E) { // In these cases, discard the computed alignment and use the // formal alignment of the allocated type. if (BaseInfo.getAlignmentSource() != AlignmentSource::Decl) - allocation = allocation.withAlignment(allocAlign); + allocation.setAlignment(allocAlign); // Set up allocatorArgs for the call to operator delete if it's not // the reserved global operator. if (E->getOperatorDelete() && !E->getOperatorDelete()->isReservedGlobalPlacementOperator()) { allocatorArgs.add(RValue::get(allocSize), getContext().getSizeType()); - allocatorArgs.add(RValue::get(allocation.getPointer()), arg->getType()); + allocatorArgs.add(RValue::get(allocation, *this), arg->getType()); } } else { @@ -1713,8 +1713,7 @@ llvm::Value *CodeGenFunction::EmitCXXNewExpr(const CXXNewExpr *E) { llvm::BasicBlock *notNullBB = createBasicBlock("new.notnull"); contBB = createBasicBlock("new.cont"); - llvm::Value *isNull = - Builder.CreateIsNull(allocation.getPointer(), "new.isnull"); + llvm::Value *isNull = Builder.CreateIsNull(allocation, "new.isnull"); Builder.CreateCondBr(isNull, contBB, notNullBB); EmitBlock(notNullBB); } @@ -1760,12 +1759,12 @@ llvm::Value *CodeGenFunction::EmitCXXNewExpr(const CXXNewExpr *E) { SkippedChecks.set(SanitizerKind::Null, nullCheck); EmitTypeCheck(CodeGenFunction::TCK_ConstructorCall, E->getAllocatedTypeSourceInfo()->getTypeLoc().getBeginLoc(), - result.getPointer(), allocType, result.getAlignment(), - SkippedChecks, numElements); + result, allocType, result.getAlignment(), SkippedChecks, + numElements); EmitNewInitializer(*this, E, allocType, elementTy, result, numElements, allocSizeWithoutCookie); - llvm::Value *resultPtr = result.getPointer(); + llvm::Value *resultPtr = result.emitRawPointer(*this); if (E->isArray()) { // NewPtr is a pointer to the base element type. If we're // allocating an array of arrays, we'll need to cast back to the @@ -1909,7 +1908,8 @@ static void EmitDestroyingObjectDelete(CodeGenFunction &CGF, CGF.CGM.getCXXABI().emitVirtualObjectDelete(CGF, DE, Ptr, ElementType, Dtor); else - CGF.EmitDeleteCall(DE->getOperatorDelete(), Ptr.getPointer(), ElementType); + CGF.EmitDeleteCall(DE->getOperatorDelete(), Ptr.emitRawPointer(CGF), + ElementType); } /// Emit the code for deleting a single object. @@ -1925,8 +1925,7 @@ static bool EmitObjectDelete(CodeGenFunction &CGF, // dynamic type, the static type shall be a base class of the dynamic type // of the object to be deleted and the static type shall have a virtual // destructor or the behavior is undefined. - CGF.EmitTypeCheck(CodeGenFunction::TCK_MemberCall, - DE->getExprLoc(), Ptr.getPointer(), + CGF.EmitTypeCheck(CodeGenFunction::TCK_MemberCall, DE->getExprLoc(), Ptr, ElementType); const FunctionDecl *OperatorDelete = DE->getOperatorDelete(); @@ -1975,9 +1974,8 @@ static bool EmitObjectDelete(CodeGenFunction &CGF, // Make sure that we call delete even if the dtor throws. // This doesn't have to a conditional cleanup because we're going // to pop it off in a second. - CGF.EHStack.pushCleanup(NormalAndEHCleanup, - Ptr.getPointer(), - OperatorDelete, ElementType); + CGF.EHStack.pushCleanup( + NormalAndEHCleanup, Ptr.emitRawPointer(CGF), OperatorDelete, ElementType); if (Dtor) CGF.EmitCXXDestructorCall(Dtor, Dtor_Complete, @@ -2064,7 +2062,7 @@ static void EmitArrayDelete(CodeGenFunction &CGF, CharUnits elementAlign = deletedPtr.getAlignment().alignmentOfArrayElement(elementSize); - llvm::Value *arrayBegin = deletedPtr.getPointer(); + llvm::Value *arrayBegin = deletedPtr.emitRawPointer(CGF); llvm::Value *arrayEnd = CGF.Builder.CreateInBoundsGEP( deletedPtr.getElementType(), arrayBegin, numElements, "delete.end"); @@ -2095,7 +2093,7 @@ void CodeGenFunction::EmitCXXDeleteExpr(const CXXDeleteExpr *E) { llvm::BasicBlock *DeleteNotNull = createBasicBlock("delete.notnull"); llvm::BasicBlock *DeleteEnd = createBasicBlock("delete.end"); - llvm::Value *IsNull = Builder.CreateIsNull(Ptr.getPointer(), "isnull"); + llvm::Value *IsNull = Builder.CreateIsNull(Ptr, "isnull"); Builder.CreateCondBr(IsNull, DeleteEnd, DeleteNotNull); EmitBlock(DeleteNotNull); @@ -2130,10 +2128,8 @@ void CodeGenFunction::EmitCXXDeleteExpr(const CXXDeleteExpr *E) { GEP.push_back(Zero); } - Ptr = Address(Builder.CreateInBoundsGEP(Ptr.getElementType(), - Ptr.getPointer(), GEP, "del.first"), - ConvertTypeForMem(DeleteTy), Ptr.getAlignment(), - Ptr.isKnownNonNull()); + Ptr = Builder.CreateInBoundsGEP(Ptr, GEP, ConvertTypeForMem(DeleteTy), + Ptr.getAlignment(), "del.first"); } assert(ConvertTypeForMem(DeleteTy) == Ptr.getElementType()); @@ -2191,7 +2187,7 @@ static llvm::Value *EmitTypeidFromVTable(CodeGenFunction &CGF, const Expr *E, // destruction and the static type of the operand is neither the constructor // or destructor’s class nor one of its bases, the behavior is undefined. CGF.EmitTypeCheck(CodeGenFunction::TCK_DynamicOperation, E->getExprLoc(), - ThisPtr.getPointer(), SrcRecordTy); + ThisPtr, SrcRecordTy); // C++ [expr.typeid]p2: // If the glvalue expression is obtained by applying the unary * operator to @@ -2207,7 +2203,7 @@ static llvm::Value *EmitTypeidFromVTable(CodeGenFunction &CGF, const Expr *E, CGF.createBasicBlock("typeid.bad_typeid"); llvm::BasicBlock *EndBlock = CGF.createBasicBlock("typeid.end"); - llvm::Value *IsNull = CGF.Builder.CreateIsNull(ThisPtr.getPointer()); + llvm::Value *IsNull = CGF.Builder.CreateIsNull(ThisPtr); CGF.Builder.CreateCondBr(IsNull, BadTypeidBlock, EndBlock); CGF.EmitBlock(BadTypeidBlock); @@ -2293,8 +2289,7 @@ llvm::Value *CodeGenFunction::EmitDynamicCast(Address ThisAddr, // construction or destruction and the static type of the operand is not a // pointer to or object of the constructor or destructor’s own class or one // of its bases, the dynamic_cast results in undefined behavior. - EmitTypeCheck(TCK_DynamicOperation, DCE->getExprLoc(), ThisAddr.getPointer(), - SrcRecordTy); + EmitTypeCheck(TCK_DynamicOperation, DCE->getExprLoc(), ThisAddr, SrcRecordTy); if (DCE->isAlwaysNull()) { if (llvm::Value *T = EmitDynamicCastToNull(*this, DestTy)) { @@ -2329,7 +2324,7 @@ llvm::Value *CodeGenFunction::EmitDynamicCast(Address ThisAddr, CastNull = createBasicBlock("dynamic_cast.null"); CastNotNull = createBasicBlock("dynamic_cast.notnull"); - llvm::Value *IsNull = Builder.CreateIsNull(ThisAddr.getPointer()); + llvm::Value *IsNull = Builder.CreateIsNull(ThisAddr); Builder.CreateCondBr(IsNull, CastNull, CastNotNull); EmitBlock(CastNotNull); } diff --git a/clang/lib/CodeGen/CGExprConstant.cpp b/clang/lib/CodeGen/CGExprConstant.cpp index 67a3cdc77042..36d7493d9a6b 100644 --- a/clang/lib/CodeGen/CGExprConstant.cpp +++ b/clang/lib/CodeGen/CGExprConstant.cpp @@ -800,8 +800,8 @@ bool ConstStructBuilder::Build(const APValue &Val, const RecordDecl *RD, // Add a vtable pointer, if we need one and it hasn't already been added. if (Layout.hasOwnVFPtr()) { llvm::Constant *VTableAddressPoint = - CGM.getCXXABI().getVTableAddressPointForConstExpr( - BaseSubobject(CD, Offset), VTableClass); + CGM.getCXXABI().getVTableAddressPoint(BaseSubobject(CD, Offset), + VTableClass); if (!AppendBytes(Offset, VTableAddressPoint)) return false; } diff --git a/clang/lib/CodeGen/CGExprScalar.cpp b/clang/lib/CodeGen/CGExprScalar.cpp index 8536570087ad..83247aa48f86 100644 --- a/clang/lib/CodeGen/CGExprScalar.cpp +++ b/clang/lib/CodeGen/CGExprScalar.cpp @@ -2250,7 +2250,7 @@ Value *ScalarExprEmitter::VisitCastExpr(CastExpr *CE) { // performed and the object is not of the derived type. if (CGF.sanitizePerformTypeCheck()) CGF.EmitTypeCheck(CodeGenFunction::TCK_DowncastPointer, CE->getExprLoc(), - Derived.getPointer(), DestTy->getPointeeType()); + Derived, DestTy->getPointeeType()); if (CGF.SanOpts.has(SanitizerKind::CFIDerivedCast)) CGF.EmitVTablePtrCheckForCast(DestTy->getPointeeType(), Derived, @@ -2258,13 +2258,14 @@ Value *ScalarExprEmitter::VisitCastExpr(CastExpr *CE) { CodeGenFunction::CFITCK_DerivedCast, CE->getBeginLoc()); - return Derived.getPointer(); + return CGF.getAsNaturalPointerTo(Derived, CE->getType()->getPointeeType()); } case CK_UncheckedDerivedToBase: case CK_DerivedToBase: { // The EmitPointerWithAlignment path does this fine; just discard // the alignment. - return CGF.EmitPointerWithAlignment(CE).getPointer(); + return CGF.getAsNaturalPointerTo(CGF.EmitPointerWithAlignment(CE), + CE->getType()->getPointeeType()); } case CK_Dynamic: { @@ -2274,7 +2275,8 @@ Value *ScalarExprEmitter::VisitCastExpr(CastExpr *CE) { } case CK_ArrayToPointerDecay: - return CGF.EmitArrayToPointerDecay(E).getPointer(); + return CGF.getAsNaturalPointerTo(CGF.EmitArrayToPointerDecay(E), + CE->getType()->getPointeeType()); case CK_FunctionToPointerDecay: return EmitLValue(E).getPointer(CGF); @@ -5588,3 +5590,16 @@ CodeGenFunction::EmitCheckedInBoundsGEP(llvm::Type *ElemTy, Value *Ptr, return GEPVal; } + +Address CodeGenFunction::EmitCheckedInBoundsGEP( + Address Addr, ArrayRef IdxList, llvm::Type *elementType, + bool SignedIndices, bool IsSubtraction, SourceLocation Loc, CharUnits Align, + const Twine &Name) { + if (!SanOpts.has(SanitizerKind::PointerOverflow)) + return Builder.CreateInBoundsGEP(Addr, IdxList, elementType, Align, Name); + + return RawAddress( + EmitCheckedInBoundsGEP(Addr.getElementType(), Addr.emitRawPointer(*this), + IdxList, SignedIndices, IsSubtraction, Loc, Name), + elementType, Align); +} diff --git a/clang/lib/CodeGen/CGNonTrivialStruct.cpp b/clang/lib/CodeGen/CGNonTrivialStruct.cpp index 75c1d7fbea84..8fade0fac21e 100644 --- a/clang/lib/CodeGen/CGNonTrivialStruct.cpp +++ b/clang/lib/CodeGen/CGNonTrivialStruct.cpp @@ -366,7 +366,7 @@ template struct GenFuncBase { llvm::Value *SizeInBytes = CGF.Builder.CreateNUWMul(BaseEltSizeVal, NumElts); llvm::Value *DstArrayEnd = CGF.Builder.CreateInBoundsGEP( - CGF.Int8Ty, DstAddr.getPointer(), SizeInBytes); + CGF.Int8Ty, DstAddr.emitRawPointer(CGF), SizeInBytes); llvm::BasicBlock *PreheaderBB = CGF.Builder.GetInsertBlock(); // Create the header block and insert the phi instructions. @@ -376,7 +376,7 @@ template struct GenFuncBase { for (unsigned I = 0; I < N; ++I) { PHIs[I] = CGF.Builder.CreatePHI(CGF.CGM.Int8PtrPtrTy, 2, "addr.cur"); - PHIs[I]->addIncoming(StartAddrs[I].getPointer(), PreheaderBB); + PHIs[I]->addIncoming(StartAddrs[I].emitRawPointer(CGF), PreheaderBB); } // Create the exit and loop body blocks. @@ -410,7 +410,7 @@ template struct GenFuncBase { // Instrs to update the destination and source addresses. // Update phi instructions. NewAddrs[I] = getAddrWithOffset(NewAddrs[I], EltSize); - PHIs[I]->addIncoming(NewAddrs[I].getPointer(), LoopBB); + PHIs[I]->addIncoming(NewAddrs[I].emitRawPointer(CGF), LoopBB); } // Insert an unconditional branch to the header block. @@ -488,7 +488,7 @@ template struct GenFuncBase { for (unsigned I = 0; I < N; ++I) { Alignments[I] = Addrs[I].getAlignment(); - Ptrs[I] = Addrs[I].getPointer(); + Ptrs[I] = Addrs[I].emitRawPointer(CallerCGF); } if (llvm::Function *F = diff --git a/clang/lib/CodeGen/CGObjC.cpp b/clang/lib/CodeGen/CGObjC.cpp index f3a948cf13f9..c7f497a7c845 100644 --- a/clang/lib/CodeGen/CGObjC.cpp +++ b/clang/lib/CodeGen/CGObjC.cpp @@ -94,8 +94,8 @@ CodeGenFunction::EmitObjCBoxedExpr(const ObjCBoxedExpr *E) { // and cast value to correct type Address Temporary = CreateMemTemp(SubExpr->getType()); EmitAnyExprToMem(SubExpr, Temporary, Qualifiers(), /*isInit*/ true); - llvm::Value *BitCast = - Builder.CreateBitCast(Temporary.getPointer(), ConvertType(ArgQT)); + llvm::Value *BitCast = Builder.CreateBitCast( + Temporary.emitRawPointer(*this), ConvertType(ArgQT)); Args.add(RValue::get(BitCast), ArgQT); // Create char array to store type encoding @@ -204,11 +204,11 @@ llvm::Value *CodeGenFunction::EmitObjCCollectionLiteral(const Expr *E, ObjCMethodDecl::param_const_iterator PI = MethodWithObjects->param_begin(); const ParmVarDecl *argDecl = *PI++; QualType ArgQT = argDecl->getType().getUnqualifiedType(); - Args.add(RValue::get(Objects.getPointer()), ArgQT); + Args.add(RValue::get(Objects, *this), ArgQT); if (DLE) { argDecl = *PI++; ArgQT = argDecl->getType().getUnqualifiedType(); - Args.add(RValue::get(Keys.getPointer()), ArgQT); + Args.add(RValue::get(Keys, *this), ArgQT); } argDecl = *PI; ArgQT = argDecl->getType().getUnqualifiedType(); @@ -827,7 +827,7 @@ static void emitStructGetterCall(CodeGenFunction &CGF, ObjCIvarDecl *ivar, // sizeof (Type of Ivar), isAtomic, false); CallArgList args; - llvm::Value *dest = CGF.ReturnValue.getPointer(); + llvm::Value *dest = CGF.ReturnValue.emitRawPointer(CGF); args.add(RValue::get(dest), Context.VoidPtrTy); args.add(RValue::get(src), Context.VoidPtrTy); @@ -1147,8 +1147,8 @@ CodeGenFunction::generateObjCGetterBody(const ObjCImplementationDecl *classImpl, callCStructCopyConstructor(Dst, Src); } else { ObjCIvarDecl *ivar = propImpl->getPropertyIvarDecl(); - emitCPPObjectAtomicGetterCall(*this, ReturnValue.getPointer(), ivar, - AtomicHelperFn); + emitCPPObjectAtomicGetterCall(*this, ReturnValue.emitRawPointer(*this), + ivar, AtomicHelperFn); } return; } @@ -1163,7 +1163,7 @@ CodeGenFunction::generateObjCGetterBody(const ObjCImplementationDecl *classImpl, } else { ObjCIvarDecl *ivar = propImpl->getPropertyIvarDecl(); - emitCPPObjectAtomicGetterCall(*this, ReturnValue.getPointer(), + emitCPPObjectAtomicGetterCall(*this, ReturnValue.emitRawPointer(*this), ivar, AtomicHelperFn); } return; @@ -1287,7 +1287,7 @@ CodeGenFunction::generateObjCGetterBody(const ObjCImplementationDecl *classImpl, case TEK_Scalar: { llvm::Value *value; if (propType->isReferenceType()) { - value = LV.getAddress(*this).getPointer(); + value = LV.getAddress(*this).emitRawPointer(*this); } else { // We want to load and autoreleaseReturnValue ARC __weak ivars. if (LV.getQuals().getObjCLifetime() == Qualifiers::OCL_Weak) { @@ -1821,16 +1821,14 @@ void CodeGenFunction::EmitObjCForCollectionStmt(const ObjCForCollectionStmt &S){ CallArgList Args; // The first argument is a temporary of the enumeration-state type. - Args.add(RValue::get(StatePtr.getPointer()), - getContext().getPointerType(StateTy)); + Args.add(RValue::get(StatePtr, *this), getContext().getPointerType(StateTy)); // The second argument is a temporary array with space for NumItems // pointers. We'll actually be loading elements from the array // pointer written into the control state; this buffer is so that // collections that *aren't* backed by arrays can still queue up // batches of elements. - Args.add(RValue::get(ItemsPtr.getPointer()), - getContext().getPointerType(ItemsTy)); + Args.add(RValue::get(ItemsPtr, *this), getContext().getPointerType(ItemsTy)); // The third argument is the capacity of that temporary array. llvm::Type *NSUIntegerTy = ConvertType(getContext().getNSUIntegerType()); @@ -2198,7 +2196,7 @@ static llvm::Value *emitARCLoadOperation(CodeGenFunction &CGF, Address addr, if (!fn) fn = getARCIntrinsic(IntID, CGF.CGM); - return CGF.EmitNounwindRuntimeCall(fn, addr.getPointer()); + return CGF.EmitNounwindRuntimeCall(fn, addr.emitRawPointer(CGF)); } /// Perform an operation having the following signature: @@ -2216,9 +2214,8 @@ static llvm::Value *emitARCStoreOperation(CodeGenFunction &CGF, Address addr, llvm::Type *origType = value->getType(); llvm::Value *args[] = { - CGF.Builder.CreateBitCast(addr.getPointer(), CGF.Int8PtrPtrTy), - CGF.Builder.CreateBitCast(value, CGF.Int8PtrTy) - }; + CGF.Builder.CreateBitCast(addr.emitRawPointer(CGF), CGF.Int8PtrPtrTy), + CGF.Builder.CreateBitCast(value, CGF.Int8PtrTy)}; llvm::CallInst *result = CGF.EmitNounwindRuntimeCall(fn, args); if (ignored) return nullptr; @@ -2237,9 +2234,8 @@ static void emitARCCopyOperation(CodeGenFunction &CGF, Address dst, Address src, fn = getARCIntrinsic(IntID, CGF.CGM); llvm::Value *args[] = { - CGF.Builder.CreateBitCast(dst.getPointer(), CGF.Int8PtrPtrTy), - CGF.Builder.CreateBitCast(src.getPointer(), CGF.Int8PtrPtrTy) - }; + CGF.Builder.CreateBitCast(dst.emitRawPointer(CGF), CGF.Int8PtrPtrTy), + CGF.Builder.CreateBitCast(src.emitRawPointer(CGF), CGF.Int8PtrPtrTy)}; CGF.EmitNounwindRuntimeCall(fn, args); } @@ -2490,9 +2486,8 @@ llvm::Value *CodeGenFunction::EmitARCStoreStrongCall(Address addr, fn = getARCIntrinsic(llvm::Intrinsic::objc_storeStrong, CGM); llvm::Value *args[] = { - Builder.CreateBitCast(addr.getPointer(), Int8PtrPtrTy), - Builder.CreateBitCast(value, Int8PtrTy) - }; + Builder.CreateBitCast(addr.emitRawPointer(*this), Int8PtrPtrTy), + Builder.CreateBitCast(value, Int8PtrTy)}; EmitNounwindRuntimeCall(fn, args); if (ignored) return nullptr; @@ -2643,7 +2638,7 @@ void CodeGenFunction::EmitARCDestroyWeak(Address addr) { if (!fn) fn = getARCIntrinsic(llvm::Intrinsic::objc_destroyWeak, CGM); - EmitNounwindRuntimeCall(fn, addr.getPointer()); + EmitNounwindRuntimeCall(fn, addr.emitRawPointer(*this)); } /// void \@objc_moveWeak(i8** %dest, i8** %src) diff --git a/clang/lib/CodeGen/CGObjCGNU.cpp b/clang/lib/CodeGen/CGObjCGNU.cpp index a36b0cdddaf0..4e7f777ba1d9 100644 --- a/clang/lib/CodeGen/CGObjCGNU.cpp +++ b/clang/lib/CodeGen/CGObjCGNU.cpp @@ -706,7 +706,8 @@ protected: llvm::Value *cmd, MessageSendInfo &MSI) override { CGBuilderTy &Builder = CGF.Builder; llvm::Value *lookupArgs[] = { - EnforceType(Builder, ObjCSuper.getPointer(), PtrToObjCSuperTy), cmd}; + EnforceType(Builder, ObjCSuper.emitRawPointer(CGF), PtrToObjCSuperTy), + cmd}; return CGF.EmitNounwindRuntimeCall(MsgLookupSuperFn, lookupArgs); } @@ -761,8 +762,8 @@ class CGObjCGNUstep : public CGObjCGNU { llvm::FunctionCallee LookupFn = SlotLookupFn; // Store the receiver on the stack so that we can reload it later - Address ReceiverPtr = - CGF.CreateTempAlloca(Receiver->getType(), CGF.getPointerAlign()); + RawAddress ReceiverPtr = + CGF.CreateTempAlloca(Receiver->getType(), CGF.getPointerAlign()); Builder.CreateStore(Receiver, ReceiverPtr); llvm::Value *self; @@ -778,9 +779,9 @@ class CGObjCGNUstep : public CGObjCGNU { LookupFn2->addParamAttr(0, llvm::Attribute::NoCapture); llvm::Value *args[] = { - EnforceType(Builder, ReceiverPtr.getPointer(), PtrToIdTy), - EnforceType(Builder, cmd, SelectorTy), - EnforceType(Builder, self, IdTy) }; + EnforceType(Builder, ReceiverPtr.getPointer(), PtrToIdTy), + EnforceType(Builder, cmd, SelectorTy), + EnforceType(Builder, self, IdTy)}; llvm::CallBase *slot = CGF.EmitRuntimeCallOrInvoke(LookupFn, args); slot->setOnlyReadsMemory(); slot->setMetadata(msgSendMDKind, node); @@ -800,7 +801,7 @@ class CGObjCGNUstep : public CGObjCGNU { llvm::Value *cmd, MessageSendInfo &MSI) override { CGBuilderTy &Builder = CGF.Builder; - llvm::Value *lookupArgs[] = {ObjCSuper.getPointer(), cmd}; + llvm::Value *lookupArgs[] = {ObjCSuper.emitRawPointer(CGF), cmd}; llvm::CallInst *slot = CGF.EmitNounwindRuntimeCall(SlotLookupSuperFn, lookupArgs); @@ -1221,10 +1222,10 @@ class CGObjCGNUstep2 : public CGObjCGNUstep { llvm::Value *cmd, MessageSendInfo &MSI) override { // Don't access the slot unless we're trying to cache the result. CGBuilderTy &Builder = CGF.Builder; - llvm::Value *lookupArgs[] = {CGObjCGNU::EnforceType(Builder, - ObjCSuper.getPointer(), - PtrToObjCSuperTy), - cmd}; + llvm::Value *lookupArgs[] = { + CGObjCGNU::EnforceType(Builder, ObjCSuper.emitRawPointer(CGF), + PtrToObjCSuperTy), + cmd}; return CGF.EmitNounwindRuntimeCall(MsgLookupSuperFn, lookupArgs); } @@ -2186,7 +2187,8 @@ protected: llvm::Value *cmd, MessageSendInfo &MSI) override { CGBuilderTy &Builder = CGF.Builder; llvm::Value *lookupArgs[] = { - EnforceType(Builder, ObjCSuper.getPointer(), PtrToObjCSuperTy), cmd, + EnforceType(Builder, ObjCSuper.emitRawPointer(CGF), PtrToObjCSuperTy), + cmd, }; if (CGM.ReturnTypeUsesSRet(MSI.CallInfo)) @@ -4201,15 +4203,15 @@ void CGObjCGNU::EmitThrowStmt(CodeGenFunction &CGF, llvm::Value * CGObjCGNU::EmitObjCWeakRead(CodeGenFunction &CGF, Address AddrWeakObj) { CGBuilderTy &B = CGF.Builder; - return B.CreateCall(WeakReadFn, - EnforceType(B, AddrWeakObj.getPointer(), PtrToIdTy)); + return B.CreateCall( + WeakReadFn, EnforceType(B, AddrWeakObj.emitRawPointer(CGF), PtrToIdTy)); } void CGObjCGNU::EmitObjCWeakAssign(CodeGenFunction &CGF, llvm::Value *src, Address dst) { CGBuilderTy &B = CGF.Builder; src = EnforceType(B, src, IdTy); - llvm::Value *dstVal = EnforceType(B, dst.getPointer(), PtrToIdTy); + llvm::Value *dstVal = EnforceType(B, dst.emitRawPointer(CGF), PtrToIdTy); B.CreateCall(WeakAssignFn, {src, dstVal}); } @@ -4218,7 +4220,7 @@ void CGObjCGNU::EmitObjCGlobalAssign(CodeGenFunction &CGF, bool threadlocal) { CGBuilderTy &B = CGF.Builder; src = EnforceType(B, src, IdTy); - llvm::Value *dstVal = EnforceType(B, dst.getPointer(), PtrToIdTy); + llvm::Value *dstVal = EnforceType(B, dst.emitRawPointer(CGF), PtrToIdTy); // FIXME. Add threadloca assign API assert(!threadlocal && "EmitObjCGlobalAssign - Threal Local API NYI"); B.CreateCall(GlobalAssignFn, {src, dstVal}); @@ -4229,7 +4231,7 @@ void CGObjCGNU::EmitObjCIvarAssign(CodeGenFunction &CGF, llvm::Value *ivarOffset) { CGBuilderTy &B = CGF.Builder; src = EnforceType(B, src, IdTy); - llvm::Value *dstVal = EnforceType(B, dst.getPointer(), IdTy); + llvm::Value *dstVal = EnforceType(B, dst.emitRawPointer(CGF), IdTy); B.CreateCall(IvarAssignFn, {src, dstVal, ivarOffset}); } @@ -4237,7 +4239,7 @@ void CGObjCGNU::EmitObjCStrongCastAssign(CodeGenFunction &CGF, llvm::Value *src, Address dst) { CGBuilderTy &B = CGF.Builder; src = EnforceType(B, src, IdTy); - llvm::Value *dstVal = EnforceType(B, dst.getPointer(), PtrToIdTy); + llvm::Value *dstVal = EnforceType(B, dst.emitRawPointer(CGF), PtrToIdTy); B.CreateCall(StrongCastAssignFn, {src, dstVal}); } @@ -4246,8 +4248,8 @@ void CGObjCGNU::EmitGCMemmoveCollectable(CodeGenFunction &CGF, Address SrcPtr, llvm::Value *Size) { CGBuilderTy &B = CGF.Builder; - llvm::Value *DestPtrVal = EnforceType(B, DestPtr.getPointer(), PtrTy); - llvm::Value *SrcPtrVal = EnforceType(B, SrcPtr.getPointer(), PtrTy); + llvm::Value *DestPtrVal = EnforceType(B, DestPtr.emitRawPointer(CGF), PtrTy); + llvm::Value *SrcPtrVal = EnforceType(B, SrcPtr.emitRawPointer(CGF), PtrTy); B.CreateCall(MemMoveFn, {DestPtrVal, SrcPtrVal, Size}); } diff --git a/clang/lib/CodeGen/CGObjCMac.cpp b/clang/lib/CodeGen/CGObjCMac.cpp index ed8d7b9a065d..8a599c10e1ca 100644 --- a/clang/lib/CodeGen/CGObjCMac.cpp +++ b/clang/lib/CodeGen/CGObjCMac.cpp @@ -1310,7 +1310,7 @@ private: /// EmitSelector - Return a Value*, of type ObjCTypes.SelectorPtrTy, /// for the given selector. llvm::Value *EmitSelector(CodeGenFunction &CGF, Selector Sel); - Address EmitSelectorAddr(Selector Sel); + ConstantAddress EmitSelectorAddr(Selector Sel); public: CGObjCMac(CodeGen::CodeGenModule &cgm); @@ -1538,7 +1538,7 @@ private: /// EmitSelector - Return a Value*, of type ObjCTypes.SelectorPtrTy, /// for the given selector. llvm::Value *EmitSelector(CodeGenFunction &CGF, Selector Sel); - Address EmitSelectorAddr(Selector Sel); + ConstantAddress EmitSelectorAddr(Selector Sel); /// GetInterfaceEHType - Get the cached ehtype for the given Objective-C /// interface. The return value has type EHTypePtrTy. @@ -2064,9 +2064,8 @@ CGObjCMac::GenerateMessageSendSuper(CodeGen::CodeGenFunction &CGF, const ObjCMethodDecl *Method) { // Create and init a super structure; this is a (receiver, class) // pair we will pass to objc_msgSendSuper. - Address ObjCSuper = - CGF.CreateTempAlloca(ObjCTypes.SuperTy, CGF.getPointerAlign(), - "objc_super"); + RawAddress ObjCSuper = CGF.CreateTempAlloca( + ObjCTypes.SuperTy, CGF.getPointerAlign(), "objc_super"); llvm::Value *ReceiverAsObject = CGF.Builder.CreateBitCast(Receiver, ObjCTypes.ObjectPtrTy); CGF.Builder.CreateStore(ReceiverAsObject, @@ -4259,7 +4258,7 @@ namespace { CGF.EmitBlock(FinallyCallExit); CGF.EmitNounwindRuntimeCall(ObjCTypes.getExceptionTryExitFn(), - ExceptionData.getPointer()); + ExceptionData.emitRawPointer(CGF)); CGF.EmitBlock(FinallyNoCallExit); @@ -4425,7 +4424,9 @@ void FragileHazards::emitHazardsInNewBlocks() { } static void addIfPresent(llvm::DenseSet &S, Address V) { - if (V.isValid()) S.insert(V.getPointer()); + if (V.isValid()) + if (llvm::Value *Ptr = V.getBasePointer()) + S.insert(Ptr); } void FragileHazards::collectLocals() { @@ -4628,13 +4629,13 @@ void CGObjCMac::EmitTryOrSynchronizedStmt(CodeGen::CodeGenFunction &CGF, // - Call objc_exception_try_enter to push ExceptionData on top of // the EH stack. CGF.EmitNounwindRuntimeCall(ObjCTypes.getExceptionTryEnterFn(), - ExceptionData.getPointer()); + ExceptionData.emitRawPointer(CGF)); // - Call setjmp on the exception data buffer. llvm::Constant *Zero = llvm::ConstantInt::get(CGF.Builder.getInt32Ty(), 0); llvm::Value *GEPIndexes[] = { Zero, Zero, Zero }; llvm::Value *SetJmpBuffer = CGF.Builder.CreateGEP( - ObjCTypes.ExceptionDataTy, ExceptionData.getPointer(), GEPIndexes, + ObjCTypes.ExceptionDataTy, ExceptionData.emitRawPointer(CGF), GEPIndexes, "setjmp_buffer"); llvm::CallInst *SetJmpResult = CGF.EmitNounwindRuntimeCall( ObjCTypes.getSetJmpFn(), SetJmpBuffer, "setjmp_result"); @@ -4673,9 +4674,9 @@ void CGObjCMac::EmitTryOrSynchronizedStmt(CodeGen::CodeGenFunction &CGF, } else { // Retrieve the exception object. We may emit multiple blocks but // nothing can cross this so the value is already in SSA form. - llvm::CallInst *Caught = - CGF.EmitNounwindRuntimeCall(ObjCTypes.getExceptionExtractFn(), - ExceptionData.getPointer(), "caught"); + llvm::CallInst *Caught = CGF.EmitNounwindRuntimeCall( + ObjCTypes.getExceptionExtractFn(), ExceptionData.emitRawPointer(CGF), + "caught"); // Push the exception to rethrow onto the EH value stack for the // benefit of any @throws in the handlers. @@ -4698,7 +4699,7 @@ void CGObjCMac::EmitTryOrSynchronizedStmt(CodeGen::CodeGenFunction &CGF, // Enter a new exception try block (in case a @catch block // throws an exception). CGF.EmitNounwindRuntimeCall(ObjCTypes.getExceptionTryEnterFn(), - ExceptionData.getPointer()); + ExceptionData.emitRawPointer(CGF)); llvm::CallInst *SetJmpResult = CGF.EmitNounwindRuntimeCall(ObjCTypes.getSetJmpFn(), @@ -4829,9 +4830,9 @@ void CGObjCMac::EmitTryOrSynchronizedStmt(CodeGen::CodeGenFunction &CGF, // Extract the new exception and save it to the // propagating-exception slot. assert(PropagatingExnVar.isValid()); - llvm::CallInst *NewCaught = - CGF.EmitNounwindRuntimeCall(ObjCTypes.getExceptionExtractFn(), - ExceptionData.getPointer(), "caught"); + llvm::CallInst *NewCaught = CGF.EmitNounwindRuntimeCall( + ObjCTypes.getExceptionExtractFn(), ExceptionData.emitRawPointer(CGF), + "caught"); CGF.Builder.CreateStore(NewCaught, PropagatingExnVar); // Don't pop the catch handler; the throw already did. @@ -4861,9 +4862,8 @@ void CGObjCMac::EmitTryOrSynchronizedStmt(CodeGen::CodeGenFunction &CGF, // Otherwise, just look in the buffer for the exception to throw. } else { - llvm::CallInst *Caught = - CGF.EmitNounwindRuntimeCall(ObjCTypes.getExceptionExtractFn(), - ExceptionData.getPointer()); + llvm::CallInst *Caught = CGF.EmitNounwindRuntimeCall( + ObjCTypes.getExceptionExtractFn(), ExceptionData.emitRawPointer(CGF)); PropagatingExn = Caught; } @@ -4906,7 +4906,7 @@ llvm::Value * CGObjCMac::EmitObjCWeakRead(CodeGen::CodeGenFunction &CGF, Address AddrWeakObj) { llvm::Type* DestTy = AddrWeakObj.getElementType(); llvm::Value *AddrWeakObjVal = CGF.Builder.CreateBitCast( - AddrWeakObj.getPointer(), ObjCTypes.PtrObjectPtrTy); + AddrWeakObj.emitRawPointer(CGF), ObjCTypes.PtrObjectPtrTy); llvm::Value *read_weak = CGF.EmitNounwindRuntimeCall(ObjCTypes.getGcReadWeakFn(), AddrWeakObjVal, "weakread"); @@ -4928,8 +4928,8 @@ void CGObjCMac::EmitObjCWeakAssign(CodeGen::CodeGenFunction &CGF, src = CGF.Builder.CreateIntToPtr(src, ObjCTypes.Int8PtrTy); } src = CGF.Builder.CreateBitCast(src, ObjCTypes.ObjectPtrTy); - llvm::Value *dstVal = - CGF.Builder.CreateBitCast(dst.getPointer(), ObjCTypes.PtrObjectPtrTy); + llvm::Value *dstVal = CGF.Builder.CreateBitCast(dst.emitRawPointer(CGF), + ObjCTypes.PtrObjectPtrTy); llvm::Value *args[] = { src, dstVal }; CGF.EmitNounwindRuntimeCall(ObjCTypes.getGcAssignWeakFn(), args, "weakassign"); @@ -4950,8 +4950,8 @@ void CGObjCMac::EmitObjCGlobalAssign(CodeGen::CodeGenFunction &CGF, src = CGF.Builder.CreateIntToPtr(src, ObjCTypes.Int8PtrTy); } src = CGF.Builder.CreateBitCast(src, ObjCTypes.ObjectPtrTy); - llvm::Value *dstVal = - CGF.Builder.CreateBitCast(dst.getPointer(), ObjCTypes.PtrObjectPtrTy); + llvm::Value *dstVal = CGF.Builder.CreateBitCast(dst.emitRawPointer(CGF), + ObjCTypes.PtrObjectPtrTy); llvm::Value *args[] = {src, dstVal}; if (!threadlocal) CGF.EmitNounwindRuntimeCall(ObjCTypes.getGcAssignGlobalFn(), @@ -4977,8 +4977,8 @@ void CGObjCMac::EmitObjCIvarAssign(CodeGen::CodeGenFunction &CGF, src = CGF.Builder.CreateIntToPtr(src, ObjCTypes.Int8PtrTy); } src = CGF.Builder.CreateBitCast(src, ObjCTypes.ObjectPtrTy); - llvm::Value *dstVal = - CGF.Builder.CreateBitCast(dst.getPointer(), ObjCTypes.PtrObjectPtrTy); + llvm::Value *dstVal = CGF.Builder.CreateBitCast(dst.emitRawPointer(CGF), + ObjCTypes.PtrObjectPtrTy); llvm::Value *args[] = {src, dstVal, ivarOffset}; CGF.EmitNounwindRuntimeCall(ObjCTypes.getGcAssignIvarFn(), args); } @@ -4997,8 +4997,8 @@ void CGObjCMac::EmitObjCStrongCastAssign(CodeGen::CodeGenFunction &CGF, src = CGF.Builder.CreateIntToPtr(src, ObjCTypes.Int8PtrTy); } src = CGF.Builder.CreateBitCast(src, ObjCTypes.ObjectPtrTy); - llvm::Value *dstVal = - CGF.Builder.CreateBitCast(dst.getPointer(), ObjCTypes.PtrObjectPtrTy); + llvm::Value *dstVal = CGF.Builder.CreateBitCast(dst.emitRawPointer(CGF), + ObjCTypes.PtrObjectPtrTy); llvm::Value *args[] = {src, dstVal}; CGF.EmitNounwindRuntimeCall(ObjCTypes.getGcAssignStrongCastFn(), args, "strongassign"); @@ -5007,7 +5007,8 @@ void CGObjCMac::EmitObjCStrongCastAssign(CodeGen::CodeGenFunction &CGF, void CGObjCMac::EmitGCMemmoveCollectable(CodeGen::CodeGenFunction &CGF, Address DestPtr, Address SrcPtr, llvm::Value *size) { - llvm::Value *args[] = { DestPtr.getPointer(), SrcPtr.getPointer(), size }; + llvm::Value *args[] = {DestPtr.emitRawPointer(CGF), + SrcPtr.emitRawPointer(CGF), size}; CGF.EmitNounwindRuntimeCall(ObjCTypes.GcMemmoveCollectableFn(), args); } @@ -5243,7 +5244,7 @@ llvm::Value *CGObjCMac::EmitSelector(CodeGenFunction &CGF, Selector Sel) { return CGF.Builder.CreateLoad(EmitSelectorAddr(Sel)); } -Address CGObjCMac::EmitSelectorAddr(Selector Sel) { +ConstantAddress CGObjCMac::EmitSelectorAddr(Selector Sel) { CharUnits Align = CGM.getPointerAlign(); llvm::GlobalVariable *&Entry = SelectorReferences[Sel]; @@ -5254,7 +5255,7 @@ Address CGObjCMac::EmitSelectorAddr(Selector Sel) { Entry->setExternallyInitialized(true); } - return Address(Entry, ObjCTypes.SelectorPtrTy, Align); + return ConstantAddress(Entry, ObjCTypes.SelectorPtrTy, Align); } llvm::Constant *CGObjCCommonMac::GetClassName(StringRef RuntimeName) { @@ -7323,7 +7324,7 @@ CGObjCNonFragileABIMac::EmitVTableMessageSend(CodeGenFunction &CGF, ObjCTypes.MessageRefTy, CGF.getPointerAlign()); // Update the message ref argument. - args[1].setRValue(RValue::get(mref.getPointer())); + args[1].setRValue(RValue::get(mref, CGF)); // Load the function to call from the message ref table. Address calleeAddr = CGF.Builder.CreateStructGEP(mref, 0); @@ -7552,9 +7553,8 @@ CGObjCNonFragileABIMac::GenerateMessageSendSuper(CodeGen::CodeGenFunction &CGF, // ... // Create and init a super structure; this is a (receiver, class) // pair we will pass to objc_msgSendSuper. - Address ObjCSuper = - CGF.CreateTempAlloca(ObjCTypes.SuperTy, CGF.getPointerAlign(), - "objc_super"); + RawAddress ObjCSuper = CGF.CreateTempAlloca( + ObjCTypes.SuperTy, CGF.getPointerAlign(), "objc_super"); llvm::Value *ReceiverAsObject = CGF.Builder.CreateBitCast(Receiver, ObjCTypes.ObjectPtrTy); @@ -7594,7 +7594,7 @@ llvm::Value *CGObjCNonFragileABIMac::EmitSelector(CodeGenFunction &CGF, return LI; } -Address CGObjCNonFragileABIMac::EmitSelectorAddr(Selector Sel) { +ConstantAddress CGObjCNonFragileABIMac::EmitSelectorAddr(Selector Sel) { llvm::GlobalVariable *&Entry = SelectorReferences[Sel]; CharUnits Align = CGM.getPointerAlign(); if (!Entry) { @@ -7610,7 +7610,7 @@ Address CGObjCNonFragileABIMac::EmitSelectorAddr(Selector Sel) { CGM.addCompilerUsedGlobal(Entry); } - return Address(Entry, ObjCTypes.SelectorPtrTy, Align); + return ConstantAddress(Entry, ObjCTypes.SelectorPtrTy, Align); } /// EmitObjCIvarAssign - Code gen for assigning to a __strong object. @@ -7629,8 +7629,8 @@ void CGObjCNonFragileABIMac::EmitObjCIvarAssign(CodeGen::CodeGenFunction &CGF, src = CGF.Builder.CreateIntToPtr(src, ObjCTypes.Int8PtrTy); } src = CGF.Builder.CreateBitCast(src, ObjCTypes.ObjectPtrTy); - llvm::Value *dstVal = - CGF.Builder.CreateBitCast(dst.getPointer(), ObjCTypes.PtrObjectPtrTy); + llvm::Value *dstVal = CGF.Builder.CreateBitCast(dst.emitRawPointer(CGF), + ObjCTypes.PtrObjectPtrTy); llvm::Value *args[] = {src, dstVal, ivarOffset}; CGF.EmitNounwindRuntimeCall(ObjCTypes.getGcAssignIvarFn(), args); } @@ -7650,8 +7650,8 @@ void CGObjCNonFragileABIMac::EmitObjCStrongCastAssign( src = CGF.Builder.CreateIntToPtr(src, ObjCTypes.Int8PtrTy); } src = CGF.Builder.CreateBitCast(src, ObjCTypes.ObjectPtrTy); - llvm::Value *dstVal = - CGF.Builder.CreateBitCast(dst.getPointer(), ObjCTypes.PtrObjectPtrTy); + llvm::Value *dstVal = CGF.Builder.CreateBitCast(dst.emitRawPointer(CGF), + ObjCTypes.PtrObjectPtrTy); llvm::Value *args[] = {src, dstVal}; CGF.EmitNounwindRuntimeCall(ObjCTypes.getGcAssignStrongCastFn(), args, "weakassign"); @@ -7660,7 +7660,8 @@ void CGObjCNonFragileABIMac::EmitObjCStrongCastAssign( void CGObjCNonFragileABIMac::EmitGCMemmoveCollectable( CodeGen::CodeGenFunction &CGF, Address DestPtr, Address SrcPtr, llvm::Value *Size) { - llvm::Value *args[] = { DestPtr.getPointer(), SrcPtr.getPointer(), Size }; + llvm::Value *args[] = {DestPtr.emitRawPointer(CGF), + SrcPtr.emitRawPointer(CGF), Size}; CGF.EmitNounwindRuntimeCall(ObjCTypes.GcMemmoveCollectableFn(), args); } @@ -7672,7 +7673,7 @@ llvm::Value * CGObjCNonFragileABIMac::EmitObjCWeakRead( Address AddrWeakObj) { llvm::Type *DestTy = AddrWeakObj.getElementType(); llvm::Value *AddrWeakObjVal = CGF.Builder.CreateBitCast( - AddrWeakObj.getPointer(), ObjCTypes.PtrObjectPtrTy); + AddrWeakObj.emitRawPointer(CGF), ObjCTypes.PtrObjectPtrTy); llvm::Value *read_weak = CGF.EmitNounwindRuntimeCall(ObjCTypes.getGcReadWeakFn(), AddrWeakObjVal, "weakread"); @@ -7694,8 +7695,8 @@ void CGObjCNonFragileABIMac::EmitObjCWeakAssign(CodeGen::CodeGenFunction &CGF, src = CGF.Builder.CreateIntToPtr(src, ObjCTypes.Int8PtrTy); } src = CGF.Builder.CreateBitCast(src, ObjCTypes.ObjectPtrTy); - llvm::Value *dstVal = - CGF.Builder.CreateBitCast(dst.getPointer(), ObjCTypes.PtrObjectPtrTy); + llvm::Value *dstVal = CGF.Builder.CreateBitCast(dst.emitRawPointer(CGF), + ObjCTypes.PtrObjectPtrTy); llvm::Value *args[] = {src, dstVal}; CGF.EmitNounwindRuntimeCall(ObjCTypes.getGcAssignWeakFn(), args, "weakassign"); @@ -7716,8 +7717,8 @@ void CGObjCNonFragileABIMac::EmitObjCGlobalAssign(CodeGen::CodeGenFunction &CGF, src = CGF.Builder.CreateIntToPtr(src, ObjCTypes.Int8PtrTy); } src = CGF.Builder.CreateBitCast(src, ObjCTypes.ObjectPtrTy); - llvm::Value *dstVal = - CGF.Builder.CreateBitCast(dst.getPointer(), ObjCTypes.PtrObjectPtrTy); + llvm::Value *dstVal = CGF.Builder.CreateBitCast(dst.emitRawPointer(CGF), + ObjCTypes.PtrObjectPtrTy); llvm::Value *args[] = {src, dstVal}; if (!threadlocal) CGF.EmitNounwindRuntimeCall(ObjCTypes.getGcAssignGlobalFn(), diff --git a/clang/lib/CodeGen/CGObjCRuntime.cpp b/clang/lib/CodeGen/CGObjCRuntime.cpp index 424564f97599..01d0f35da196 100644 --- a/clang/lib/CodeGen/CGObjCRuntime.cpp +++ b/clang/lib/CodeGen/CGObjCRuntime.cpp @@ -67,7 +67,7 @@ LValue CGObjCRuntime::EmitValueForIvarAtOffset(CodeGen::CodeGenFunction &CGF, V = CGF.Builder.CreateInBoundsGEP(CGF.Int8Ty, V, Offset, "add.ptr"); if (!Ivar->isBitField()) { - LValue LV = CGF.MakeNaturalAlignAddrLValue(V, IvarTy); + LValue LV = CGF.MakeNaturalAlignRawAddrLValue(V, IvarTy); return LV; } @@ -233,7 +233,7 @@ void CGObjCRuntime::EmitTryCatchStmt(CodeGenFunction &CGF, llvm::Instruction *CPICandidate = Handler.Block->getFirstNonPHI(); if (auto *CPI = dyn_cast_or_null(CPICandidate)) { CGF.CurrentFuncletPad = CPI; - CPI->setOperand(2, CGF.getExceptionSlot().getPointer()); + CPI->setOperand(2, CGF.getExceptionSlot().emitRawPointer(CGF)); CGF.EHStack.pushCleanup(NormalCleanup, CPI); } } @@ -405,7 +405,7 @@ bool CGObjCRuntime::canMessageReceiverBeNull(CodeGenFunction &CGF, auto self = curMethod->getSelfDecl(); if (self->getType().isConstQualified()) { if (auto LI = dyn_cast(receiver->stripPointerCasts())) { - llvm::Value *selfAddr = CGF.GetAddrOfLocalVar(self).getPointer(); + llvm::Value *selfAddr = CGF.GetAddrOfLocalVar(self).emitRawPointer(CGF); if (selfAddr == LI->getPointerOperand()) { return false; } diff --git a/clang/lib/CodeGen/CGOpenMPRuntime.cpp b/clang/lib/CodeGen/CGOpenMPRuntime.cpp index 00e395c2a207..bc363313dec6 100644 --- a/clang/lib/CodeGen/CGOpenMPRuntime.cpp +++ b/clang/lib/CodeGen/CGOpenMPRuntime.cpp @@ -622,7 +622,7 @@ static void emitInitWithReductionInitializer(CodeGenFunction &CGF, auto *GV = new llvm::GlobalVariable( CGF.CGM.getModule(), Init->getType(), /*isConstant=*/true, llvm::GlobalValue::PrivateLinkage, Init, Name); - LValue LV = CGF.MakeNaturalAlignAddrLValue(GV, Ty); + LValue LV = CGF.MakeNaturalAlignRawAddrLValue(GV, Ty); RValue InitRVal; switch (CGF.getEvaluationKind(Ty)) { case TEK_Scalar: @@ -668,8 +668,8 @@ static void EmitOMPAggregateInit(CodeGenFunction &CGF, Address DestAddr, llvm::Value *SrcBegin = nullptr; if (DRD) - SrcBegin = SrcAddr.getPointer(); - llvm::Value *DestBegin = DestAddr.getPointer(); + SrcBegin = SrcAddr.emitRawPointer(CGF); + llvm::Value *DestBegin = DestAddr.emitRawPointer(CGF); // Cast from pointer to array type to pointer to single element. llvm::Value *DestEnd = CGF.Builder.CreateGEP(DestAddr.getElementType(), DestBegin, NumElements); @@ -912,7 +912,7 @@ static LValue loadToBegin(CodeGenFunction &CGF, QualType BaseTy, QualType ElTy, static Address castToBase(CodeGenFunction &CGF, QualType BaseTy, QualType ElTy, Address OriginalBaseAddress, llvm::Value *Addr) { - Address Tmp = Address::invalid(); + RawAddress Tmp = RawAddress::invalid(); Address TopTmp = Address::invalid(); Address MostTopTmp = Address::invalid(); BaseTy = BaseTy.getNonReferenceType(); @@ -971,10 +971,10 @@ Address ReductionCodeGen::adjustPrivateAddress(CodeGenFunction &CGF, unsigned N, Address SharedAddr = SharedAddresses[N].first.getAddress(CGF); llvm::Value *Adjustment = CGF.Builder.CreatePtrDiff( SharedAddr.getElementType(), BaseLValue.getPointer(CGF), - SharedAddr.getPointer()); + SharedAddr.emitRawPointer(CGF)); llvm::Value *PrivatePointer = CGF.Builder.CreatePointerBitCastOrAddrSpaceCast( - PrivateAddr.getPointer(), SharedAddr.getType()); + PrivateAddr.emitRawPointer(CGF), SharedAddr.getType()); llvm::Value *Ptr = CGF.Builder.CreateGEP( SharedAddr.getElementType(), PrivatePointer, Adjustment); return castToBase(CGF, OrigVD->getType(), @@ -1557,7 +1557,7 @@ static llvm::TargetRegionEntryInfo getEntryInfoFromPresumedLoc( return OMPBuilder.getTargetEntryUniqueInfo(FileInfoCallBack, ParentName); } -Address CGOpenMPRuntime::getAddrOfDeclareTargetVar(const VarDecl *VD) { +ConstantAddress CGOpenMPRuntime::getAddrOfDeclareTargetVar(const VarDecl *VD) { auto AddrOfGlobal = [&VD, this]() { return CGM.GetAddrOfGlobal(VD); }; auto LinkageForVariable = [&VD, this]() { @@ -1579,8 +1579,8 @@ Address CGOpenMPRuntime::getAddrOfDeclareTargetVar(const VarDecl *VD) { LinkageForVariable); if (!addr) - return Address::invalid(); - return Address(addr, LlvmPtrTy, CGM.getContext().getDeclAlign(VD)); + return ConstantAddress::invalid(); + return ConstantAddress(addr, LlvmPtrTy, CGM.getContext().getDeclAlign(VD)); } llvm::Constant * @@ -1604,7 +1604,7 @@ Address CGOpenMPRuntime::getAddrOfThreadPrivate(CodeGenFunction &CGF, llvm::Type *VarTy = VDAddr.getElementType(); llvm::Value *Args[] = { emitUpdateLocation(CGF, Loc), getThreadID(CGF, Loc), - CGF.Builder.CreatePointerCast(VDAddr.getPointer(), CGM.Int8PtrTy), + CGF.Builder.CreatePointerCast(VDAddr.emitRawPointer(CGF), CGM.Int8PtrTy), CGM.getSize(CGM.GetTargetTypeStoreSize(VarTy)), getOrCreateThreadPrivateCache(VD)}; return Address( @@ -1627,7 +1627,8 @@ void CGOpenMPRuntime::emitThreadPrivateVarInit( // Call __kmpc_threadprivate_register(&loc, &var, ctor, cctor/*NULL*/, dtor) // to register constructor/destructor for variable. llvm::Value *Args[] = { - OMPLoc, CGF.Builder.CreatePointerCast(VDAddr.getPointer(), CGM.VoidPtrTy), + OMPLoc, + CGF.Builder.CreatePointerCast(VDAddr.emitRawPointer(CGF), CGM.VoidPtrTy), Ctor, CopyCtor, Dtor}; CGF.EmitRuntimeCall( OMPBuilder.getOrCreateRuntimeFunction( @@ -1900,13 +1901,13 @@ void CGOpenMPRuntime::emitParallelCall(CodeGenFunction &CGF, SourceLocation Loc, // OutlinedFn(>id, &zero_bound, CapturedStruct); Address ThreadIDAddr = RT.emitThreadIDAddress(CGF, Loc); - Address ZeroAddrBound = + RawAddress ZeroAddrBound = CGF.CreateDefaultAlignTempAlloca(CGF.Int32Ty, /*Name=*/".bound.zero.addr"); CGF.Builder.CreateStore(CGF.Builder.getInt32(/*C*/ 0), ZeroAddrBound); llvm::SmallVector OutlinedFnArgs; // ThreadId for serialized parallels is 0. - OutlinedFnArgs.push_back(ThreadIDAddr.getPointer()); + OutlinedFnArgs.push_back(ThreadIDAddr.emitRawPointer(CGF)); OutlinedFnArgs.push_back(ZeroAddrBound.getPointer()); OutlinedFnArgs.append(CapturedVars.begin(), CapturedVars.end()); @@ -2272,7 +2273,7 @@ void CGOpenMPRuntime::emitSingleRegion(CodeGenFunction &CGF, emitUpdateLocation(CGF, Loc), // ident_t * getThreadID(CGF, Loc), // i32 BufSize, // size_t - CL.getPointer(), // void * + CL.emitRawPointer(CGF), // void * CpyFn, // void (*) (void *, void *) DidItVal // i32 did_it }; @@ -2591,10 +2592,10 @@ static void emitForStaticInitCall( ThreadId, CGF.Builder.getInt32(addMonoNonMonoModifier(CGF.CGM, Schedule, M1, M2)), // Schedule type - Values.IL.getPointer(), // &isLastIter - Values.LB.getPointer(), // &LB - Values.UB.getPointer(), // &UB - Values.ST.getPointer(), // &Stride + Values.IL.emitRawPointer(CGF), // &isLastIter + Values.LB.emitRawPointer(CGF), // &LB + Values.UB.emitRawPointer(CGF), // &UB + Values.ST.emitRawPointer(CGF), // &Stride CGF.Builder.getIntN(Values.IVSize, 1), // Incr Chunk // Chunk }; @@ -2697,12 +2698,11 @@ llvm::Value *CGOpenMPRuntime::emitForNext(CodeGenFunction &CGF, // kmp_int[32|64] *p_lower, kmp_int[32|64] *p_upper, // kmp_int[32|64] *p_stride); llvm::Value *Args[] = { - emitUpdateLocation(CGF, Loc), - getThreadID(CGF, Loc), - IL.getPointer(), // &isLastIter - LB.getPointer(), // &Lower - UB.getPointer(), // &Upper - ST.getPointer() // &Stride + emitUpdateLocation(CGF, Loc), getThreadID(CGF, Loc), + IL.emitRawPointer(CGF), // &isLastIter + LB.emitRawPointer(CGF), // &Lower + UB.emitRawPointer(CGF), // &Upper + ST.emitRawPointer(CGF) // &Stride }; llvm::Value *Call = CGF.EmitRuntimeCall( OMPBuilder.createDispatchNextFunction(IVSize, IVSigned), Args); @@ -3047,7 +3047,7 @@ emitProxyTaskFunction(CodeGenModule &CGM, SourceLocation Loc, CGF.Builder .CreatePointerBitCastOrAddrSpaceCast(TDBase.getAddress(CGF), CGF.VoidPtrTy, CGF.Int8Ty) - .getPointer()}; + .emitRawPointer(CGF)}; SmallVector CallArgs(std::begin(CommonArgs), std::end(CommonArgs)); if (isOpenMPTaskLoopDirective(Kind)) { @@ -3574,7 +3574,8 @@ getPointerAndSize(CodeGenFunction &CGF, const Expr *E) { CGF.EmitOMPArraySectionExpr(ASE, /*IsLowerBound=*/false); Address UpAddrAddress = UpAddrLVal.getAddress(CGF); llvm::Value *UpAddr = CGF.Builder.CreateConstGEP1_32( - UpAddrAddress.getElementType(), UpAddrAddress.getPointer(), /*Idx0=*/1); + UpAddrAddress.getElementType(), UpAddrAddress.emitRawPointer(CGF), + /*Idx0=*/1); llvm::Value *LowIntPtr = CGF.Builder.CreatePtrToInt(Addr, CGF.SizeTy); llvm::Value *UpIntPtr = CGF.Builder.CreatePtrToInt(UpAddr, CGF.SizeTy); SizeVal = CGF.Builder.CreateNUWSub(UpIntPtr, LowIntPtr); @@ -3888,8 +3889,9 @@ CGOpenMPRuntime::emitTaskInit(CodeGenFunction &CGF, SourceLocation Loc, llvm::Value *Size; std::tie(Addr, Size) = getPointerAndSize(CGF, E); llvm::Value *Idx = CGF.EmitLoadOfScalar(PosLVal, E->getExprLoc()); - LValue Base = CGF.MakeAddrLValue( - CGF.Builder.CreateGEP(AffinitiesArray, Idx), KmpTaskAffinityInfoTy); + LValue Base = + CGF.MakeAddrLValue(CGF.Builder.CreateGEP(CGF, AffinitiesArray, Idx), + KmpTaskAffinityInfoTy); // affs[i].base_addr = &; LValue BaseAddrLVal = CGF.EmitLValueForField( Base, *std::next(KmpAffinityInfoRD->field_begin(), BaseAddr)); @@ -3910,7 +3912,7 @@ CGOpenMPRuntime::emitTaskInit(CodeGenFunction &CGF, SourceLocation Loc, llvm::Value *LocRef = emitUpdateLocation(CGF, Loc); llvm::Value *GTid = getThreadID(CGF, Loc); llvm::Value *AffinListPtr = CGF.Builder.CreatePointerBitCastOrAddrSpaceCast( - AffinitiesArray.getPointer(), CGM.VoidPtrTy); + AffinitiesArray.emitRawPointer(CGF), CGM.VoidPtrTy); // FIXME: Emit the function and ignore its result for now unless the // runtime function is properly implemented. (void)CGF.EmitRuntimeCall( @@ -3921,8 +3923,8 @@ CGOpenMPRuntime::emitTaskInit(CodeGenFunction &CGF, SourceLocation Loc, llvm::Value *NewTaskNewTaskTTy = CGF.Builder.CreatePointerBitCastOrAddrSpaceCast( NewTask, KmpTaskTWithPrivatesPtrTy); - LValue Base = CGF.MakeNaturalAlignAddrLValue(NewTaskNewTaskTTy, - KmpTaskTWithPrivatesQTy); + LValue Base = CGF.MakeNaturalAlignRawAddrLValue(NewTaskNewTaskTTy, + KmpTaskTWithPrivatesQTy); LValue TDBase = CGF.EmitLValueForField(Base, *KmpTaskTWithPrivatesQTyRD->field_begin()); // Fill the data in the resulting kmp_task_t record. @@ -4047,7 +4049,7 @@ CGOpenMPRuntime::getDepobjElements(CodeGenFunction &CGF, LValue DepobjLVal, CGF.ConvertTypeForMem(KmpDependInfoPtrTy)), KmpDependInfoPtrTy->castAs()); Address DepObjAddr = CGF.Builder.CreateGEP( - Base.getAddress(CGF), + CGF, Base.getAddress(CGF), llvm::ConstantInt::get(CGF.IntPtrTy, -1, /*isSigned=*/true)); LValue NumDepsBase = CGF.MakeAddrLValue( DepObjAddr, KmpDependInfoTy, Base.getBaseInfo(), Base.getTBAAInfo()); @@ -4097,7 +4099,7 @@ static void emitDependData(CodeGenFunction &CGF, QualType &KmpDependInfoTy, LValue &PosLVal = *Pos.get(); llvm::Value *Idx = CGF.EmitLoadOfScalar(PosLVal, E->getExprLoc()); Base = CGF.MakeAddrLValue( - CGF.Builder.CreateGEP(DependenciesArray, Idx), KmpDependInfoTy); + CGF.Builder.CreateGEP(CGF, DependenciesArray, Idx), KmpDependInfoTy); } // deps[i].base_addr = &; LValue BaseAddrLVal = CGF.EmitLValueForField( @@ -4195,7 +4197,7 @@ void CGOpenMPRuntime::emitDepobjElements(CodeGenFunction &CGF, ElSize, CGF.Builder.CreateIntCast(NumDeps, CGF.SizeTy, /*isSigned=*/false)); llvm::Value *Pos = CGF.EmitLoadOfScalar(PosLVal, E->getExprLoc()); - Address DepAddr = CGF.Builder.CreateGEP(DependenciesArray, Pos); + Address DepAddr = CGF.Builder.CreateGEP(CGF, DependenciesArray, Pos); CGF.Builder.CreateMemCpy(DepAddr, Base.getAddress(CGF), Size); // Increase pos. @@ -4430,7 +4432,7 @@ void CGOpenMPRuntime::emitDestroyClause(CodeGenFunction &CGF, LValue DepobjLVal, Base.getAddress(CGF), CGF.ConvertTypeForMem(KmpDependInfoPtrTy), CGF.ConvertTypeForMem(KmpDependInfoTy)); llvm::Value *DepObjAddr = CGF.Builder.CreateGEP( - Addr.getElementType(), Addr.getPointer(), + Addr.getElementType(), Addr.emitRawPointer(CGF), llvm::ConstantInt::get(CGF.IntPtrTy, -1, /*isSigned=*/true)); DepObjAddr = CGF.Builder.CreatePointerBitCastOrAddrSpaceCast(DepObjAddr, CGF.VoidPtrTy); @@ -4460,8 +4462,8 @@ void CGOpenMPRuntime::emitUpdateClause(CodeGenFunction &CGF, LValue DepobjLVal, Address Begin = Base.getAddress(CGF); // Cast from pointer to array type to pointer to single element. - llvm::Value *End = CGF.Builder.CreateGEP( - Begin.getElementType(), Begin.getPointer(), NumDeps); + llvm::Value *End = CGF.Builder.CreateGEP(Begin.getElementType(), + Begin.emitRawPointer(CGF), NumDeps); // The basic structure here is a while-do loop. llvm::BasicBlock *BodyBB = CGF.createBasicBlock("omp.body"); llvm::BasicBlock *DoneBB = CGF.createBasicBlock("omp.done"); @@ -4469,7 +4471,7 @@ void CGOpenMPRuntime::emitUpdateClause(CodeGenFunction &CGF, LValue DepobjLVal, CGF.EmitBlock(BodyBB); llvm::PHINode *ElementPHI = CGF.Builder.CreatePHI(Begin.getType(), 2, "omp.elementPast"); - ElementPHI->addIncoming(Begin.getPointer(), EntryBB); + ElementPHI->addIncoming(Begin.emitRawPointer(CGF), EntryBB); Begin = Begin.withPointer(ElementPHI, KnownNonNull); Base = CGF.MakeAddrLValue(Begin, KmpDependInfoTy, Base.getBaseInfo(), Base.getTBAAInfo()); @@ -4483,12 +4485,12 @@ void CGOpenMPRuntime::emitUpdateClause(CodeGenFunction &CGF, LValue DepobjLVal, FlagsLVal); // Shift the address forward by one element. - Address ElementNext = - CGF.Builder.CreateConstGEP(Begin, /*Index=*/1, "omp.elementNext"); - ElementPHI->addIncoming(ElementNext.getPointer(), - CGF.Builder.GetInsertBlock()); + llvm::Value *ElementNext = + CGF.Builder.CreateConstGEP(Begin, /*Index=*/1, "omp.elementNext") + .emitRawPointer(CGF); + ElementPHI->addIncoming(ElementNext, CGF.Builder.GetInsertBlock()); llvm::Value *IsEmpty = - CGF.Builder.CreateICmpEQ(ElementNext.getPointer(), End, "omp.isempty"); + CGF.Builder.CreateICmpEQ(ElementNext, End, "omp.isempty"); CGF.Builder.CreateCondBr(IsEmpty, DoneBB, BodyBB); // Done. CGF.EmitBlock(DoneBB, /*IsFinished=*/true); @@ -4531,7 +4533,7 @@ void CGOpenMPRuntime::emitTaskCall(CodeGenFunction &CGF, SourceLocation Loc, DepTaskArgs[1] = ThreadID; DepTaskArgs[2] = NewTask; DepTaskArgs[3] = NumOfElements; - DepTaskArgs[4] = DependenciesArray.getPointer(); + DepTaskArgs[4] = DependenciesArray.emitRawPointer(CGF); DepTaskArgs[5] = CGF.Builder.getInt32(0); DepTaskArgs[6] = llvm::ConstantPointerNull::get(CGF.VoidPtrTy); } @@ -4563,7 +4565,7 @@ void CGOpenMPRuntime::emitTaskCall(CodeGenFunction &CGF, SourceLocation Loc, DepWaitTaskArgs[0] = UpLoc; DepWaitTaskArgs[1] = ThreadID; DepWaitTaskArgs[2] = NumOfElements; - DepWaitTaskArgs[3] = DependenciesArray.getPointer(); + DepWaitTaskArgs[3] = DependenciesArray.emitRawPointer(CGF); DepWaitTaskArgs[4] = CGF.Builder.getInt32(0); DepWaitTaskArgs[5] = llvm::ConstantPointerNull::get(CGF.VoidPtrTy); DepWaitTaskArgs[6] = @@ -4725,8 +4727,8 @@ static void EmitOMPAggregateReduction( const ArrayType *ArrayTy = Type->getAsArrayTypeUnsafe(); llvm::Value *NumElements = CGF.emitArrayLength(ArrayTy, ElementTy, LHSAddr); - llvm::Value *RHSBegin = RHSAddr.getPointer(); - llvm::Value *LHSBegin = LHSAddr.getPointer(); + llvm::Value *RHSBegin = RHSAddr.emitRawPointer(CGF); + llvm::Value *LHSBegin = LHSAddr.emitRawPointer(CGF); // Cast from pointer to array type to pointer to single element. llvm::Value *LHSEnd = CGF.Builder.CreateGEP(LHSAddr.getElementType(), LHSBegin, NumElements); @@ -4990,7 +4992,7 @@ void CGOpenMPRuntime::emitReduction(CodeGenFunction &CGF, SourceLocation Loc, QualType ReductionArrayTy = C.getConstantArrayType( C.VoidPtrTy, ArraySize, nullptr, ArraySizeModifier::Normal, /*IndexTypeQuals=*/0); - Address ReductionList = + RawAddress ReductionList = CGF.CreateMemTemp(ReductionArrayTy, ".omp.reduction.red_list"); const auto *IPriv = Privates.begin(); unsigned Idx = 0; @@ -5462,7 +5464,7 @@ llvm::Value *CGOpenMPRuntime::emitTaskReductionInit( C.getConstantArrayType(RDType, ArraySize, nullptr, ArraySizeModifier::Normal, /*IndexTypeQuals=*/0); // kmp_task_red_input_t .rd_input.[Size]; - Address TaskRedInput = CGF.CreateMemTemp(ArrayRDType, ".rd_input."); + RawAddress TaskRedInput = CGF.CreateMemTemp(ArrayRDType, ".rd_input."); ReductionCodeGen RCG(Data.ReductionVars, Data.ReductionOrigs, Data.ReductionCopies, Data.ReductionOps); for (unsigned Cnt = 0; Cnt < Size; ++Cnt) { @@ -5473,7 +5475,7 @@ llvm::Value *CGOpenMPRuntime::emitTaskReductionInit( TaskRedInput.getElementType(), TaskRedInput.getPointer(), Idxs, /*SignedIndices=*/false, /*IsSubtraction=*/false, Loc, ".rd_input.gep."); - LValue ElemLVal = CGF.MakeNaturalAlignAddrLValue(GEP, RDType); + LValue ElemLVal = CGF.MakeNaturalAlignRawAddrLValue(GEP, RDType); // ElemLVal.reduce_shar = &Shareds[Cnt]; LValue SharedLVal = CGF.EmitLValueForField(ElemLVal, SharedFD); RCG.emitSharedOrigLValue(CGF, Cnt); @@ -5629,7 +5631,7 @@ void CGOpenMPRuntime::emitTaskwaitCall(CodeGenFunction &CGF, SourceLocation Loc, DepWaitTaskArgs[0] = UpLoc; DepWaitTaskArgs[1] = ThreadID; DepWaitTaskArgs[2] = NumOfElements; - DepWaitTaskArgs[3] = DependenciesArray.getPointer(); + DepWaitTaskArgs[3] = DependenciesArray.emitRawPointer(CGF); DepWaitTaskArgs[4] = CGF.Builder.getInt32(0); DepWaitTaskArgs[5] = llvm::ConstantPointerNull::get(CGF.VoidPtrTy); DepWaitTaskArgs[6] = @@ -5852,7 +5854,7 @@ void CGOpenMPRuntime::emitUsesAllocatorsInit(CodeGenFunction &CGF, AllocatorTraitsLVal = CGF.MakeAddrLValue(Addr, CGF.getContext().VoidPtrTy, AllocatorTraitsLVal.getBaseInfo(), AllocatorTraitsLVal.getTBAAInfo()); - llvm::Value *Traits = Addr.getPointer(); + llvm::Value *Traits = Addr.emitRawPointer(CGF); llvm::Value *AllocatorVal = CGF.EmitRuntimeCall(OMPBuilder.getOrCreateRuntimeFunction( @@ -7312,17 +7314,19 @@ private: CGF.EmitOMPSharedLValue(MC.getAssociatedExpression()) .getAddress(CGF); } - Size = CGF.Builder.CreatePtrDiff( - CGF.Int8Ty, ComponentLB.getPointer(), LB.getPointer()); + llvm::Value *ComponentLBPtr = ComponentLB.emitRawPointer(CGF); + llvm::Value *LBPtr = LB.emitRawPointer(CGF); + Size = CGF.Builder.CreatePtrDiff(CGF.Int8Ty, ComponentLBPtr, + LBPtr); break; } } assert(Size && "Failed to determine structure size"); CombinedInfo.Exprs.emplace_back(MapDecl, MapExpr); - CombinedInfo.BasePointers.push_back(BP.getPointer()); + CombinedInfo.BasePointers.push_back(BP.emitRawPointer(CGF)); CombinedInfo.DevicePtrDecls.push_back(nullptr); CombinedInfo.DevicePointers.push_back(DeviceInfoTy::None); - CombinedInfo.Pointers.push_back(LB.getPointer()); + CombinedInfo.Pointers.push_back(LB.emitRawPointer(CGF)); CombinedInfo.Sizes.push_back(CGF.Builder.CreateIntCast( Size, CGF.Int64Ty, /*isSigned=*/true)); CombinedInfo.Types.push_back(Flags); @@ -7332,13 +7336,14 @@ private: LB = CGF.Builder.CreateConstGEP(ComponentLB, 1); } CombinedInfo.Exprs.emplace_back(MapDecl, MapExpr); - CombinedInfo.BasePointers.push_back(BP.getPointer()); + CombinedInfo.BasePointers.push_back(BP.emitRawPointer(CGF)); CombinedInfo.DevicePtrDecls.push_back(nullptr); CombinedInfo.DevicePointers.push_back(DeviceInfoTy::None); - CombinedInfo.Pointers.push_back(LB.getPointer()); + CombinedInfo.Pointers.push_back(LB.emitRawPointer(CGF)); + llvm::Value *LBPtr = LB.emitRawPointer(CGF); Size = CGF.Builder.CreatePtrDiff( - CGF.Int8Ty, CGF.Builder.CreateConstGEP(HB, 1).getPointer(), - LB.getPointer()); + CGF.Int8Ty, CGF.Builder.CreateConstGEP(HB, 1).emitRawPointer(CGF), + LBPtr); CombinedInfo.Sizes.push_back( CGF.Builder.CreateIntCast(Size, CGF.Int64Ty, /*isSigned=*/true)); CombinedInfo.Types.push_back(Flags); @@ -7356,20 +7361,21 @@ private: (Next == CE && MapType != OMPC_MAP_unknown)) { if (!IsMappingWholeStruct) { CombinedInfo.Exprs.emplace_back(MapDecl, MapExpr); - CombinedInfo.BasePointers.push_back(BP.getPointer()); + CombinedInfo.BasePointers.push_back(BP.emitRawPointer(CGF)); CombinedInfo.DevicePtrDecls.push_back(nullptr); CombinedInfo.DevicePointers.push_back(DeviceInfoTy::None); - CombinedInfo.Pointers.push_back(LB.getPointer()); + CombinedInfo.Pointers.push_back(LB.emitRawPointer(CGF)); CombinedInfo.Sizes.push_back(CGF.Builder.CreateIntCast( Size, CGF.Int64Ty, /*isSigned=*/true)); CombinedInfo.NonContigInfo.Dims.push_back(IsNonContiguous ? DimSize : 1); } else { StructBaseCombinedInfo.Exprs.emplace_back(MapDecl, MapExpr); - StructBaseCombinedInfo.BasePointers.push_back(BP.getPointer()); + StructBaseCombinedInfo.BasePointers.push_back( + BP.emitRawPointer(CGF)); StructBaseCombinedInfo.DevicePtrDecls.push_back(nullptr); StructBaseCombinedInfo.DevicePointers.push_back(DeviceInfoTy::None); - StructBaseCombinedInfo.Pointers.push_back(LB.getPointer()); + StructBaseCombinedInfo.Pointers.push_back(LB.emitRawPointer(CGF)); StructBaseCombinedInfo.Sizes.push_back(CGF.Builder.CreateIntCast( Size, CGF.Int64Ty, /*isSigned=*/true)); StructBaseCombinedInfo.NonContigInfo.Dims.push_back( @@ -8211,11 +8217,11 @@ public: } CombinedInfo.Exprs.push_back(VD); // Base is the base of the struct - CombinedInfo.BasePointers.push_back(PartialStruct.Base.getPointer()); + CombinedInfo.BasePointers.push_back(PartialStruct.Base.emitRawPointer(CGF)); CombinedInfo.DevicePtrDecls.push_back(nullptr); CombinedInfo.DevicePointers.push_back(DeviceInfoTy::None); // Pointer is the address of the lowest element - llvm::Value *LB = LBAddr.getPointer(); + llvm::Value *LB = LBAddr.emitRawPointer(CGF); const CXXMethodDecl *MD = CGF.CurFuncDecl ? dyn_cast(CGF.CurFuncDecl) : nullptr; const CXXRecordDecl *RD = MD ? MD->getParent() : nullptr; @@ -8229,7 +8235,7 @@ public: // if the this[:1] expression had appeared in a map clause with a map-type // of tofrom. // Emit this[:1] - CombinedInfo.Pointers.push_back(PartialStruct.Base.getPointer()); + CombinedInfo.Pointers.push_back(PartialStruct.Base.emitRawPointer(CGF)); QualType Ty = MD->getFunctionObjectParameterType(); llvm::Value *Size = CGF.Builder.CreateIntCast(CGF.getTypeSize(Ty), CGF.Int64Ty, @@ -8238,7 +8244,7 @@ public: } else { CombinedInfo.Pointers.push_back(LB); // Size is (addr of {highest+1} element) - (addr of lowest element) - llvm::Value *HB = HBAddr.getPointer(); + llvm::Value *HB = HBAddr.emitRawPointer(CGF); llvm::Value *HAddr = CGF.Builder.CreateConstGEP1_32( HBAddr.getElementType(), HB, /*Idx0=*/1); llvm::Value *CLAddr = CGF.Builder.CreatePointerCast(LB, CGF.VoidPtrTy); @@ -8747,7 +8753,7 @@ public: Address PtrAddr = CGF.EmitLoadOfReference(CGF.MakeAddrLValue( CV, ElementType, CGF.getContext().getDeclAlign(VD), AlignmentSource::Decl)); - CombinedInfo.Pointers.push_back(PtrAddr.getPointer()); + CombinedInfo.Pointers.push_back(PtrAddr.emitRawPointer(CGF)); } else { CombinedInfo.Pointers.push_back(CV); } @@ -9558,10 +9564,11 @@ static void emitTargetCallKernelLaunch( bool HasNoWait = D.hasClausesOfKind(); unsigned NumTargetItems = InputInfo.NumberOfTargetItems; - llvm::Value *BasePointersArray = InputInfo.BasePointersArray.getPointer(); - llvm::Value *PointersArray = InputInfo.PointersArray.getPointer(); - llvm::Value *SizesArray = InputInfo.SizesArray.getPointer(); - llvm::Value *MappersArray = InputInfo.MappersArray.getPointer(); + llvm::Value *BasePointersArray = + InputInfo.BasePointersArray.emitRawPointer(CGF); + llvm::Value *PointersArray = InputInfo.PointersArray.emitRawPointer(CGF); + llvm::Value *SizesArray = InputInfo.SizesArray.emitRawPointer(CGF); + llvm::Value *MappersArray = InputInfo.MappersArray.emitRawPointer(CGF); auto &&EmitTargetCallFallbackCB = [&OMPRuntime, OutlinedFn, &D, &CapturedVars, RequiresOuterTask, &CS, @@ -10309,15 +10316,16 @@ void CGOpenMPRuntime::emitTargetDataStandAloneCall( // Source location for the ident struct llvm::Value *RTLoc = emitUpdateLocation(CGF, D.getBeginLoc()); - llvm::Value *OffloadingArgs[] = {RTLoc, - DeviceID, - PointerNum, - InputInfo.BasePointersArray.getPointer(), - InputInfo.PointersArray.getPointer(), - InputInfo.SizesArray.getPointer(), - MapTypesArray, - MapNamesArray, - InputInfo.MappersArray.getPointer()}; + llvm::Value *OffloadingArgs[] = { + RTLoc, + DeviceID, + PointerNum, + InputInfo.BasePointersArray.emitRawPointer(CGF), + InputInfo.PointersArray.emitRawPointer(CGF), + InputInfo.SizesArray.emitRawPointer(CGF), + MapTypesArray, + MapNamesArray, + InputInfo.MappersArray.emitRawPointer(CGF)}; // Select the right runtime function call for each standalone // directive. @@ -11128,7 +11136,7 @@ void CGOpenMPRuntime::emitDoacrossInit(CodeGenFunction &CGF, getThreadID(CGF, D.getBeginLoc()), llvm::ConstantInt::getSigned(CGM.Int32Ty, NumIterations.size()), CGF.Builder.CreatePointerBitCastOrAddrSpaceCast( - CGF.Builder.CreateConstArrayGEP(DimsAddr, 0).getPointer(), + CGF.Builder.CreateConstArrayGEP(DimsAddr, 0).emitRawPointer(CGF), CGM.VoidPtrTy)}; llvm::FunctionCallee RTLFn = OMPBuilder.getOrCreateRuntimeFunction( @@ -11162,7 +11170,8 @@ static void EmitDoacrossOrdered(CodeGenFunction &CGF, CodeGenModule &CGM, /*Volatile=*/false, Int64Ty); } llvm::Value *Args[] = { - ULoc, ThreadID, CGF.Builder.CreateConstArrayGEP(CntAddr, 0).getPointer()}; + ULoc, ThreadID, + CGF.Builder.CreateConstArrayGEP(CntAddr, 0).emitRawPointer(CGF)}; llvm::FunctionCallee RTLFn; llvm::OpenMPIRBuilder &OMPBuilder = CGM.getOpenMPRuntime().getOMPBuilder(); OMPDoacrossKind ODK; @@ -11332,7 +11341,7 @@ Address CGOpenMPRuntime::getAddressOfLocalVariable(CodeGenFunction &CGF, Args[0] = CGF.CGM.getOpenMPRuntime().getThreadID( CGF, SourceLocation::getFromRawEncoding(LocEncoding)); Args[1] = CGF.Builder.CreatePointerBitCastOrAddrSpaceCast( - Addr.getPointer(), CGF.VoidPtrTy); + Addr.emitRawPointer(CGF), CGF.VoidPtrTy); llvm::Value *AllocVal = getAllocatorVal(CGF, AllocExpr); Args[2] = AllocVal; CGF.EmitRuntimeCall(RTLFn, Args); @@ -11690,15 +11699,17 @@ void CGOpenMPRuntime::emitLastprivateConditionalUpdate(CodeGenFunction &CGF, LLIVTy, getName({UniqueDeclName, "iv"})); cast(LastIV)->setAlignment( IVLVal.getAlignment().getAsAlign()); - LValue LastIVLVal = CGF.MakeNaturalAlignAddrLValue(LastIV, IVLVal.getType()); + LValue LastIVLVal = + CGF.MakeNaturalAlignRawAddrLValue(LastIV, IVLVal.getType()); // Last value of the lastprivate conditional. // decltype(priv_a) last_a; llvm::GlobalVariable *Last = OMPBuilder.getOrCreateInternalVariable( CGF.ConvertTypeForMem(LVal.getType()), UniqueDeclName); - Last->setAlignment(LVal.getAlignment().getAsAlign()); - LValue LastLVal = CGF.MakeAddrLValue( - Address(Last, Last->getValueType(), LVal.getAlignment()), LVal.getType()); + cast(Last)->setAlignment( + LVal.getAlignment().getAsAlign()); + LValue LastLVal = + CGF.MakeRawAddrLValue(Last, LVal.getType(), LVal.getAlignment()); // Global loop counter. Required to handle inner parallel-for regions. // iv @@ -11871,9 +11882,8 @@ void CGOpenMPRuntime::emitLastprivateConditionalFinalUpdate( // The variable was not updated in the region - exit. if (!GV) return; - LValue LPLVal = CGF.MakeAddrLValue( - Address(GV, GV->getValueType(), PrivLVal.getAlignment()), - PrivLVal.getType().getNonReferenceType()); + LValue LPLVal = CGF.MakeRawAddrLValue( + GV, PrivLVal.getType().getNonReferenceType(), PrivLVal.getAlignment()); llvm::Value *Res = CGF.EmitLoadOfScalar(LPLVal, Loc); CGF.EmitStoreOfScalar(Res, PrivLVal); } diff --git a/clang/lib/CodeGen/CGOpenMPRuntime.h b/clang/lib/CodeGen/CGOpenMPRuntime.h index c3206427b143..522ae3d35d22 100644 --- a/clang/lib/CodeGen/CGOpenMPRuntime.h +++ b/clang/lib/CodeGen/CGOpenMPRuntime.h @@ -1068,13 +1068,12 @@ public: /// \param Loc Location of the reference to threadprivate var. /// \return Address of the threadprivate variable for the current thread. virtual Address getAddrOfThreadPrivate(CodeGenFunction &CGF, - const VarDecl *VD, - Address VDAddr, + const VarDecl *VD, Address VDAddr, SourceLocation Loc); /// Returns the address of the variable marked as declare target with link /// clause OR as declare target with to clause and unified memory. - virtual Address getAddrOfDeclareTargetVar(const VarDecl *VD); + virtual ConstantAddress getAddrOfDeclareTargetVar(const VarDecl *VD); /// Emit a code for initialization of threadprivate variable. It emits /// a call to runtime library which adds initial value to the newly created diff --git a/clang/lib/CodeGen/CGOpenMPRuntimeGPU.cpp b/clang/lib/CodeGen/CGOpenMPRuntimeGPU.cpp index 299ee1460b3d..5baac8f0e3e2 100644 --- a/clang/lib/CodeGen/CGOpenMPRuntimeGPU.cpp +++ b/clang/lib/CodeGen/CGOpenMPRuntimeGPU.cpp @@ -1096,7 +1096,8 @@ void CGOpenMPRuntimeGPU::emitGenericVarsProlog(CodeGenFunction &CGF, llvm::PointerType *VarPtrTy = CGF.ConvertTypeForMem(VarTy)->getPointerTo(); llvm::Value *CastedVoidPtr = Bld.CreatePointerBitCastOrAddrSpaceCast( VoidPtr, VarPtrTy, VD->getName() + "_on_stack"); - LValue VarAddr = CGF.MakeNaturalAlignAddrLValue(CastedVoidPtr, VarTy); + LValue VarAddr = + CGF.MakeNaturalAlignPointeeRawAddrLValue(CastedVoidPtr, VarTy); Rec.second.PrivateAddr = VarAddr.getAddress(CGF); Rec.second.GlobalizedVal = VoidPtr; @@ -1206,8 +1207,8 @@ void CGOpenMPRuntimeGPU::emitTeamsCall(CodeGenFunction &CGF, bool IsBareKernel = D.getSingleClause(); - Address ZeroAddr = CGF.CreateDefaultAlignTempAlloca(CGF.Int32Ty, - /*Name=*/".zero.addr"); + RawAddress ZeroAddr = CGF.CreateDefaultAlignTempAlloca(CGF.Int32Ty, + /*Name=*/".zero.addr"); CGF.Builder.CreateStore(CGF.Builder.getInt32(/*C*/ 0), ZeroAddr); llvm::SmallVector OutlinedFnArgs; // We don't emit any thread id function call in bare kernel, but because the @@ -1215,7 +1216,7 @@ void CGOpenMPRuntimeGPU::emitTeamsCall(CodeGenFunction &CGF, if (IsBareKernel) OutlinedFnArgs.push_back(llvm::ConstantPointerNull::get(CGM.VoidPtrTy)); else - OutlinedFnArgs.push_back(emitThreadIDAddress(CGF, Loc).getPointer()); + OutlinedFnArgs.push_back(emitThreadIDAddress(CGF, Loc).emitRawPointer(CGF)); OutlinedFnArgs.push_back(ZeroAddr.getPointer()); OutlinedFnArgs.append(CapturedVars.begin(), CapturedVars.end()); emitOutlinedFunctionCall(CGF, Loc, OutlinedFn, OutlinedFnArgs); @@ -1289,7 +1290,7 @@ void CGOpenMPRuntimeGPU::emitParallelCall(CodeGenFunction &CGF, llvm::ConstantInt::get(CGF.Int32Ty, -1), FnPtr, ID, - Bld.CreateBitOrPointerCast(CapturedVarsAddrs.getPointer(), + Bld.CreateBitOrPointerCast(CapturedVarsAddrs.emitRawPointer(CGF), CGF.VoidPtrPtrTy), llvm::ConstantInt::get(CGM.SizeTy, CapturedVars.size())}; CGF.EmitRuntimeCall(OMPBuilder.getOrCreateRuntimeFunction( @@ -1503,17 +1504,18 @@ static void shuffleAndStore(CodeGenFunction &CGF, Address SrcAddr, CGF.EmitBlock(PreCondBB); llvm::PHINode *PhiSrc = Bld.CreatePHI(Ptr.getType(), /*NumReservedValues=*/2); - PhiSrc->addIncoming(Ptr.getPointer(), CurrentBB); + PhiSrc->addIncoming(Ptr.emitRawPointer(CGF), CurrentBB); llvm::PHINode *PhiDest = Bld.CreatePHI(ElemPtr.getType(), /*NumReservedValues=*/2); - PhiDest->addIncoming(ElemPtr.getPointer(), CurrentBB); + PhiDest->addIncoming(ElemPtr.emitRawPointer(CGF), CurrentBB); Ptr = Address(PhiSrc, Ptr.getElementType(), Ptr.getAlignment()); ElemPtr = Address(PhiDest, ElemPtr.getElementType(), ElemPtr.getAlignment()); + llvm::Value *PtrEndRaw = PtrEnd.emitRawPointer(CGF); + llvm::Value *PtrRaw = Ptr.emitRawPointer(CGF); llvm::Value *PtrDiff = Bld.CreatePtrDiff( - CGF.Int8Ty, PtrEnd.getPointer(), - Bld.CreatePointerBitCastOrAddrSpaceCast(Ptr.getPointer(), - CGF.VoidPtrTy)); + CGF.Int8Ty, PtrEndRaw, + Bld.CreatePointerBitCastOrAddrSpaceCast(PtrRaw, CGF.VoidPtrTy)); Bld.CreateCondBr(Bld.CreateICmpSGT(PtrDiff, Bld.getInt64(IntSize - 1)), ThenBB, ExitBB); CGF.EmitBlock(ThenBB); @@ -1528,8 +1530,8 @@ static void shuffleAndStore(CodeGenFunction &CGF, Address SrcAddr, TBAAAccessInfo()); Address LocalPtr = Bld.CreateConstGEP(Ptr, 1); Address LocalElemPtr = Bld.CreateConstGEP(ElemPtr, 1); - PhiSrc->addIncoming(LocalPtr.getPointer(), ThenBB); - PhiDest->addIncoming(LocalElemPtr.getPointer(), ThenBB); + PhiSrc->addIncoming(LocalPtr.emitRawPointer(CGF), ThenBB); + PhiDest->addIncoming(LocalElemPtr.emitRawPointer(CGF), ThenBB); CGF.EmitBranch(PreCondBB); CGF.EmitBlock(ExitBB); } else { @@ -1676,10 +1678,10 @@ static void emitReductionListCopy( // scope and that of functions it invokes (i.e., reduce_function). // RemoteReduceData[i] = (void*)&RemoteElem if (UpdateDestListPtr) { - CGF.EmitStoreOfScalar(Bld.CreatePointerBitCastOrAddrSpaceCast( - DestElementAddr.getPointer(), CGF.VoidPtrTy), - DestElementPtrAddr, /*Volatile=*/false, - C.VoidPtrTy); + CGF.EmitStoreOfScalar( + Bld.CreatePointerBitCastOrAddrSpaceCast( + DestElementAddr.emitRawPointer(CGF), CGF.VoidPtrTy), + DestElementPtrAddr, /*Volatile=*/false, C.VoidPtrTy); } ++Idx; @@ -1830,7 +1832,7 @@ static llvm::Value *emitInterWarpCopyFunction(CodeGenModule &CGM, // elemptr = ((CopyType*)(elemptrptr)) + I Address ElemPtr(ElemPtrPtr, CopyType, Align); if (NumIters > 1) - ElemPtr = Bld.CreateGEP(ElemPtr, Cnt); + ElemPtr = Bld.CreateGEP(CGF, ElemPtr, Cnt); // Get pointer to location in transfer medium. // MediumPtr = &medium[warp_id] @@ -1894,7 +1896,7 @@ static llvm::Value *emitInterWarpCopyFunction(CodeGenModule &CGM, TargetElemPtrPtr, /*Volatile=*/false, C.VoidPtrTy, Loc); Address TargetElemPtr(TargetElemPtrVal, CopyType, Align); if (NumIters > 1) - TargetElemPtr = Bld.CreateGEP(TargetElemPtr, Cnt); + TargetElemPtr = Bld.CreateGEP(CGF, TargetElemPtr, Cnt); // *TargetElemPtr = SrcMediumVal; llvm::Value *SrcMediumValue = @@ -2105,9 +2107,9 @@ static llvm::Function *emitShuffleAndReduceFunction( CGF.EmitBlock(ThenBB); // reduce_function(LocalReduceList, RemoteReduceList) llvm::Value *LocalReduceListPtr = Bld.CreatePointerBitCastOrAddrSpaceCast( - LocalReduceList.getPointer(), CGF.VoidPtrTy); + LocalReduceList.emitRawPointer(CGF), CGF.VoidPtrTy); llvm::Value *RemoteReduceListPtr = Bld.CreatePointerBitCastOrAddrSpaceCast( - RemoteReduceList.getPointer(), CGF.VoidPtrTy); + RemoteReduceList.emitRawPointer(CGF), CGF.VoidPtrTy); CGM.getOpenMPRuntime().emitOutlinedFunctionCall( CGF, Loc, ReduceFn, {LocalReduceListPtr, RemoteReduceListPtr}); Bld.CreateBr(MergeBB); @@ -2218,9 +2220,9 @@ static llvm::Value *emitListToGlobalCopyFunction( llvm::Value *BufferPtr = Bld.CreateInBoundsGEP(LLVMReductionsBufferTy, BufferArrPtr, Idxs); LValue GlobLVal = CGF.EmitLValueForField( - CGF.MakeNaturalAlignAddrLValue(BufferPtr, StaticTy), FD); + CGF.MakeNaturalAlignRawAddrLValue(BufferPtr, StaticTy), FD); Address GlobAddr = GlobLVal.getAddress(CGF); - GlobLVal.setAddress(Address(GlobAddr.getPointer(), + GlobLVal.setAddress(Address(GlobAddr.emitRawPointer(CGF), CGF.ConvertTypeForMem(Private->getType()), GlobAddr.getAlignment())); switch (CGF.getEvaluationKind(Private->getType())) { @@ -2304,7 +2306,7 @@ static llvm::Value *emitListToGlobalReduceFunction( // 1. Build a list of reduction variables. // void *RedList[] = {[0], ..., [-1]}; - Address ReductionList = + RawAddress ReductionList = CGF.CreateMemTemp(ReductionArrayTy, ".omp.reduction.red_list"); auto IPriv = Privates.begin(); llvm::Value *Idxs[] = {CGF.EmitLoadOfScalar(CGF.GetAddrOfLocalVar(&IdxArg), @@ -2319,10 +2321,10 @@ static llvm::Value *emitListToGlobalReduceFunction( llvm::Value *BufferPtr = Bld.CreateInBoundsGEP(LLVMReductionsBufferTy, BufferArrPtr, Idxs); LValue GlobLVal = CGF.EmitLValueForField( - CGF.MakeNaturalAlignAddrLValue(BufferPtr, StaticTy), FD); + CGF.MakeNaturalAlignRawAddrLValue(BufferPtr, StaticTy), FD); Address GlobAddr = GlobLVal.getAddress(CGF); - CGF.EmitStoreOfScalar(GlobAddr.getPointer(), Elem, /*Volatile=*/false, - C.VoidPtrTy); + CGF.EmitStoreOfScalar(GlobAddr.emitRawPointer(CGF), Elem, + /*Volatile=*/false, C.VoidPtrTy); if ((*IPriv)->getType()->isVariablyModifiedType()) { // Store array size. ++Idx; @@ -2425,9 +2427,9 @@ static llvm::Value *emitGlobalToListCopyFunction( llvm::Value *BufferPtr = Bld.CreateInBoundsGEP(LLVMReductionsBufferTy, BufferArrPtr, Idxs); LValue GlobLVal = CGF.EmitLValueForField( - CGF.MakeNaturalAlignAddrLValue(BufferPtr, StaticTy), FD); + CGF.MakeNaturalAlignRawAddrLValue(BufferPtr, StaticTy), FD); Address GlobAddr = GlobLVal.getAddress(CGF); - GlobLVal.setAddress(Address(GlobAddr.getPointer(), + GlobLVal.setAddress(Address(GlobAddr.emitRawPointer(CGF), CGF.ConvertTypeForMem(Private->getType()), GlobAddr.getAlignment())); switch (CGF.getEvaluationKind(Private->getType())) { @@ -2526,10 +2528,10 @@ static llvm::Value *emitGlobalToListReduceFunction( llvm::Value *BufferPtr = Bld.CreateInBoundsGEP(LLVMReductionsBufferTy, BufferArrPtr, Idxs); LValue GlobLVal = CGF.EmitLValueForField( - CGF.MakeNaturalAlignAddrLValue(BufferPtr, StaticTy), FD); + CGF.MakeNaturalAlignRawAddrLValue(BufferPtr, StaticTy), FD); Address GlobAddr = GlobLVal.getAddress(CGF); - CGF.EmitStoreOfScalar(GlobAddr.getPointer(), Elem, /*Volatile=*/false, - C.VoidPtrTy); + CGF.EmitStoreOfScalar(GlobAddr.emitRawPointer(CGF), Elem, + /*Volatile=*/false, C.VoidPtrTy); if ((*IPriv)->getType()->isVariablyModifiedType()) { // Store array size. ++Idx; @@ -2545,7 +2547,7 @@ static llvm::Value *emitGlobalToListReduceFunction( } // Call reduce_function(ReduceList, GlobalReduceList) - llvm::Value *GlobalReduceList = ReductionList.getPointer(); + llvm::Value *GlobalReduceList = ReductionList.emitRawPointer(CGF); Address AddrReduceListArg = CGF.GetAddrOfLocalVar(&ReduceListArg); llvm::Value *ReducedPtr = CGF.EmitLoadOfScalar( AddrReduceListArg, /*Volatile=*/false, C.VoidPtrTy, Loc); @@ -2876,7 +2878,7 @@ void CGOpenMPRuntimeGPU::emitReduction( } llvm::Value *RL = CGF.Builder.CreatePointerBitCastOrAddrSpaceCast( - ReductionList.getPointer(), CGF.VoidPtrTy); + ReductionList.emitRawPointer(CGF), CGF.VoidPtrTy); llvm::Function *ReductionFn = emitReductionFunction( CGF.CurFn->getName(), Loc, CGF.ConvertTypeForMem(ReductionArrayTy), Privates, LHSExprs, RHSExprs, ReductionOps); @@ -3106,15 +3108,15 @@ llvm::Function *CGOpenMPRuntimeGPU::createParallelDataSharingWrapper( // Get the array of arguments. SmallVector Args; - Args.emplace_back(CGF.GetAddrOfLocalVar(&WrapperArg).getPointer()); - Args.emplace_back(ZeroAddr.getPointer()); + Args.emplace_back(CGF.GetAddrOfLocalVar(&WrapperArg).emitRawPointer(CGF)); + Args.emplace_back(ZeroAddr.emitRawPointer(CGF)); CGBuilderTy &Bld = CGF.Builder; auto CI = CS.capture_begin(); // Use global memory for data sharing. // Handle passing of global args to workers. - Address GlobalArgs = + RawAddress GlobalArgs = CGF.CreateDefaultAlignTempAlloca(CGF.VoidPtrPtrTy, "global_args"); llvm::Value *GlobalArgsPtr = GlobalArgs.getPointer(); llvm::Value *DataSharingArgs[] = {GlobalArgsPtr}; @@ -3400,7 +3402,7 @@ void CGOpenMPRuntimeGPU::adjustTargetSpecificDataForLambdas( VDAddr = CGF.EmitLoadOfReferenceLValue(VDAddr, VD->getType().getCanonicalType()) .getAddress(CGF); - CGF.EmitStoreOfScalar(VDAddr.getPointer(), VarLVal); + CGF.EmitStoreOfScalar(VDAddr.emitRawPointer(CGF), VarLVal); } } } diff --git a/clang/lib/CodeGen/CGStmt.cpp b/clang/lib/CodeGen/CGStmt.cpp index cb5a004e4f4a..576fe2f7a2d4 100644 --- a/clang/lib/CodeGen/CGStmt.cpp +++ b/clang/lib/CodeGen/CGStmt.cpp @@ -2294,7 +2294,7 @@ std::pair CodeGenFunction::EmitAsmInputLValue( Address Addr = InputValue.getAddress(*this); ConstraintStr += '*'; - return {Addr.getPointer(), Addr.getElementType()}; + return {InputValue.getPointer(*this), Addr.getElementType()}; } std::pair @@ -2701,7 +2701,7 @@ void CodeGenFunction::EmitAsmStmt(const AsmStmt &S) { ArgTypes.push_back(DestAddr.getType()); ArgElemTypes.push_back(DestAddr.getElementType()); - Args.push_back(DestAddr.getPointer()); + Args.push_back(DestAddr.emitRawPointer(*this)); Constraints += "=*"; Constraints += OutputConstraint; ReadOnly = ReadNone = false; @@ -3076,8 +3076,8 @@ CodeGenFunction::GenerateCapturedStmtFunction(const CapturedStmt &S) { CapturedStmtInfo->setContextValue(Builder.CreateLoad(DeclPtr)); // Initialize variable-length arrays. - LValue Base = MakeNaturalAlignAddrLValue(CapturedStmtInfo->getContextValue(), - Ctx.getTagDeclType(RD)); + LValue Base = MakeNaturalAlignRawAddrLValue( + CapturedStmtInfo->getContextValue(), Ctx.getTagDeclType(RD)); for (auto *FD : RD->fields()) { if (FD->hasCapturedVLAType()) { auto *ExprArg = diff --git a/clang/lib/CodeGen/CGStmtOpenMP.cpp b/clang/lib/CodeGen/CGStmtOpenMP.cpp index f37ac549d10a..e6d504bcdeca 100644 --- a/clang/lib/CodeGen/CGStmtOpenMP.cpp +++ b/clang/lib/CodeGen/CGStmtOpenMP.cpp @@ -350,7 +350,8 @@ void CodeGenFunction::GenerateOpenMPCapturedVars( LValue DstLV = MakeAddrLValue(DstAddr, Ctx.getUIntPtrType()); llvm::Value *SrcAddrVal = EmitScalarConversion( - DstAddr.getPointer(), Ctx.getPointerType(Ctx.getUIntPtrType()), + DstAddr.emitRawPointer(*this), + Ctx.getPointerType(Ctx.getUIntPtrType()), Ctx.getPointerType(CurField->getType()), CurCap->getLocation()); LValue SrcLV = MakeNaturalAlignAddrLValue(SrcAddrVal, CurField->getType()); @@ -364,7 +365,8 @@ void CodeGenFunction::GenerateOpenMPCapturedVars( CapturedVars.push_back(CV); } else { assert(CurCap->capturesVariable() && "Expected capture by reference."); - CapturedVars.push_back(EmitLValue(*I).getAddress(*this).getPointer()); + CapturedVars.push_back( + EmitLValue(*I).getAddress(*this).emitRawPointer(*this)); } } } @@ -375,8 +377,9 @@ static Address castValueFromUintptr(CodeGenFunction &CGF, SourceLocation Loc, ASTContext &Ctx = CGF.getContext(); llvm::Value *CastedPtr = CGF.EmitScalarConversion( - AddrLV.getAddress(CGF).getPointer(), Ctx.getUIntPtrType(), + AddrLV.getAddress(CGF).emitRawPointer(CGF), Ctx.getUIntPtrType(), Ctx.getPointerType(DstType), Loc); + // FIXME: should the pointee type (DstType) be passed? Address TmpAddr = CGF.MakeNaturalAlignAddrLValue(CastedPtr, DstType).getAddress(CGF); return TmpAddr; @@ -702,8 +705,8 @@ void CodeGenFunction::EmitOMPAggregateAssign( llvm::Value *NumElements = emitArrayLength(ArrayTy, ElementTy, DestAddr); SrcAddr = SrcAddr.withElementType(DestAddr.getElementType()); - llvm::Value *SrcBegin = SrcAddr.getPointer(); - llvm::Value *DestBegin = DestAddr.getPointer(); + llvm::Value *SrcBegin = SrcAddr.emitRawPointer(*this); + llvm::Value *DestBegin = DestAddr.emitRawPointer(*this); // Cast from pointer to array type to pointer to single element. llvm::Value *DestEnd = Builder.CreateInBoundsGEP(DestAddr.getElementType(), DestBegin, NumElements); @@ -1007,10 +1010,10 @@ bool CodeGenFunction::EmitOMPCopyinClause(const OMPExecutableDirective &D) { CopyBegin = createBasicBlock("copyin.not.master"); CopyEnd = createBasicBlock("copyin.not.master.end"); // TODO: Avoid ptrtoint conversion. - auto *MasterAddrInt = - Builder.CreatePtrToInt(MasterAddr.getPointer(), CGM.IntPtrTy); - auto *PrivateAddrInt = - Builder.CreatePtrToInt(PrivateAddr.getPointer(), CGM.IntPtrTy); + auto *MasterAddrInt = Builder.CreatePtrToInt( + MasterAddr.emitRawPointer(*this), CGM.IntPtrTy); + auto *PrivateAddrInt = Builder.CreatePtrToInt( + PrivateAddr.emitRawPointer(*this), CGM.IntPtrTy); Builder.CreateCondBr( Builder.CreateICmpNE(MasterAddrInt, PrivateAddrInt), CopyBegin, CopyEnd); @@ -1666,7 +1669,7 @@ Address CodeGenFunction::OMPBuilderCBHelpers::getAddrOfThreadPrivate( llvm::Type *VarTy = VDAddr.getElementType(); llvm::Value *Data = - CGF.Builder.CreatePointerCast(VDAddr.getPointer(), CGM.Int8PtrTy); + CGF.Builder.CreatePointerCast(VDAddr.emitRawPointer(CGF), CGM.Int8PtrTy); llvm::ConstantInt *Size = CGM.getSize(CGM.GetTargetTypeStoreSize(VarTy)); std::string Suffix = getNameWithSeparators({"cache", ""}); llvm::Twine CacheName = Twine(CGM.getMangledName(VD)).concat(Suffix); @@ -2045,7 +2048,7 @@ void CodeGenFunction::EmitOMPCanonicalLoop(const OMPCanonicalLoop *S) { ->getParam(0) ->getType() .getNonReferenceType(); - Address CountAddr = CreateMemTemp(LogicalTy, ".count.addr"); + RawAddress CountAddr = CreateMemTemp(LogicalTy, ".count.addr"); emitCapturedStmtCall(*this, DistanceClosure, {CountAddr.getPointer()}); llvm::Value *DistVal = Builder.CreateLoad(CountAddr, ".count"); @@ -2061,7 +2064,7 @@ void CodeGenFunction::EmitOMPCanonicalLoop(const OMPCanonicalLoop *S) { LValue LCVal = EmitLValue(LoopVarRef); Address LoopVarAddress = LCVal.getAddress(*this); emitCapturedStmtCall(*this, LoopVarClosure, - {LoopVarAddress.getPointer(), IndVar}); + {LoopVarAddress.emitRawPointer(*this), IndVar}); RunCleanupsScope BodyScope(*this); EmitStmt(BodyStmt); @@ -4795,7 +4798,7 @@ void CodeGenFunction::EmitOMPTaskBasedDirective( ParamTypes.push_back(PrivatesPtr->getType()); for (const Expr *E : Data.PrivateVars) { const auto *VD = cast(cast(E)->getDecl()); - Address PrivatePtr = CGF.CreateMemTemp( + RawAddress PrivatePtr = CGF.CreateMemTemp( CGF.getContext().getPointerType(E->getType()), ".priv.ptr.addr"); PrivatePtrs.emplace_back(VD, PrivatePtr); CallArgs.push_back(PrivatePtr.getPointer()); @@ -4803,7 +4806,7 @@ void CodeGenFunction::EmitOMPTaskBasedDirective( } for (const Expr *E : Data.FirstprivateVars) { const auto *VD = cast(cast(E)->getDecl()); - Address PrivatePtr = + RawAddress PrivatePtr = CGF.CreateMemTemp(CGF.getContext().getPointerType(E->getType()), ".firstpriv.ptr.addr"); PrivatePtrs.emplace_back(VD, PrivatePtr); @@ -4813,7 +4816,7 @@ void CodeGenFunction::EmitOMPTaskBasedDirective( } for (const Expr *E : Data.LastprivateVars) { const auto *VD = cast(cast(E)->getDecl()); - Address PrivatePtr = + RawAddress PrivatePtr = CGF.CreateMemTemp(CGF.getContext().getPointerType(E->getType()), ".lastpriv.ptr.addr"); PrivatePtrs.emplace_back(VD, PrivatePtr); @@ -4826,7 +4829,7 @@ void CodeGenFunction::EmitOMPTaskBasedDirective( Ty = CGF.getContext().getPointerType(Ty); if (isAllocatableDecl(VD)) Ty = CGF.getContext().getPointerType(Ty); - Address PrivatePtr = CGF.CreateMemTemp( + RawAddress PrivatePtr = CGF.CreateMemTemp( CGF.getContext().getPointerType(Ty), ".local.ptr.addr"); auto Result = UntiedLocalVars.insert( std::make_pair(VD, std::make_pair(PrivatePtr, Address::invalid()))); @@ -4859,7 +4862,7 @@ void CodeGenFunction::EmitOMPTaskBasedDirective( if (auto *DI = CGF.getDebugInfo()) if (CGF.CGM.getCodeGenOpts().hasReducedDebugInfo()) (void)DI->EmitDeclareOfAutoVariable( - Pair.first, Pair.second.getPointer(), CGF.Builder, + Pair.first, Pair.second.getBasePointer(), CGF.Builder, /*UsePointerValue*/ true); } // Adjust mapping for internal locals by mapping actual memory instead of @@ -4912,14 +4915,14 @@ void CodeGenFunction::EmitOMPTaskBasedDirective( RedCG, Cnt); Address Replacement = CGF.CGM.getOpenMPRuntime().getTaskReductionItem( CGF, S.getBeginLoc(), ReductionsPtr, RedCG.getSharedLValue(Cnt)); - Replacement = - Address(CGF.EmitScalarConversion( - Replacement.getPointer(), CGF.getContext().VoidPtrTy, - CGF.getContext().getPointerType( - Data.ReductionCopies[Cnt]->getType()), - Data.ReductionCopies[Cnt]->getExprLoc()), - CGF.ConvertTypeForMem(Data.ReductionCopies[Cnt]->getType()), - Replacement.getAlignment()); + Replacement = Address( + CGF.EmitScalarConversion(Replacement.emitRawPointer(CGF), + CGF.getContext().VoidPtrTy, + CGF.getContext().getPointerType( + Data.ReductionCopies[Cnt]->getType()), + Data.ReductionCopies[Cnt]->getExprLoc()), + CGF.ConvertTypeForMem(Data.ReductionCopies[Cnt]->getType()), + Replacement.getAlignment()); Replacement = RedCG.adjustPrivateAddress(CGF, Cnt, Replacement); Scope.addPrivate(RedCG.getBaseDecl(Cnt), Replacement); } @@ -4970,7 +4973,7 @@ void CodeGenFunction::EmitOMPTaskBasedDirective( CGF, S.getBeginLoc(), ReductionsPtr, RedCG.getSharedLValue(Cnt)); Replacement = Address( CGF.EmitScalarConversion( - Replacement.getPointer(), CGF.getContext().VoidPtrTy, + Replacement.emitRawPointer(CGF), CGF.getContext().VoidPtrTy, CGF.getContext().getPointerType(InRedPrivs[Cnt]->getType()), InRedPrivs[Cnt]->getExprLoc()), CGF.ConvertTypeForMem(InRedPrivs[Cnt]->getType()), @@ -5089,7 +5092,7 @@ void CodeGenFunction::EmitOMPTargetTaskBasedDirective( // If there is no user-defined mapper, the mapper array will be nullptr. In // this case, we don't need to privatize it. if (!isa_and_nonnull( - InputInfo.MappersArray.getPointer())) { + InputInfo.MappersArray.emitRawPointer(*this))) { MVD = createImplicitFirstprivateForType( getContext(), Data, BaseAndPointerAndMapperType, CD, S.getBeginLoc()); TargetScope.addPrivate(MVD, InputInfo.MappersArray); @@ -5115,7 +5118,7 @@ void CodeGenFunction::EmitOMPTargetTaskBasedDirective( ParamTypes.push_back(PrivatesPtr->getType()); for (const Expr *E : Data.FirstprivateVars) { const auto *VD = cast(cast(E)->getDecl()); - Address PrivatePtr = + RawAddress PrivatePtr = CGF.CreateMemTemp(CGF.getContext().getPointerType(E->getType()), ".firstpriv.ptr.addr"); PrivatePtrs.emplace_back(VD, PrivatePtr); @@ -5194,14 +5197,14 @@ void CodeGenFunction::processInReduction(const OMPExecutableDirective &S, RedCG, Cnt); Address Replacement = CGF.CGM.getOpenMPRuntime().getTaskReductionItem( CGF, S.getBeginLoc(), ReductionsPtr, RedCG.getSharedLValue(Cnt)); - Replacement = - Address(CGF.EmitScalarConversion( - Replacement.getPointer(), CGF.getContext().VoidPtrTy, - CGF.getContext().getPointerType( - Data.ReductionCopies[Cnt]->getType()), - Data.ReductionCopies[Cnt]->getExprLoc()), - CGF.ConvertTypeForMem(Data.ReductionCopies[Cnt]->getType()), - Replacement.getAlignment()); + Replacement = Address( + CGF.EmitScalarConversion(Replacement.emitRawPointer(CGF), + CGF.getContext().VoidPtrTy, + CGF.getContext().getPointerType( + Data.ReductionCopies[Cnt]->getType()), + Data.ReductionCopies[Cnt]->getExprLoc()), + CGF.ConvertTypeForMem(Data.ReductionCopies[Cnt]->getType()), + Replacement.getAlignment()); Replacement = RedCG.adjustPrivateAddress(CGF, Cnt, Replacement); Scope.addPrivate(RedCG.getBaseDecl(Cnt), Replacement); } @@ -5247,7 +5250,7 @@ void CodeGenFunction::processInReduction(const OMPExecutableDirective &S, CGF, S.getBeginLoc(), ReductionsPtr, RedCG.getSharedLValue(Cnt)); Replacement = Address( CGF.EmitScalarConversion( - Replacement.getPointer(), CGF.getContext().VoidPtrTy, + Replacement.emitRawPointer(CGF), CGF.getContext().VoidPtrTy, CGF.getContext().getPointerType(InRedPrivs[Cnt]->getType()), InRedPrivs[Cnt]->getExprLoc()), CGF.ConvertTypeForMem(InRedPrivs[Cnt]->getType()), @@ -5394,7 +5397,7 @@ void CodeGenFunction::EmitOMPDepobjDirective(const OMPDepobjDirective &S) { Dependencies.DepExprs.append(DC->varlist_begin(), DC->varlist_end()); Address DepAddr = CGM.getOpenMPRuntime().emitDepobjDependClause( *this, Dependencies, DC->getBeginLoc()); - EmitStoreOfScalar(DepAddr.getPointer(), DOLVal); + EmitStoreOfScalar(DepAddr.emitRawPointer(*this), DOLVal); return; } if (const auto *DC = S.getSingleClause()) { @@ -6471,21 +6474,21 @@ static void emitOMPAtomicCompareExpr( D->getType()->hasSignedIntegerRepresentation()); llvm::OpenMPIRBuilder::AtomicOpValue XOpVal{ - XAddr.getPointer(), XAddr.getElementType(), + XAddr.emitRawPointer(CGF), XAddr.getElementType(), X->getType()->hasSignedIntegerRepresentation(), X->getType().isVolatileQualified()}; llvm::OpenMPIRBuilder::AtomicOpValue VOpVal, ROpVal; if (V) { LValue LV = CGF.EmitLValue(V); Address Addr = LV.getAddress(CGF); - VOpVal = {Addr.getPointer(), Addr.getElementType(), + VOpVal = {Addr.emitRawPointer(CGF), Addr.getElementType(), V->getType()->hasSignedIntegerRepresentation(), V->getType().isVolatileQualified()}; } if (R) { LValue LV = CGF.EmitLValue(R); Address Addr = LV.getAddress(CGF); - ROpVal = {Addr.getPointer(), Addr.getElementType(), + ROpVal = {Addr.emitRawPointer(CGF), Addr.getElementType(), R->getType()->hasSignedIntegerRepresentation(), R->getType().isVolatileQualified()}; } @@ -7029,7 +7032,7 @@ void CodeGenFunction::EmitOMPInteropDirective(const OMPInteropDirective &S) { std::tie(NumDependences, DependenciesArray) = CGM.getOpenMPRuntime().emitDependClause(*this, Data.Dependences, S.getBeginLoc()); - DependenceList = DependenciesArray.getPointer(); + DependenceList = DependenciesArray.emitRawPointer(*this); } Data.HasNowaitClause = S.hasClausesOfKind(); diff --git a/clang/lib/CodeGen/CGVTables.cpp b/clang/lib/CodeGen/CGVTables.cpp index 8dee3f74b44b..862369ae009f 100644 --- a/clang/lib/CodeGen/CGVTables.cpp +++ b/clang/lib/CodeGen/CGVTables.cpp @@ -201,14 +201,13 @@ CodeGenFunction::GenerateVarArgsThunk(llvm::Function *Fn, // Find the first store of "this", which will be to the alloca associated // with "this". - Address ThisPtr = - Address(&*AI, ConvertTypeForMem(MD->getFunctionObjectParameterType()), - CGM.getClassPointerAlignment(MD->getParent())); + Address ThisPtr = makeNaturalAddressForPointer( + &*AI, MD->getFunctionObjectParameterType(), + CGM.getClassPointerAlignment(MD->getParent())); llvm::BasicBlock *EntryBB = &Fn->front(); llvm::BasicBlock::iterator ThisStore = llvm::find_if(*EntryBB, [&](llvm::Instruction &I) { - return isa(I) && - I.getOperand(0) == ThisPtr.getPointer(); + return isa(I) && I.getOperand(0) == &*AI; }); assert(ThisStore != EntryBB->end() && "Store of this should be in entry block?"); diff --git a/clang/lib/CodeGen/CGValue.h b/clang/lib/CodeGen/CGValue.h index 1e6f67250583..cc9ad10ae596 100644 --- a/clang/lib/CodeGen/CGValue.h +++ b/clang/lib/CodeGen/CGValue.h @@ -14,12 +14,13 @@ #ifndef LLVM_CLANG_LIB_CODEGEN_CGVALUE_H #define LLVM_CLANG_LIB_CODEGEN_CGVALUE_H +#include "Address.h" +#include "CodeGenTBAA.h" +#include "EHScopeStack.h" #include "clang/AST/ASTContext.h" #include "clang/AST/Type.h" -#include "llvm/IR/Value.h" #include "llvm/IR/Type.h" -#include "Address.h" -#include "CodeGenTBAA.h" +#include "llvm/IR/Value.h" namespace llvm { class Constant; @@ -28,57 +29,64 @@ namespace llvm { namespace clang { namespace CodeGen { - class AggValueSlot; - class CodeGenFunction; - struct CGBitFieldInfo; +class AggValueSlot; +class CGBuilderTy; +class CodeGenFunction; +struct CGBitFieldInfo; /// RValue - This trivial value class is used to represent the result of an /// expression that is evaluated. It can be one of three things: either a /// simple LLVM SSA value, a pair of SSA values for complex numbers, or the /// address of an aggregate value in memory. class RValue { - enum Flavor { Scalar, Complex, Aggregate }; + friend struct DominatingValue; - // The shift to make to an aggregate's alignment to make it look - // like a pointer. - enum { AggAlignShift = 4 }; + enum FlavorEnum { Scalar, Complex, Aggregate }; - // Stores first value and flavor. - llvm::PointerIntPair V1; - // Stores second value and volatility. - llvm::PointerIntPair V2; - // Stores element type for aggregate values. - llvm::Type *ElementType; + union { + // Stores first and second value. + struct { + llvm::Value *first; + llvm::Value *second; + } Vals; + + // Stores aggregate address. + Address AggregateAddr; + }; + + unsigned IsVolatile : 1; + unsigned Flavor : 2; public: - bool isScalar() const { return V1.getInt() == Scalar; } - bool isComplex() const { return V1.getInt() == Complex; } - bool isAggregate() const { return V1.getInt() == Aggregate; } + RValue() : Vals{nullptr, nullptr}, Flavor(Scalar) {} + + bool isScalar() const { return Flavor == Scalar; } + bool isComplex() const { return Flavor == Complex; } + bool isAggregate() const { return Flavor == Aggregate; } - bool isVolatileQualified() const { return V2.getInt(); } + bool isVolatileQualified() const { return IsVolatile; } /// getScalarVal() - Return the Value* of this scalar value. llvm::Value *getScalarVal() const { assert(isScalar() && "Not a scalar!"); - return V1.getPointer(); + return Vals.first; } /// getComplexVal - Return the real/imag components of this complex value. /// std::pair getComplexVal() const { - return std::make_pair(V1.getPointer(), V2.getPointer()); + return std::make_pair(Vals.first, Vals.second); } /// getAggregateAddr() - Return the Value* of the address of the aggregate. Address getAggregateAddress() const { assert(isAggregate() && "Not an aggregate!"); - auto align = reinterpret_cast(V2.getPointer()) >> AggAlignShift; - return Address( - V1.getPointer(), ElementType, CharUnits::fromQuantity(align)); + return AggregateAddr; } - llvm::Value *getAggregatePointer() const { - assert(isAggregate() && "Not an aggregate!"); - return V1.getPointer(); + + llvm::Value *getAggregatePointer(QualType PointeeType, + CodeGenFunction &CGF) const { + return getAggregateAddress().getBasePointer(); } static RValue getIgnored() { @@ -88,17 +96,19 @@ public: static RValue get(llvm::Value *V) { RValue ER; - ER.V1.setPointer(V); - ER.V1.setInt(Scalar); - ER.V2.setInt(false); + ER.Vals.first = V; + ER.Flavor = Scalar; + ER.IsVolatile = false; return ER; } + static RValue get(Address Addr, CodeGenFunction &CGF) { + return RValue::get(Addr.emitRawPointer(CGF)); + } static RValue getComplex(llvm::Value *V1, llvm::Value *V2) { RValue ER; - ER.V1.setPointer(V1); - ER.V2.setPointer(V2); - ER.V1.setInt(Complex); - ER.V2.setInt(false); + ER.Vals = {V1, V2}; + ER.Flavor = Complex; + ER.IsVolatile = false; return ER; } static RValue getComplex(const std::pair &C) { @@ -107,15 +117,15 @@ public: // FIXME: Aggregate rvalues need to retain information about whether they are // volatile or not. Remove default to find all places that probably get this // wrong. + + /// Convert an Address to an RValue. If the Address is not + /// signed, create an RValue using the unsigned address. Otherwise, resign the + /// address using the provided type. static RValue getAggregate(Address addr, bool isVolatile = false) { RValue ER; - ER.V1.setPointer(addr.getPointer()); - ER.V1.setInt(Aggregate); - ER.ElementType = addr.getElementType(); - - auto align = static_cast(addr.getAlignment().getQuantity()); - ER.V2.setPointer(reinterpret_cast(align << AggAlignShift)); - ER.V2.setInt(isVolatile); + ER.AggregateAddr = addr; + ER.Flavor = Aggregate; + ER.IsVolatile = isVolatile; return ER; } }; @@ -178,8 +188,10 @@ class LValue { MatrixElt // This is a matrix element, use getVector* } LVType; - llvm::Value *V; - llvm::Type *ElementType; + union { + Address Addr = Address::invalid(); + llvm::Value *V; + }; union { // Index into a vector subscript: V[i] @@ -197,10 +209,6 @@ class LValue { // 'const' is unused here Qualifiers Quals; - // The alignment to use when accessing this lvalue. (For vector elements, - // this is the alignment of the whole vector.) - unsigned Alignment; - // objective-c's ivar bool Ivar:1; @@ -234,23 +242,19 @@ class LValue { Expr *BaseIvarExp; private: - void Initialize(QualType Type, Qualifiers Quals, CharUnits Alignment, + void Initialize(QualType Type, Qualifiers Quals, Address Addr, LValueBaseInfo BaseInfo, TBAAAccessInfo TBAAInfo) { - assert((!Alignment.isZero() || Type->isIncompleteType()) && - "initializing l-value with zero alignment!"); - if (isGlobalReg()) - assert(ElementType == nullptr && "Global reg does not store elem type"); - else - assert(ElementType != nullptr && "Must have elem type"); - this->Type = Type; this->Quals = Quals; const unsigned MaxAlign = 1U << 31; - this->Alignment = Alignment.getQuantity() <= MaxAlign - ? Alignment.getQuantity() - : MaxAlign; - assert(this->Alignment == Alignment.getQuantity() && - "Alignment exceeds allowed max!"); + CharUnits Alignment = Addr.getAlignment(); + assert((isGlobalReg() || !Alignment.isZero() || Type->isIncompleteType()) && + "initializing l-value with zero alignment!"); + if (Alignment.getQuantity() > MaxAlign) { + assert(false && "Alignment exceeds allowed max!"); + Alignment = CharUnits::fromQuantity(MaxAlign); + } + this->Addr = Addr; this->BaseInfo = BaseInfo; this->TBAAInfo = TBAAInfo; @@ -259,9 +263,20 @@ private: this->ImpreciseLifetime = false; this->Nontemporal = false; this->ThreadLocalRef = false; + this->IsKnownNonNull = false; this->BaseIvarExp = nullptr; } + void initializeSimpleLValue(Address Addr, QualType Type, + LValueBaseInfo BaseInfo, TBAAAccessInfo TBAAInfo, + ASTContext &Context) { + Qualifiers QS = Type.getQualifiers(); + QS.setObjCGCAttr(Context.getObjCGCAttrKind(Type)); + LVType = Simple; + Initialize(Type, QS, Addr, BaseInfo, TBAAInfo); + assert(Addr.getBasePointer()->getType()->isPointerTy()); + } + public: bool isSimple() const { return LVType == Simple; } bool isVectorElt() const { return LVType == VectorElt; } @@ -328,8 +343,8 @@ public: LangAS getAddressSpace() const { return Quals.getAddressSpace(); } - CharUnits getAlignment() const { return CharUnits::fromQuantity(Alignment); } - void setAlignment(CharUnits A) { Alignment = A.getQuantity(); } + CharUnits getAlignment() const { return Addr.getAlignment(); } + void setAlignment(CharUnits A) { Addr.setAlignment(A); } LValueBaseInfo getBaseInfo() const { return BaseInfo; } void setBaseInfo(LValueBaseInfo Info) { BaseInfo = Info; } @@ -345,28 +360,32 @@ public: // simple lvalue llvm::Value *getPointer(CodeGenFunction &CGF) const { assert(isSimple()); - return V; + return Addr.getBasePointer(); } - Address getAddress(CodeGenFunction &CGF) const { - return Address(getPointer(CGF), ElementType, getAlignment(), - isKnownNonNull()); - } - void setAddress(Address address) { + llvm::Value *emitRawPointer(CodeGenFunction &CGF) const { assert(isSimple()); - V = address.getPointer(); - ElementType = address.getElementType(); - Alignment = address.getAlignment().getQuantity(); - IsKnownNonNull = address.isKnownNonNull(); + return Addr.isValid() ? Addr.emitRawPointer(CGF) : nullptr; } + Address getAddress(CodeGenFunction &CGF) const { + // FIXME: remove parameter. + return Addr; + } + + void setAddress(Address address) { Addr = address; } + // vector elt lvalue Address getVectorAddress() const { - return Address(getVectorPointer(), ElementType, getAlignment(), - (KnownNonNull_t)isKnownNonNull()); + assert(isVectorElt()); + return Addr; + } + llvm::Value *getRawVectorPointer(CodeGenFunction &CGF) const { + assert(isVectorElt()); + return Addr.emitRawPointer(CGF); } llvm::Value *getVectorPointer() const { assert(isVectorElt()); - return V; + return Addr.getBasePointer(); } llvm::Value *getVectorIdx() const { assert(isVectorElt()); @@ -374,12 +393,12 @@ public: } Address getMatrixAddress() const { - return Address(getMatrixPointer(), ElementType, getAlignment(), - (KnownNonNull_t)isKnownNonNull()); + assert(isMatrixElt()); + return Addr; } llvm::Value *getMatrixPointer() const { assert(isMatrixElt()); - return V; + return Addr.getBasePointer(); } llvm::Value *getMatrixIdx() const { assert(isMatrixElt()); @@ -388,12 +407,12 @@ public: // extended vector elements. Address getExtVectorAddress() const { - return Address(getExtVectorPointer(), ElementType, getAlignment(), - (KnownNonNull_t)isKnownNonNull()); + assert(isExtVectorElt()); + return Addr; } - llvm::Value *getExtVectorPointer() const { + llvm::Value *getRawExtVectorPointer(CodeGenFunction &CGF) const { assert(isExtVectorElt()); - return V; + return Addr.emitRawPointer(CGF); } llvm::Constant *getExtVectorElts() const { assert(isExtVectorElt()); @@ -402,10 +421,14 @@ public: // bitfield lvalue Address getBitFieldAddress() const { - return Address(getBitFieldPointer(), ElementType, getAlignment(), - (KnownNonNull_t)isKnownNonNull()); + assert(isBitField()); + return Addr; + } + llvm::Value *getRawBitFieldPointer(CodeGenFunction &CGF) const { + assert(isBitField()); + return Addr.emitRawPointer(CGF); } - llvm::Value *getBitFieldPointer() const { assert(isBitField()); return V; } + const CGBitFieldInfo &getBitFieldInfo() const { assert(isBitField()); return *BitFieldInfo; @@ -414,18 +437,13 @@ public: // global register lvalue llvm::Value *getGlobalReg() const { assert(isGlobalReg()); return V; } - static LValue MakeAddr(Address address, QualType type, ASTContext &Context, + static LValue MakeAddr(Address Addr, QualType type, ASTContext &Context, LValueBaseInfo BaseInfo, TBAAAccessInfo TBAAInfo) { - Qualifiers qs = type.getQualifiers(); - qs.setObjCGCAttr(Context.getObjCGCAttrKind(type)); - LValue R; R.LVType = Simple; - assert(address.getPointer()->getType()->isPointerTy()); - R.V = address.getPointer(); - R.ElementType = address.getElementType(); - R.IsKnownNonNull = address.isKnownNonNull(); - R.Initialize(type, qs, address.getAlignment(), BaseInfo, TBAAInfo); + R.initializeSimpleLValue(Addr, type, BaseInfo, TBAAInfo, Context); + R.Addr = Addr; + assert(Addr.getType()->isPointerTy()); return R; } @@ -434,26 +452,18 @@ public: TBAAAccessInfo TBAAInfo) { LValue R; R.LVType = VectorElt; - R.V = vecAddress.getPointer(); - R.ElementType = vecAddress.getElementType(); R.VectorIdx = Idx; - R.IsKnownNonNull = vecAddress.isKnownNonNull(); - R.Initialize(type, type.getQualifiers(), vecAddress.getAlignment(), - BaseInfo, TBAAInfo); + R.Initialize(type, type.getQualifiers(), vecAddress, BaseInfo, TBAAInfo); return R; } - static LValue MakeExtVectorElt(Address vecAddress, llvm::Constant *Elts, + static LValue MakeExtVectorElt(Address Addr, llvm::Constant *Elts, QualType type, LValueBaseInfo BaseInfo, TBAAAccessInfo TBAAInfo) { LValue R; R.LVType = ExtVectorElt; - R.V = vecAddress.getPointer(); - R.ElementType = vecAddress.getElementType(); R.VectorElts = Elts; - R.IsKnownNonNull = vecAddress.isKnownNonNull(); - R.Initialize(type, type.getQualifiers(), vecAddress.getAlignment(), - BaseInfo, TBAAInfo); + R.Initialize(type, type.getQualifiers(), Addr, BaseInfo, TBAAInfo); return R; } @@ -468,12 +478,8 @@ public: TBAAAccessInfo TBAAInfo) { LValue R; R.LVType = BitField; - R.V = Addr.getPointer(); - R.ElementType = Addr.getElementType(); R.BitFieldInfo = &Info; - R.IsKnownNonNull = Addr.isKnownNonNull(); - R.Initialize(type, type.getQualifiers(), Addr.getAlignment(), BaseInfo, - TBAAInfo); + R.Initialize(type, type.getQualifiers(), Addr, BaseInfo, TBAAInfo); return R; } @@ -481,11 +487,9 @@ public: QualType type) { LValue R; R.LVType = GlobalReg; - R.V = V; - R.ElementType = nullptr; - R.IsKnownNonNull = true; - R.Initialize(type, type.getQualifiers(), alignment, + R.Initialize(type, type.getQualifiers(), Address::invalid(), LValueBaseInfo(AlignmentSource::Decl), TBAAAccessInfo()); + R.V = V; return R; } @@ -494,12 +498,8 @@ public: TBAAAccessInfo TBAAInfo) { LValue R; R.LVType = MatrixElt; - R.V = matAddress.getPointer(); - R.ElementType = matAddress.getElementType(); R.VectorIdx = Idx; - R.IsKnownNonNull = matAddress.isKnownNonNull(); - R.Initialize(type, type.getQualifiers(), matAddress.getAlignment(), - BaseInfo, TBAAInfo); + R.Initialize(type, type.getQualifiers(), matAddress, BaseInfo, TBAAInfo); return R; } @@ -643,17 +643,17 @@ public: return NeedsGCBarriers_t(ObjCGCFlag); } - llvm::Value *getPointer() const { - return Addr.getPointer(); + llvm::Value *getPointer(QualType PointeeTy, CodeGenFunction &CGF) const; + + llvm::Value *emitRawPointer(CodeGenFunction &CGF) const { + return Addr.isValid() ? Addr.emitRawPointer(CGF) : nullptr; } Address getAddress() const { return Addr; } - bool isIgnored() const { - return !Addr.isValid(); - } + bool isIgnored() const { return !Addr.isValid(); } CharUnits getAlignment() const { return Addr.getAlignment(); diff --git a/clang/lib/CodeGen/CodeGenFunction.cpp b/clang/lib/CodeGen/CodeGenFunction.cpp index f2ebaf767452..44103884940f 100644 --- a/clang/lib/CodeGen/CodeGenFunction.cpp +++ b/clang/lib/CodeGen/CodeGenFunction.cpp @@ -193,26 +193,35 @@ CodeGenFunction::CGFPOptionsRAII::~CGFPOptionsRAII() { CGF.Builder.setDefaultConstrainedRounding(OldRounding); } -LValue CodeGenFunction::MakeNaturalAlignAddrLValue(llvm::Value *V, QualType T) { +static LValue MakeNaturalAlignAddrLValue(llvm::Value *V, QualType T, + bool ForPointeeType, + CodeGenFunction &CGF) { LValueBaseInfo BaseInfo; TBAAAccessInfo TBAAInfo; - CharUnits Alignment = CGM.getNaturalTypeAlignment(T, &BaseInfo, &TBAAInfo); - Address Addr(V, ConvertTypeForMem(T), Alignment); - return LValue::MakeAddr(Addr, T, getContext(), BaseInfo, TBAAInfo); + CharUnits Alignment = + CGF.CGM.getNaturalTypeAlignment(T, &BaseInfo, &TBAAInfo, ForPointeeType); + Address Addr = Address(V, CGF.ConvertTypeForMem(T), Alignment); + return CGF.MakeAddrLValue(Addr, T, BaseInfo, TBAAInfo); +} + +LValue CodeGenFunction::MakeNaturalAlignAddrLValue(llvm::Value *V, QualType T) { + return ::MakeNaturalAlignAddrLValue(V, T, /*ForPointeeType*/ false, *this); } -/// Given a value of type T* that may not be to a complete object, -/// construct an l-value with the natural pointee alignment of T. LValue CodeGenFunction::MakeNaturalAlignPointeeAddrLValue(llvm::Value *V, QualType T) { - LValueBaseInfo BaseInfo; - TBAAAccessInfo TBAAInfo; - CharUnits Align = CGM.getNaturalTypeAlignment(T, &BaseInfo, &TBAAInfo, - /* forPointeeType= */ true); - Address Addr(V, ConvertTypeForMem(T), Align); - return MakeAddrLValue(Addr, T, BaseInfo, TBAAInfo); + return ::MakeNaturalAlignAddrLValue(V, T, /*ForPointeeType*/ true, *this); +} + +LValue CodeGenFunction::MakeNaturalAlignRawAddrLValue(llvm::Value *V, + QualType T) { + return ::MakeNaturalAlignAddrLValue(V, T, /*ForPointeeType*/ false, *this); } +LValue CodeGenFunction::MakeNaturalAlignPointeeRawAddrLValue(llvm::Value *V, + QualType T) { + return ::MakeNaturalAlignAddrLValue(V, T, /*ForPointeeType*/ true, *this); +} llvm::Type *CodeGenFunction::ConvertTypeForMem(QualType T) { return CGM.getTypes().ConvertTypeForMem(T); @@ -525,7 +534,8 @@ void CodeGenFunction::FinishFunction(SourceLocation EndLoc) { ReturnBlock.getBlock()->eraseFromParent(); } if (ReturnValue.isValid()) { - auto *RetAlloca = dyn_cast(ReturnValue.getPointer()); + auto *RetAlloca = + dyn_cast(ReturnValue.emitRawPointer(*this)); if (RetAlloca && RetAlloca->use_empty()) { RetAlloca->eraseFromParent(); ReturnValue = Address::invalid(); @@ -1122,13 +1132,14 @@ void CodeGenFunction::StartFunction(GlobalDecl GD, QualType RetTy, auto AI = CurFn->arg_begin(); if (CurFnInfo->getReturnInfo().isSRetAfterThis()) ++AI; - ReturnValue = - Address(&*AI, ConvertType(RetTy), - CurFnInfo->getReturnInfo().getIndirectAlign(), KnownNonNull); + ReturnValue = makeNaturalAddressForPointer( + &*AI, RetTy, CurFnInfo->getReturnInfo().getIndirectAlign(), false, + nullptr, nullptr, KnownNonNull); if (!CurFnInfo->getReturnInfo().getIndirectByVal()) { - ReturnValuePointer = CreateDefaultAlignTempAlloca( - ReturnValue.getPointer()->getType(), "result.ptr"); - Builder.CreateStore(ReturnValue.getPointer(), ReturnValuePointer); + ReturnValuePointer = + CreateDefaultAlignTempAlloca(ReturnValue.getType(), "result.ptr"); + Builder.CreateStore(ReturnValue.emitRawPointer(*this), + ReturnValuePointer); } } else if (CurFnInfo->getReturnInfo().getKind() == ABIArgInfo::InAlloca && !hasScalarEvaluationKind(CurFnInfo->getReturnType())) { @@ -1189,8 +1200,9 @@ void CodeGenFunction::StartFunction(GlobalDecl GD, QualType RetTy, // or contains the address of the enclosing object). LValue ThisFieldLValue = EmitLValueForLambdaField(LambdaThisCaptureField); if (!LambdaThisCaptureField->getType()->isPointerType()) { - // If the enclosing object was captured by value, just use its address. - CXXThisValue = ThisFieldLValue.getAddress(*this).getPointer(); + // If the enclosing object was captured by value, just use its + // address. Sign this pointer. + CXXThisValue = ThisFieldLValue.getPointer(*this); } else { // Load the lvalue pointed to by the field, since '*this' was captured // by reference. @@ -2012,8 +2024,9 @@ static void emitNonZeroVLAInit(CodeGenFunction &CGF, QualType baseType, = llvm::ConstantInt::get(CGF.IntPtrTy, baseSize.getQuantity()); Address begin = dest.withElementType(CGF.Int8Ty); - llvm::Value *end = Builder.CreateInBoundsGEP( - begin.getElementType(), begin.getPointer(), sizeInChars, "vla.end"); + llvm::Value *end = Builder.CreateInBoundsGEP(begin.getElementType(), + begin.emitRawPointer(CGF), + sizeInChars, "vla.end"); llvm::BasicBlock *originBB = CGF.Builder.GetInsertBlock(); llvm::BasicBlock *loopBB = CGF.createBasicBlock("vla-init.loop"); @@ -2024,7 +2037,7 @@ static void emitNonZeroVLAInit(CodeGenFunction &CGF, QualType baseType, CGF.EmitBlock(loopBB); llvm::PHINode *cur = Builder.CreatePHI(begin.getType(), 2, "vla.cur"); - cur->addIncoming(begin.getPointer(), originBB); + cur->addIncoming(begin.emitRawPointer(CGF), originBB); CharUnits curAlign = dest.getAlignment().alignmentOfArrayElement(baseSize); @@ -2217,10 +2230,10 @@ llvm::Value *CodeGenFunction::emitArrayLength(const ArrayType *origArrayType, addr = addr.withElementType(baseType); } else { // Create the actual GEP. - addr = Address(Builder.CreateInBoundsGEP( - addr.getElementType(), addr.getPointer(), gepIndices, "array.begin"), - ConvertTypeForMem(eltType), - addr.getAlignment()); + addr = Address(Builder.CreateInBoundsGEP(addr.getElementType(), + addr.emitRawPointer(*this), + gepIndices, "array.begin"), + ConvertTypeForMem(eltType), addr.getAlignment()); } baseType = eltType; @@ -2561,7 +2574,7 @@ void CodeGenFunction::EmitVarAnnotations(const VarDecl *D, llvm::Value *V) { Address CodeGenFunction::EmitFieldAnnotations(const FieldDecl *D, Address Addr) { assert(D->hasAttr() && "no annotate attribute"); - llvm::Value *V = Addr.getPointer(); + llvm::Value *V = Addr.emitRawPointer(*this); llvm::Type *VTy = V->getType(); auto *PTy = dyn_cast(VTy); unsigned AS = PTy ? PTy->getAddressSpace() : 0; diff --git a/clang/lib/CodeGen/CodeGenFunction.h b/clang/lib/CodeGen/CodeGenFunction.h index e8f8aa601ed0..8dd6da5f85f1 100644 --- a/clang/lib/CodeGen/CodeGenFunction.h +++ b/clang/lib/CodeGen/CodeGenFunction.h @@ -151,6 +151,9 @@ struct DominatingLLVMValue { /// Answer whether the given value needs extra work to be saved. static bool needsSaving(llvm::Value *value) { + if (!value) + return false; + // If it's not an instruction, we don't need to save. if (!isa(value)) return false; @@ -177,21 +180,28 @@ template <> struct DominatingValue
{ typedef Address type; struct saved_type { - DominatingLLVMValue::saved_type SavedValue; + DominatingLLVMValue::saved_type BasePtr; llvm::Type *ElementType; CharUnits Alignment; + DominatingLLVMValue::saved_type Offset; + llvm::PointerType *EffectiveType; }; static bool needsSaving(type value) { - return DominatingLLVMValue::needsSaving(value.getPointer()); + if (DominatingLLVMValue::needsSaving(value.getBasePointer()) || + DominatingLLVMValue::needsSaving(value.getOffset())) + return true; + return false; } static saved_type save(CodeGenFunction &CGF, type value) { - return { DominatingLLVMValue::save(CGF, value.getPointer()), - value.getElementType(), value.getAlignment() }; + return {DominatingLLVMValue::save(CGF, value.getBasePointer()), + value.getElementType(), value.getAlignment(), + DominatingLLVMValue::save(CGF, value.getOffset()), value.getType()}; } static type restore(CodeGenFunction &CGF, saved_type value) { - return Address(DominatingLLVMValue::restore(CGF, value.SavedValue), - value.ElementType, value.Alignment); + return Address(DominatingLLVMValue::restore(CGF, value.BasePtr), + value.ElementType, value.Alignment, + DominatingLLVMValue::restore(CGF, value.Offset)); } }; @@ -201,14 +211,26 @@ template <> struct DominatingValue { class saved_type { enum Kind { ScalarLiteral, ScalarAddress, AggregateLiteral, AggregateAddress, ComplexAddress }; - - llvm::Value *Value; - llvm::Type *ElementType; + union { + struct { + DominatingLLVMValue::saved_type first, second; + } Vals; + DominatingValue
::saved_type AggregateAddr; + }; LLVM_PREFERRED_TYPE(Kind) unsigned K : 3; - unsigned Align : 29; - saved_type(llvm::Value *v, llvm::Type *e, Kind k, unsigned a = 0) - : Value(v), ElementType(e), K(k), Align(a) {} + unsigned IsVolatile : 1; + + saved_type(DominatingLLVMValue::saved_type Val1, unsigned K) + : Vals{Val1, DominatingLLVMValue::saved_type()}, K(K) {} + + saved_type(DominatingLLVMValue::saved_type Val1, + DominatingLLVMValue::saved_type Val2) + : Vals{Val1, Val2}, K(ComplexAddress) {} + + saved_type(DominatingValue
::saved_type AggregateAddr, + bool IsVolatile, unsigned K) + : AggregateAddr(AggregateAddr), K(K) {} public: static bool needsSaving(RValue value); @@ -659,7 +681,7 @@ public: llvm::Value *Size; public: - CallLifetimeEnd(Address addr, llvm::Value *size) + CallLifetimeEnd(RawAddress addr, llvm::Value *size) : Addr(addr.getPointer()), Size(size) {} void Emit(CodeGenFunction &CGF, Flags flags) override { @@ -684,7 +706,7 @@ public: }; /// i32s containing the indexes of the cleanup destinations. - Address NormalCleanupDest = Address::invalid(); + RawAddress NormalCleanupDest = RawAddress::invalid(); unsigned NextCleanupDestIndex = 1; @@ -819,10 +841,10 @@ public: template void pushCleanupAfterFullExpr(CleanupKind Kind, As... A) { if (!isInConditionalBranch()) - return pushCleanupAfterFullExprWithActiveFlag(Kind, Address::invalid(), - A...); + return pushCleanupAfterFullExprWithActiveFlag( + Kind, RawAddress::invalid(), A...); - Address ActiveFlag = createCleanupActiveFlag(); + RawAddress ActiveFlag = createCleanupActiveFlag(); assert(!DominatingValue
::needsSaving(ActiveFlag) && "cleanup active flag should never need saving"); @@ -835,7 +857,7 @@ public: template void pushCleanupAfterFullExprWithActiveFlag(CleanupKind Kind, - Address ActiveFlag, As... A) { + RawAddress ActiveFlag, As... A) { LifetimeExtendedCleanupHeader Header = {sizeof(T), Kind, ActiveFlag.isValid()}; @@ -850,7 +872,7 @@ public: new (Buffer) LifetimeExtendedCleanupHeader(Header); new (Buffer + sizeof(Header)) T(A...); if (Header.IsConditional) - new (Buffer + sizeof(Header) + sizeof(T)) Address(ActiveFlag); + new (Buffer + sizeof(Header) + sizeof(T)) RawAddress(ActiveFlag); } /// Set up the last cleanup that was pushed as a conditional @@ -859,8 +881,8 @@ public: initFullExprCleanupWithFlag(createCleanupActiveFlag()); } - void initFullExprCleanupWithFlag(Address ActiveFlag); - Address createCleanupActiveFlag(); + void initFullExprCleanupWithFlag(RawAddress ActiveFlag); + RawAddress createCleanupActiveFlag(); /// PushDestructorCleanup - Push a cleanup to call the /// complete-object destructor of an object of the given type at the @@ -1048,7 +1070,7 @@ public: QualType VarTy = LocalVD->getType(); if (VarTy->isReferenceType()) { Address Temp = CGF.CreateMemTemp(VarTy); - CGF.Builder.CreateStore(TempAddr.getPointer(), Temp); + CGF.Builder.CreateStore(TempAddr.emitRawPointer(CGF), Temp); TempAddr = Temp; } SavedTempAddresses.try_emplace(LocalVD, TempAddr); @@ -1243,10 +1265,12 @@ public: /// one branch or the other of a conditional expression. bool isInConditionalBranch() const { return OutermostConditional != nullptr; } - void setBeforeOutermostConditional(llvm::Value *value, Address addr) { + void setBeforeOutermostConditional(llvm::Value *value, Address addr, + CodeGenFunction &CGF) { assert(isInConditionalBranch()); llvm::BasicBlock *block = OutermostConditional->getStartingBlock(); - auto store = new llvm::StoreInst(value, addr.getPointer(), &block->back()); + auto store = + new llvm::StoreInst(value, addr.emitRawPointer(CGF), &block->back()); store->setAlignment(addr.getAlignment().getAsAlign()); } @@ -1601,7 +1625,7 @@ public: /// If \p StepV is null, the default increment is 1. void maybeUpdateMCDCTestVectorBitmap(const Expr *E) { if (isMCDCCoverageEnabled() && isBinaryLogicalOp(E)) { - PGO.emitMCDCTestVectorBitmapUpdate(Builder, E, MCDCCondBitmapAddr); + PGO.emitMCDCTestVectorBitmapUpdate(Builder, E, MCDCCondBitmapAddr, *this); PGO.setCurrentStmt(E); } } @@ -1609,7 +1633,7 @@ public: /// Update the MCDC temp value with the condition's evaluated result. void maybeUpdateMCDCCondBitmap(const Expr *E, llvm::Value *Val) { if (isMCDCCoverageEnabled()) { - PGO.emitMCDCCondBitmapUpdate(Builder, E, MCDCCondBitmapAddr, Val); + PGO.emitMCDCCondBitmapUpdate(Builder, E, MCDCCondBitmapAddr, Val, *this); PGO.setCurrentStmt(E); } } @@ -1704,7 +1728,7 @@ public: : CGF(CGF), OldCXXThisValue(CGF.CXXThisValue), OldCXXThisAlignment(CGF.CXXThisAlignment), SourceLocScope(E, CGF.CurSourceLocExprScope) { - CGF.CXXThisValue = CGF.CXXDefaultInitExprThis.getPointer(); + CGF.CXXThisValue = CGF.CXXDefaultInitExprThis.getBasePointer(); CGF.CXXThisAlignment = CGF.CXXDefaultInitExprThis.getAlignment(); } ~CXXDefaultInitExprScope() { @@ -2090,7 +2114,7 @@ public: llvm::Value *getExceptionFromSlot(); llvm::Value *getSelectorFromSlot(); - Address getNormalCleanupDestSlot(); + RawAddress getNormalCleanupDestSlot(); llvm::BasicBlock *getUnreachableBlock() { if (!UnreachableBlock) { @@ -2579,10 +2603,40 @@ public: // Helpers //===--------------------------------------------------------------------===// + Address mergeAddressesInConditionalExpr(Address LHS, Address RHS, + llvm::BasicBlock *LHSBlock, + llvm::BasicBlock *RHSBlock, + llvm::BasicBlock *MergeBlock, + QualType MergedType) { + Builder.SetInsertPoint(MergeBlock); + llvm::PHINode *PtrPhi = Builder.CreatePHI(LHS.getType(), 2, "cond"); + PtrPhi->addIncoming(LHS.getBasePointer(), LHSBlock); + PtrPhi->addIncoming(RHS.getBasePointer(), RHSBlock); + LHS.replaceBasePointer(PtrPhi); + LHS.setAlignment(std::min(LHS.getAlignment(), RHS.getAlignment())); + return LHS; + } + + /// Construct an address with the natural alignment of T. If a pointer to T + /// is expected to be signed, the pointer passed to this function must have + /// been signed, and the returned Address will have the pointer authentication + /// information needed to authenticate the signed pointer. + Address makeNaturalAddressForPointer( + llvm::Value *Ptr, QualType T, CharUnits Alignment = CharUnits::Zero(), + bool ForPointeeType = false, LValueBaseInfo *BaseInfo = nullptr, + TBAAAccessInfo *TBAAInfo = nullptr, + KnownNonNull_t IsKnownNonNull = NotKnownNonNull) { + if (Alignment.isZero()) + Alignment = + CGM.getNaturalTypeAlignment(T, BaseInfo, TBAAInfo, ForPointeeType); + return Address(Ptr, ConvertTypeForMem(T), Alignment, nullptr, + IsKnownNonNull); + } + LValue MakeAddrLValue(Address Addr, QualType T, AlignmentSource Source = AlignmentSource::Type) { - return LValue::MakeAddr(Addr, T, getContext(), LValueBaseInfo(Source), - CGM.getTBAAAccessInfo(T)); + return MakeAddrLValue(Addr, T, LValueBaseInfo(Source), + CGM.getTBAAAccessInfo(T)); } LValue MakeAddrLValue(Address Addr, QualType T, LValueBaseInfo BaseInfo, @@ -2592,6 +2646,14 @@ public: LValue MakeAddrLValue(llvm::Value *V, QualType T, CharUnits Alignment, AlignmentSource Source = AlignmentSource::Type) { + return MakeAddrLValue(makeNaturalAddressForPointer(V, T, Alignment), T, + LValueBaseInfo(Source), CGM.getTBAAAccessInfo(T)); + } + + /// Same as MakeAddrLValue above except that the pointer is known to be + /// unsigned. + LValue MakeRawAddrLValue(llvm::Value *V, QualType T, CharUnits Alignment, + AlignmentSource Source = AlignmentSource::Type) { Address Addr(V, ConvertTypeForMem(T), Alignment); return LValue::MakeAddr(Addr, T, getContext(), LValueBaseInfo(Source), CGM.getTBAAAccessInfo(T)); @@ -2604,9 +2666,18 @@ public: TBAAAccessInfo()); } + /// Given a value of type T* that may not be to a complete object, construct + /// an l-value with the natural pointee alignment of T. LValue MakeNaturalAlignPointeeAddrLValue(llvm::Value *V, QualType T); + LValue MakeNaturalAlignAddrLValue(llvm::Value *V, QualType T); + /// Same as MakeNaturalAlignPointeeAddrLValue except that the pointer is known + /// to be unsigned. + LValue MakeNaturalAlignPointeeRawAddrLValue(llvm::Value *V, QualType T); + + LValue MakeNaturalAlignRawAddrLValue(llvm::Value *V, QualType T); + Address EmitLoadOfReference(LValue RefLVal, LValueBaseInfo *PointeeBaseInfo = nullptr, TBAAAccessInfo *PointeeTBAAInfo = nullptr); @@ -2655,13 +2726,13 @@ public: /// more efficient if the caller knows that the address will not be exposed. llvm::AllocaInst *CreateTempAlloca(llvm::Type *Ty, const Twine &Name = "tmp", llvm::Value *ArraySize = nullptr); - Address CreateTempAlloca(llvm::Type *Ty, CharUnits align, - const Twine &Name = "tmp", - llvm::Value *ArraySize = nullptr, - Address *Alloca = nullptr); - Address CreateTempAllocaWithoutCast(llvm::Type *Ty, CharUnits align, - const Twine &Name = "tmp", - llvm::Value *ArraySize = nullptr); + RawAddress CreateTempAlloca(llvm::Type *Ty, CharUnits align, + const Twine &Name = "tmp", + llvm::Value *ArraySize = nullptr, + RawAddress *Alloca = nullptr); + RawAddress CreateTempAllocaWithoutCast(llvm::Type *Ty, CharUnits align, + const Twine &Name = "tmp", + llvm::Value *ArraySize = nullptr); /// CreateDefaultAlignedTempAlloca - This creates an alloca with the /// default ABI alignment of the given LLVM type. @@ -2673,8 +2744,8 @@ public: /// not hand this address off to arbitrary IRGen routines, and especially /// do not pass it as an argument to a function that might expect a /// properly ABI-aligned value. - Address CreateDefaultAlignTempAlloca(llvm::Type *Ty, - const Twine &Name = "tmp"); + RawAddress CreateDefaultAlignTempAlloca(llvm::Type *Ty, + const Twine &Name = "tmp"); /// CreateIRTemp - Create a temporary IR object of the given type, with /// appropriate alignment. This routine should only be used when an temporary @@ -2684,32 +2755,31 @@ public: /// /// That is, this is exactly equivalent to CreateMemTemp, but calling /// ConvertType instead of ConvertTypeForMem. - Address CreateIRTemp(QualType T, const Twine &Name = "tmp"); + RawAddress CreateIRTemp(QualType T, const Twine &Name = "tmp"); /// CreateMemTemp - Create a temporary memory object of the given type, with /// appropriate alignmen and cast it to the default address space. Returns /// the original alloca instruction by \p Alloca if it is not nullptr. - Address CreateMemTemp(QualType T, const Twine &Name = "tmp", - Address *Alloca = nullptr); - Address CreateMemTemp(QualType T, CharUnits Align, const Twine &Name = "tmp", - Address *Alloca = nullptr); + RawAddress CreateMemTemp(QualType T, const Twine &Name = "tmp", + RawAddress *Alloca = nullptr); + RawAddress CreateMemTemp(QualType T, CharUnits Align, + const Twine &Name = "tmp", + RawAddress *Alloca = nullptr); /// CreateMemTemp - Create a temporary memory object of the given type, with /// appropriate alignmen without casting it to the default address space. - Address CreateMemTempWithoutCast(QualType T, const Twine &Name = "tmp"); - Address CreateMemTempWithoutCast(QualType T, CharUnits Align, - const Twine &Name = "tmp"); + RawAddress CreateMemTempWithoutCast(QualType T, const Twine &Name = "tmp"); + RawAddress CreateMemTempWithoutCast(QualType T, CharUnits Align, + const Twine &Name = "tmp"); /// CreateAggTemp - Create a temporary memory object for the given /// aggregate type. AggValueSlot CreateAggTemp(QualType T, const Twine &Name = "tmp", - Address *Alloca = nullptr) { - return AggValueSlot::forAddr(CreateMemTemp(T, Name, Alloca), - T.getQualifiers(), - AggValueSlot::IsNotDestructed, - AggValueSlot::DoesNotNeedGCBarriers, - AggValueSlot::IsNotAliased, - AggValueSlot::DoesNotOverlap); + RawAddress *Alloca = nullptr) { + return AggValueSlot::forAddr( + CreateMemTemp(T, Name, Alloca), T.getQualifiers(), + AggValueSlot::IsNotDestructed, AggValueSlot::DoesNotNeedGCBarriers, + AggValueSlot::IsNotAliased, AggValueSlot::DoesNotOverlap); } /// EvaluateExprAsBool - Perform the usual unary conversions on the specified @@ -3083,6 +3153,25 @@ public: /// calls to EmitTypeCheck can be skipped. bool sanitizePerformTypeCheck() const; + void EmitTypeCheck(TypeCheckKind TCK, SourceLocation Loc, LValue LV, + QualType Type, SanitizerSet SkippedChecks = SanitizerSet(), + llvm::Value *ArraySize = nullptr) { + if (!sanitizePerformTypeCheck()) + return; + EmitTypeCheck(TCK, Loc, LV.emitRawPointer(*this), Type, LV.getAlignment(), + SkippedChecks, ArraySize); + } + + void EmitTypeCheck(TypeCheckKind TCK, SourceLocation Loc, Address Addr, + QualType Type, CharUnits Alignment = CharUnits::Zero(), + SanitizerSet SkippedChecks = SanitizerSet(), + llvm::Value *ArraySize = nullptr) { + if (!sanitizePerformTypeCheck()) + return; + EmitTypeCheck(TCK, Loc, Addr.emitRawPointer(*this), Type, Alignment, + SkippedChecks, ArraySize); + } + /// Emit a check that \p V is the address of storage of the /// appropriate size and alignment for an object of type \p Type /// (or if ArraySize is provided, for an array of that bound). @@ -3183,17 +3272,17 @@ public: /// Address with original alloca instruction. Invalid if the variable was /// emitted as a global constant. - Address AllocaAddr; + RawAddress AllocaAddr; struct Invalid {}; AutoVarEmission(Invalid) : Variable(nullptr), Addr(Address::invalid()), - AllocaAddr(Address::invalid()) {} + AllocaAddr(RawAddress::invalid()) {} AutoVarEmission(const VarDecl &variable) : Variable(&variable), Addr(Address::invalid()), NRVOFlag(nullptr), IsEscapingByRef(false), IsConstantAggregate(false), - SizeForLifetimeMarkers(nullptr), AllocaAddr(Address::invalid()) {} + SizeForLifetimeMarkers(nullptr), AllocaAddr(RawAddress::invalid()) {} bool wasEmittedAsGlobal() const { return !Addr.isValid(); } @@ -3216,7 +3305,7 @@ public: } /// Returns the address for the original alloca instruction. - Address getOriginalAllocatedAddress() const { return AllocaAddr; } + RawAddress getOriginalAllocatedAddress() const { return AllocaAddr; } /// Returns the address of the object within this declaration. /// Note that this does not chase the forwarding pointer for @@ -3246,23 +3335,32 @@ public: llvm::GlobalValue::LinkageTypes Linkage); class ParamValue { - llvm::Value *Value; - llvm::Type *ElementType; - unsigned Alignment; - ParamValue(llvm::Value *V, llvm::Type *T, unsigned A) - : Value(V), ElementType(T), Alignment(A) {} + union { + Address Addr; + llvm::Value *Value; + }; + + bool IsIndirect; + + ParamValue(llvm::Value *V) : Value(V), IsIndirect(false) {} + ParamValue(Address A) : Addr(A), IsIndirect(true) {} + public: static ParamValue forDirect(llvm::Value *value) { - return ParamValue(value, nullptr, 0); + return ParamValue(value); } static ParamValue forIndirect(Address addr) { assert(!addr.getAlignment().isZero()); - return ParamValue(addr.getPointer(), addr.getElementType(), - addr.getAlignment().getQuantity()); + return ParamValue(addr); } - bool isIndirect() const { return Alignment != 0; } - llvm::Value *getAnyValue() const { return Value; } + bool isIndirect() const { return IsIndirect; } + llvm::Value *getAnyValue() const { + if (!isIndirect()) + return Value; + assert(!Addr.hasOffset() && "unexpected offset"); + return Addr.getBasePointer(); + } llvm::Value *getDirectValue() const { assert(!isIndirect()); @@ -3271,8 +3369,7 @@ public: Address getIndirectAddress() const { assert(isIndirect()); - return Address(Value, ElementType, CharUnits::fromQuantity(Alignment), - KnownNonNull); + return Addr; } }; @@ -4182,6 +4279,9 @@ public: const Twine &name = ""); llvm::CallInst *EmitNounwindRuntimeCall(llvm::FunctionCallee callee, const Twine &name = ""); + llvm::CallInst *EmitNounwindRuntimeCall(llvm::FunctionCallee callee, + ArrayRef
args, + const Twine &name = ""); llvm::CallInst *EmitNounwindRuntimeCall(llvm::FunctionCallee callee, ArrayRef args, const Twine &name = ""); @@ -4208,6 +4308,12 @@ public: CXXDtorType Type, const CXXRecordDecl *RD); + llvm::Value *getAsNaturalPointerTo(Address Addr, QualType PointeeType) { + return Addr.getBasePointer(); + } + + bool isPointerKnownNonNull(const Expr *E); + // Return the copy constructor name with the prefix "__copy_constructor_" // removed. static std::string getNonTrivialCopyConstructorStr(QualType QT, @@ -4780,6 +4886,11 @@ public: SourceLocation Loc, const Twine &Name = ""); + Address EmitCheckedInBoundsGEP(Address Addr, ArrayRef IdxList, + llvm::Type *elementType, bool SignedIndices, + bool IsSubtraction, SourceLocation Loc, + CharUnits Align, const Twine &Name = ""); + /// Specifies which type of sanitizer check to apply when handling a /// particular builtin. enum BuiltinCheckKind { @@ -4842,6 +4953,10 @@ public: void EmitNonNullArgCheck(RValue RV, QualType ArgType, SourceLocation ArgLoc, AbstractCallee AC, unsigned ParmNum); + void EmitNonNullArgCheck(Address Addr, QualType ArgType, + SourceLocation ArgLoc, AbstractCallee AC, + unsigned ParmNum); + /// EmitCallArg - Emit a single call argument. void EmitCallArg(CallArgList &args, const Expr *E, QualType ArgType); @@ -5050,7 +5165,7 @@ DominatingLLVMValue::save(CodeGenFunction &CGF, llvm::Value *value) { CGF.CreateTempAlloca(value->getType(), align, "cond-cleanup.save"); CGF.Builder.CreateStore(value, alloca); - return saved_type(alloca.getPointer(), true); + return saved_type(alloca.emitRawPointer(CGF), true); } inline llvm::Value *DominatingLLVMValue::restore(CodeGenFunction &CGF, diff --git a/clang/lib/CodeGen/CodeGenModule.cpp b/clang/lib/CodeGen/CodeGenModule.cpp index e3ed5e90f2d3..00b3bfcaa0bc 100644 --- a/clang/lib/CodeGen/CodeGenModule.cpp +++ b/clang/lib/CodeGen/CodeGenModule.cpp @@ -7267,7 +7267,7 @@ void CodeGenFunction::EmitDeclMetadata() { for (auto &I : LocalDeclMap) { const Decl *D = I.first; - llvm::Value *Addr = I.second.getPointer(); + llvm::Value *Addr = I.second.emitRawPointer(*this); if (auto *Alloca = dyn_cast(Addr)) { llvm::Value *DAddr = GetPointerConstant(getLLVMContext(), D); Alloca->setMetadata( diff --git a/clang/lib/CodeGen/CodeGenPGO.cpp b/clang/lib/CodeGen/CodeGenPGO.cpp index 2619edfeb7dc..76704c4d7be4 100644 --- a/clang/lib/CodeGen/CodeGenPGO.cpp +++ b/clang/lib/CodeGen/CodeGenPGO.cpp @@ -1239,7 +1239,8 @@ void CodeGenPGO::emitMCDCParameters(CGBuilderTy &Builder) { void CodeGenPGO::emitMCDCTestVectorBitmapUpdate(CGBuilderTy &Builder, const Expr *S, - Address MCDCCondBitmapAddr) { + Address MCDCCondBitmapAddr, + CodeGenFunction &CGF) { if (!canEmitMCDCCoverage(Builder) || !RegionMCDCState) return; @@ -1262,7 +1263,7 @@ void CodeGenPGO::emitMCDCTestVectorBitmapUpdate(CGBuilderTy &Builder, Builder.getInt64(FunctionHash), Builder.getInt32(RegionMCDCState->BitmapBytes), Builder.getInt32(MCDCTestVectorBitmapOffset), - MCDCCondBitmapAddr.getPointer()}; + MCDCCondBitmapAddr.emitRawPointer(CGF)}; Builder.CreateCall( CGM.getIntrinsic(llvm::Intrinsic::instrprof_mcdc_tvbitmap_update), Args); } @@ -1283,7 +1284,8 @@ void CodeGenPGO::emitMCDCCondBitmapReset(CGBuilderTy &Builder, const Expr *S, void CodeGenPGO::emitMCDCCondBitmapUpdate(CGBuilderTy &Builder, const Expr *S, Address MCDCCondBitmapAddr, - llvm::Value *Val) { + llvm::Value *Val, + CodeGenFunction &CGF) { if (!canEmitMCDCCoverage(Builder) || !RegionMCDCState) return; @@ -1312,7 +1314,7 @@ void CodeGenPGO::emitMCDCCondBitmapUpdate(CGBuilderTy &Builder, const Expr *S, llvm::Value *Args[5] = {llvm::ConstantExpr::getBitCast(FuncNameVar, I8PtrTy), Builder.getInt64(FunctionHash), Builder.getInt32(Branch.ID), - MCDCCondBitmapAddr.getPointer(), Val}; + MCDCCondBitmapAddr.emitRawPointer(CGF), Val}; Builder.CreateCall( CGM.getIntrinsic(llvm::Intrinsic::instrprof_mcdc_condbitmap_update), Args); diff --git a/clang/lib/CodeGen/CodeGenPGO.h b/clang/lib/CodeGen/CodeGenPGO.h index 036fbf6815a4..9d66ffad6f43 100644 --- a/clang/lib/CodeGen/CodeGenPGO.h +++ b/clang/lib/CodeGen/CodeGenPGO.h @@ -113,12 +113,14 @@ public: void emitCounterSetOrIncrement(CGBuilderTy &Builder, const Stmt *S, llvm::Value *StepV); void emitMCDCTestVectorBitmapUpdate(CGBuilderTy &Builder, const Expr *S, - Address MCDCCondBitmapAddr); + Address MCDCCondBitmapAddr, + CodeGenFunction &CGF); void emitMCDCParameters(CGBuilderTy &Builder); void emitMCDCCondBitmapReset(CGBuilderTy &Builder, const Expr *S, Address MCDCCondBitmapAddr); void emitMCDCCondBitmapUpdate(CGBuilderTy &Builder, const Expr *S, - Address MCDCCondBitmapAddr, llvm::Value *Val); + Address MCDCCondBitmapAddr, llvm::Value *Val, + CodeGenFunction &CGF); /// Return the region count for the counter at the given index. uint64_t getRegionCount(const Stmt *S) { diff --git a/clang/lib/CodeGen/ItaniumCXXABI.cpp b/clang/lib/CodeGen/ItaniumCXXABI.cpp index bdd53a192f82..fd71317572f0 100644 --- a/clang/lib/CodeGen/ItaniumCXXABI.cpp +++ b/clang/lib/CodeGen/ItaniumCXXABI.cpp @@ -307,10 +307,6 @@ public: CodeGenFunction &CGF, const CXXRecordDecl *VTableClass, BaseSubobject Base, const CXXRecordDecl *NearestVBase); - llvm::Constant * - getVTableAddressPointForConstExpr(BaseSubobject Base, - const CXXRecordDecl *VTableClass) override; - llvm::GlobalVariable *getAddrOfVTable(const CXXRecordDecl *RD, CharUnits VPtrOffset) override; @@ -646,7 +642,7 @@ CGCallee ItaniumCXXABI::EmitLoadOfMemberFunctionPointer( // Apply the adjustment and cast back to the original struct type // for consistency. - llvm::Value *This = ThisAddr.getPointer(); + llvm::Value *This = ThisAddr.emitRawPointer(CGF); This = Builder.CreateInBoundsGEP(Builder.getInt8Ty(), This, Adj); ThisPtrForCall = This; @@ -850,7 +846,7 @@ llvm::Value *ItaniumCXXABI::EmitMemberDataPointerAddress( CGBuilderTy &Builder = CGF.Builder; // Apply the offset, which we assume is non-null. - return Builder.CreateInBoundsGEP(CGF.Int8Ty, Base.getPointer(), MemPtr, + return Builder.CreateInBoundsGEP(CGF.Int8Ty, Base.emitRawPointer(CGF), MemPtr, "memptr.offset"); } @@ -1245,7 +1241,7 @@ void ItaniumCXXABI::emitVirtualObjectDelete(CodeGenFunction &CGF, CGF.getPointerAlign()); // Apply the offset. - llvm::Value *CompletePtr = Ptr.getPointer(); + llvm::Value *CompletePtr = Ptr.emitRawPointer(CGF); CompletePtr = CGF.Builder.CreateInBoundsGEP(CGF.Int8Ty, CompletePtr, Offset); @@ -1482,7 +1478,8 @@ llvm::Value *ItaniumCXXABI::emitDynamicCastCall( computeOffsetHint(CGF.getContext(), SrcDecl, DestDecl).getQuantity()); // Emit the call to __dynamic_cast. - llvm::Value *Args[] = {ThisAddr.getPointer(), SrcRTTI, DestRTTI, OffsetHint}; + llvm::Value *Args[] = {ThisAddr.emitRawPointer(CGF), SrcRTTI, DestRTTI, + OffsetHint}; llvm::Value *Value = CGF.EmitNounwindRuntimeCall(getItaniumDynamicCastFn(CGF), Args); @@ -1571,7 +1568,7 @@ llvm::Value *ItaniumCXXABI::emitExactDynamicCast( VPtr, CGM.getTBAAVTablePtrAccessInfo(CGF.VoidPtrPtrTy)); llvm::Value *Success = CGF.Builder.CreateICmpEQ( VPtr, getVTableAddressPoint(BaseSubobject(SrcDecl, *Offset), DestDecl)); - llvm::Value *Result = ThisAddr.getPointer(); + llvm::Value *Result = ThisAddr.emitRawPointer(CGF); if (!Offset->isZero()) Result = CGF.Builder.CreateInBoundsGEP( CGF.CharTy, Result, @@ -1611,7 +1608,7 @@ llvm::Value *ItaniumCXXABI::emitDynamicCastToVoid(CodeGenFunction &CGF, PtrDiffLTy, OffsetToTop, CGF.getPointerAlign(), "offset.to.top"); } // Finally, add the offset to the pointer. - return CGF.Builder.CreateInBoundsGEP(CGF.Int8Ty, ThisAddr.getPointer(), + return CGF.Builder.CreateInBoundsGEP(CGF.Int8Ty, ThisAddr.emitRawPointer(CGF), OffsetToTop); } @@ -1792,8 +1789,8 @@ void ItaniumCXXABI::EmitDestructorCall(CodeGenFunction &CGF, else Callee = CGCallee::forDirect(CGM.getAddrOfCXXStructor(GD), GD); - CGF.EmitCXXDestructorCall(GD, Callee, This.getPointer(), ThisTy, VTT, VTTTy, - nullptr); + CGF.EmitCXXDestructorCall(GD, Callee, CGF.getAsNaturalPointerTo(This, ThisTy), + ThisTy, VTT, VTTTy, nullptr); } void ItaniumCXXABI::emitVTableDefinitions(CodeGenVTables &CGVT, @@ -1952,11 +1949,6 @@ llvm::Value *ItaniumCXXABI::getVTableAddressPointInStructorWithVTT( CGF.getPointerAlign()); } -llvm::Constant *ItaniumCXXABI::getVTableAddressPointForConstExpr( - BaseSubobject Base, const CXXRecordDecl *VTableClass) { - return getVTableAddressPoint(Base, VTableClass); -} - llvm::GlobalVariable *ItaniumCXXABI::getAddrOfVTable(const CXXRecordDecl *RD, CharUnits VPtrOffset) { assert(VPtrOffset.isZero() && "Itanium ABI only supports zero vptr offsets"); @@ -2088,8 +2080,8 @@ llvm::Value *ItaniumCXXABI::EmitVirtualDestructorCall( ThisTy = D->getDestroyedType(); } - CGF.EmitCXXDestructorCall(GD, Callee, This.getPointer(), ThisTy, nullptr, - QualType(), nullptr); + CGF.EmitCXXDestructorCall(GD, Callee, This.emitRawPointer(CGF), ThisTy, + nullptr, QualType(), nullptr); return nullptr; } @@ -2162,7 +2154,7 @@ static llvm::Value *performTypeAdjustment(CodeGenFunction &CGF, int64_t VirtualAdjustment, bool IsReturnAdjustment) { if (!NonVirtualAdjustment && !VirtualAdjustment) - return InitialPtr.getPointer(); + return InitialPtr.emitRawPointer(CGF); Address V = InitialPtr.withElementType(CGF.Int8Ty); @@ -2195,10 +2187,10 @@ static llvm::Value *performTypeAdjustment(CodeGenFunction &CGF, CGF.getPointerAlign()); } // Adjust our pointer. - ResultPtr = CGF.Builder.CreateInBoundsGEP( - V.getElementType(), V.getPointer(), Offset); + ResultPtr = CGF.Builder.CreateInBoundsGEP(V.getElementType(), + V.emitRawPointer(CGF), Offset); } else { - ResultPtr = V.getPointer(); + ResultPtr = V.emitRawPointer(CGF); } // In a derived-to-base conversion, the non-virtual adjustment is @@ -2284,7 +2276,7 @@ Address ItaniumCXXABI::InitializeArrayCookie(CodeGenFunction &CGF, llvm::FunctionType::get(CGM.VoidTy, NumElementsPtr.getType(), false); llvm::FunctionCallee F = CGM.CreateRuntimeFunction(FTy, "__asan_poison_cxx_array_cookie"); - CGF.Builder.CreateCall(F, NumElementsPtr.getPointer()); + CGF.Builder.CreateCall(F, NumElementsPtr.emitRawPointer(CGF)); } // Finally, compute a pointer to the actual data buffer by skipping @@ -2315,7 +2307,7 @@ llvm::Value *ItaniumCXXABI::readArrayCookieImpl(CodeGenFunction &CGF, llvm::FunctionType::get(CGF.SizeTy, CGF.UnqualPtrTy, false); llvm::FunctionCallee F = CGM.CreateRuntimeFunction(FTy, "__asan_load_cxx_array_cookie"); - return CGF.Builder.CreateCall(F, numElementsPtr.getPointer()); + return CGF.Builder.CreateCall(F, numElementsPtr.emitRawPointer(CGF)); } CharUnits ARMCXXABI::getArrayCookieSizeImpl(QualType elementType) { @@ -2627,7 +2619,7 @@ void ItaniumCXXABI::EmitGuardedInit(CodeGenFunction &CGF, // Call __cxa_guard_release. This cannot throw. CGF.EmitNounwindRuntimeCall(getGuardReleaseFn(CGM, guardPtrTy), - guardAddr.getPointer()); + guardAddr.emitRawPointer(CGF)); } else if (D.isLocalVarDecl()) { // For local variables, store 1 into the first byte of the guard variable // after the object initialization completes so that initialization is @@ -3120,10 +3112,10 @@ LValue ItaniumCXXABI::EmitThreadLocalVarDeclLValue(CodeGenFunction &CGF, LValue LV; if (VD->getType()->isReferenceType()) - LV = CGF.MakeNaturalAlignAddrLValue(CallVal, LValType); + LV = CGF.MakeNaturalAlignRawAddrLValue(CallVal, LValType); else - LV = CGF.MakeAddrLValue(CallVal, LValType, - CGF.getContext().getDeclAlign(VD)); + LV = CGF.MakeRawAddrLValue(CallVal, LValType, + CGF.getContext().getDeclAlign(VD)); // FIXME: need setObjCGCLValueClass? return LV; } @@ -4604,7 +4596,7 @@ static void InitCatchParam(CodeGenFunction &CGF, CGF.Builder.CreateStore(Casted, ExnPtrTmp); // Bind the reference to the temporary. - AdjustedExn = ExnPtrTmp.getPointer(); + AdjustedExn = ExnPtrTmp.emitRawPointer(CGF); } } diff --git a/clang/lib/CodeGen/MicrosoftCXXABI.cpp b/clang/lib/CodeGen/MicrosoftCXXABI.cpp index 172c4c937b97..d38a26940a3c 100644 --- a/clang/lib/CodeGen/MicrosoftCXXABI.cpp +++ b/clang/lib/CodeGen/MicrosoftCXXABI.cpp @@ -327,10 +327,6 @@ public: CodeGenFunction &CGF, const CXXRecordDecl *VTableClass, BaseSubobject Base, const CXXRecordDecl *NearestVBase) override; - llvm::Constant * - getVTableAddressPointForConstExpr(BaseSubobject Base, - const CXXRecordDecl *VTableClass) override; - llvm::GlobalVariable *getAddrOfVTable(const CXXRecordDecl *RD, CharUnits VPtrOffset) override; @@ -937,7 +933,7 @@ void MicrosoftCXXABI::emitBeginCatch(CodeGenFunction &CGF, } CodeGenFunction::AutoVarEmission var = CGF.EmitAutoVarAlloca(*CatchParam); - CPI->setArgOperand(2, var.getObjectAddress(CGF).getPointer()); + CPI->setArgOperand(2, var.getObjectAddress(CGF).emitRawPointer(CGF)); CGF.EHStack.pushCleanup(NormalCleanup, CPI); CGF.EmitAutoVarCleanups(var); } @@ -974,7 +970,7 @@ MicrosoftCXXABI::performBaseAdjustment(CodeGenFunction &CGF, Address Value, llvm::Value *Offset = GetVirtualBaseClassOffset(CGF, Value, SrcDecl, PolymorphicBase); llvm::Value *Ptr = CGF.Builder.CreateInBoundsGEP( - Value.getElementType(), Value.getPointer(), Offset); + Value.getElementType(), Value.emitRawPointer(CGF), Offset); CharUnits VBaseAlign = CGF.CGM.getVBaseAlignment(Value.getAlignment(), SrcDecl, PolymorphicBase); return std::make_tuple(Address(Ptr, CGF.Int8Ty, VBaseAlign), Offset, @@ -1011,7 +1007,7 @@ llvm::Value *MicrosoftCXXABI::EmitTypeid(CodeGenFunction &CGF, llvm::Type *StdTypeInfoPtrTy) { std::tie(ThisPtr, std::ignore, std::ignore) = performBaseAdjustment(CGF, ThisPtr, SrcRecordTy); - llvm::CallBase *Typeid = emitRTtypeidCall(CGF, ThisPtr.getPointer()); + llvm::CallBase *Typeid = emitRTtypeidCall(CGF, ThisPtr.emitRawPointer(CGF)); return CGF.Builder.CreateBitCast(Typeid, StdTypeInfoPtrTy); } @@ -1033,7 +1029,7 @@ llvm::Value *MicrosoftCXXABI::emitDynamicCastCall( llvm::Value *Offset; std::tie(This, Offset, std::ignore) = performBaseAdjustment(CGF, This, SrcRecordTy); - llvm::Value *ThisPtr = This.getPointer(); + llvm::Value *ThisPtr = This.emitRawPointer(CGF); Offset = CGF.Builder.CreateTrunc(Offset, CGF.Int32Ty); // PVOID __RTDynamicCast( @@ -1065,7 +1061,7 @@ llvm::Value *MicrosoftCXXABI::emitDynamicCastToVoid(CodeGenFunction &CGF, llvm::FunctionCallee Function = CGF.CGM.CreateRuntimeFunction( llvm::FunctionType::get(CGF.Int8PtrTy, ArgTypes, false), "__RTCastToVoid"); - llvm::Value *Args[] = {Value.getPointer()}; + llvm::Value *Args[] = {Value.emitRawPointer(CGF)}; return CGF.EmitRuntimeCall(Function, Args); } @@ -1493,7 +1489,7 @@ Address MicrosoftCXXABI::adjustThisArgumentForVirtualFunctionCall( llvm::Value *VBaseOffset = GetVirtualBaseClassOffset(CGF, Result, Derived, VBase); llvm::Value *VBasePtr = CGF.Builder.CreateInBoundsGEP( - Result.getElementType(), Result.getPointer(), VBaseOffset); + Result.getElementType(), Result.emitRawPointer(CGF), VBaseOffset); CharUnits VBaseAlign = CGF.CGM.getVBaseAlignment(Result.getAlignment(), Derived, VBase); Result = Address(VBasePtr, CGF.Int8Ty, VBaseAlign); @@ -1660,7 +1656,8 @@ void MicrosoftCXXABI::EmitDestructorCall(CodeGenFunction &CGF, llvm::Value *Implicit = getCXXDestructorImplicitParam(CGF, DD, Type, ForVirtualBase, Delegating); // = nullptr - CGF.EmitCXXDestructorCall(GD, Callee, This.getPointer(), ThisTy, + CGF.EmitCXXDestructorCall(GD, Callee, CGF.getAsNaturalPointerTo(This, ThisTy), + ThisTy, /*ImplicitParam=*/Implicit, /*ImplicitParamTy=*/QualType(), nullptr); if (BaseDtorEndBB) { @@ -1791,13 +1788,6 @@ MicrosoftCXXABI::getVTableAddressPoint(BaseSubobject Base, return VFTablesMap[ID]; } -llvm::Constant *MicrosoftCXXABI::getVTableAddressPointForConstExpr( - BaseSubobject Base, const CXXRecordDecl *VTableClass) { - llvm::Constant *VFTable = getVTableAddressPoint(Base, VTableClass); - assert(VFTable && "Couldn't find a vftable for the given base?"); - return VFTable; -} - llvm::GlobalVariable *MicrosoftCXXABI::getAddrOfVTable(const CXXRecordDecl *RD, CharUnits VPtrOffset) { // getAddrOfVTable may return 0 if asked to get an address of a vtable which @@ -2013,8 +2003,9 @@ llvm::Value *MicrosoftCXXABI::EmitVirtualDestructorCall( } This = adjustThisArgumentForVirtualFunctionCall(CGF, GD, This, true); - RValue RV = CGF.EmitCXXDestructorCall(GD, Callee, This.getPointer(), ThisTy, - ImplicitParam, Context.IntTy, CE); + RValue RV = + CGF.EmitCXXDestructorCall(GD, Callee, This.emitRawPointer(CGF), ThisTy, + ImplicitParam, Context.IntTy, CE); return RV.getScalarVal(); } @@ -2212,13 +2203,13 @@ llvm::Value *MicrosoftCXXABI::performThisAdjustment(CodeGenFunction &CGF, Address This, const ThisAdjustment &TA) { if (TA.isEmpty()) - return This.getPointer(); + return This.emitRawPointer(CGF); This = This.withElementType(CGF.Int8Ty); llvm::Value *V; if (TA.Virtual.isEmpty()) { - V = This.getPointer(); + V = This.emitRawPointer(CGF); } else { assert(TA.Virtual.Microsoft.VtordispOffset < 0); // Adjust the this argument based on the vtordisp value. @@ -2227,7 +2218,7 @@ llvm::Value *MicrosoftCXXABI::performThisAdjustment(CodeGenFunction &CGF, CharUnits::fromQuantity(TA.Virtual.Microsoft.VtordispOffset)); VtorDispPtr = VtorDispPtr.withElementType(CGF.Int32Ty); llvm::Value *VtorDisp = CGF.Builder.CreateLoad(VtorDispPtr, "vtordisp"); - V = CGF.Builder.CreateGEP(This.getElementType(), This.getPointer(), + V = CGF.Builder.CreateGEP(This.getElementType(), This.emitRawPointer(CGF), CGF.Builder.CreateNeg(VtorDisp)); // Unfortunately, having applied the vtordisp means that we no @@ -2264,11 +2255,11 @@ llvm::Value * MicrosoftCXXABI::performReturnAdjustment(CodeGenFunction &CGF, Address Ret, const ReturnAdjustment &RA) { if (RA.isEmpty()) - return Ret.getPointer(); + return Ret.emitRawPointer(CGF); Ret = Ret.withElementType(CGF.Int8Ty); - llvm::Value *V = Ret.getPointer(); + llvm::Value *V = Ret.emitRawPointer(CGF); if (RA.Virtual.Microsoft.VBIndex) { assert(RA.Virtual.Microsoft.VBIndex > 0); int32_t IntSize = CGF.getIntSize().getQuantity(); @@ -2583,7 +2574,7 @@ struct ResetGuardBit final : EHScopeStack::Cleanup { struct CallInitThreadAbort final : EHScopeStack::Cleanup { llvm::Value *Guard; - CallInitThreadAbort(Address Guard) : Guard(Guard.getPointer()) {} + CallInitThreadAbort(RawAddress Guard) : Guard(Guard.getPointer()) {} void Emit(CodeGenFunction &CGF, Flags flags) override { // Calling _Init_thread_abort will reset the guard's state. @@ -3123,8 +3114,8 @@ MicrosoftCXXABI::GetVBaseOffsetFromVBPtr(CodeGenFunction &CGF, llvm::Value **VBPtrOut) { CGBuilderTy &Builder = CGF.Builder; // Load the vbtable pointer from the vbptr in the instance. - llvm::Value *VBPtr = Builder.CreateInBoundsGEP(CGM.Int8Ty, This.getPointer(), - VBPtrOffset, "vbptr"); + llvm::Value *VBPtr = Builder.CreateInBoundsGEP( + CGM.Int8Ty, This.emitRawPointer(CGF), VBPtrOffset, "vbptr"); if (VBPtrOut) *VBPtrOut = VBPtr; @@ -3203,7 +3194,7 @@ llvm::Value *MicrosoftCXXABI::AdjustVirtualBase( Builder.CreateBr(SkipAdjustBB); CGF.EmitBlock(SkipAdjustBB); llvm::PHINode *Phi = Builder.CreatePHI(CGM.Int8PtrTy, 2, "memptr.base"); - Phi->addIncoming(Base.getPointer(), OriginalBB); + Phi->addIncoming(Base.emitRawPointer(CGF), OriginalBB); Phi->addIncoming(AdjustedBase, VBaseAdjustBB); return Phi; } @@ -3238,7 +3229,7 @@ llvm::Value *MicrosoftCXXABI::EmitMemberDataPointerAddress( Addr = AdjustVirtualBase(CGF, E, RD, Base, VirtualBaseAdjustmentOffset, VBPtrOffset); } else { - Addr = Base.getPointer(); + Addr = Base.emitRawPointer(CGF); } // Apply the offset, which we assume is non-null. @@ -3526,7 +3517,7 @@ CGCallee MicrosoftCXXABI::EmitLoadOfMemberFunctionPointer( ThisPtrForCall = AdjustVirtualBase(CGF, E, RD, This, VirtualBaseAdjustmentOffset, VBPtrOffset); } else { - ThisPtrForCall = This.getPointer(); + ThisPtrForCall = This.emitRawPointer(CGF); } if (NonVirtualBaseAdjustment) @@ -4445,10 +4436,7 @@ void MicrosoftCXXABI::emitThrow(CodeGenFunction &CGF, const CXXThrowExpr *E) { llvm::GlobalVariable *TI = getThrowInfo(ThrowType); // Call into the runtime to throw the exception. - llvm::Value *Args[] = { - AI.getPointer(), - TI - }; + llvm::Value *Args[] = {AI.emitRawPointer(CGF), TI}; CGF.EmitNoreturnRuntimeCallOrInvoke(getThrowFn(), Args); } diff --git a/clang/lib/CodeGen/TargetInfo.h b/clang/lib/CodeGen/TargetInfo.h index 6893b50a3cfe..b1dfe5bf8f27 100644 --- a/clang/lib/CodeGen/TargetInfo.h +++ b/clang/lib/CodeGen/TargetInfo.h @@ -295,6 +295,11 @@ public: /// Get the AST address space for alloca. virtual LangAS getASTAllocaAddressSpace() const { return LangAS::Default; } + Address performAddrSpaceCast(CodeGen::CodeGenFunction &CGF, Address Addr, + LangAS SrcAddr, LangAS DestAddr, + llvm::Type *DestTy, + bool IsNonNull = false) const; + /// Perform address space cast of an expression of pointer type. /// \param V is the LLVM value to be casted to another address space. /// \param SrcAddr is the language address space of \p V. diff --git a/clang/lib/CodeGen/Targets/NVPTX.cpp b/clang/lib/CodeGen/Targets/NVPTX.cpp index 8718f1ecf3a7..7dce5042c3dc 100644 --- a/clang/lib/CodeGen/Targets/NVPTX.cpp +++ b/clang/lib/CodeGen/Targets/NVPTX.cpp @@ -85,7 +85,7 @@ private: LValue Src) { llvm::Value *Handle = nullptr; llvm::Constant *C = - llvm::dyn_cast(Src.getAddress(CGF).getPointer()); + llvm::dyn_cast(Src.getAddress(CGF).emitRawPointer(CGF)); // Lookup `addrspacecast` through the constant pointer if any. if (auto *ASC = llvm::dyn_cast_or_null(C)) C = llvm::cast(ASC->getPointerOperand()); diff --git a/clang/lib/CodeGen/Targets/PPC.cpp b/clang/lib/CodeGen/Targets/PPC.cpp index 3eadb19bd205..174fddabbbdb 100644 --- a/clang/lib/CodeGen/Targets/PPC.cpp +++ b/clang/lib/CodeGen/Targets/PPC.cpp @@ -513,9 +513,10 @@ Address PPC32_SVR4_ABIInfo::EmitVAArg(CodeGenFunction &CGF, Address VAList, CharUnits RegSize = CharUnits::fromQuantity((isInt || IsSoftFloatABI) ? 4 : 8); llvm::Value *RegOffset = Builder.CreateMul(NumRegs, Builder.getInt8(RegSize.getQuantity())); - RegAddr = Address( - Builder.CreateInBoundsGEP(CGF.Int8Ty, RegAddr.getPointer(), RegOffset), - DirectTy, RegAddr.getAlignment().alignmentOfArrayElement(RegSize)); + RegAddr = Address(Builder.CreateInBoundsGEP( + CGF.Int8Ty, RegAddr.emitRawPointer(CGF), RegOffset), + DirectTy, + RegAddr.getAlignment().alignmentOfArrayElement(RegSize)); // Increase the used-register count. NumRegs = @@ -551,7 +552,7 @@ Address PPC32_SVR4_ABIInfo::EmitVAArg(CodeGenFunction &CGF, Address VAList, // Round up address of argument to alignment CharUnits Align = CGF.getContext().getTypeAlignInChars(Ty); if (Align > OverflowAreaAlign) { - llvm::Value *Ptr = OverflowArea.getPointer(); + llvm::Value *Ptr = OverflowArea.emitRawPointer(CGF); OverflowArea = Address(emitRoundPointerUpToAlignment(CGF, Ptr, Align), OverflowArea.getElementType(), Align); } @@ -560,7 +561,7 @@ Address PPC32_SVR4_ABIInfo::EmitVAArg(CodeGenFunction &CGF, Address VAList, // Increase the overflow area. OverflowArea = Builder.CreateConstInBoundsByteGEP(OverflowArea, Size); - Builder.CreateStore(OverflowArea.getPointer(), OverflowAreaAddr); + Builder.CreateStore(OverflowArea.emitRawPointer(CGF), OverflowAreaAddr); CGF.EmitBranch(Cont); } diff --git a/clang/lib/CodeGen/Targets/Sparc.cpp b/clang/lib/CodeGen/Targets/Sparc.cpp index a337a52a94ec..9025a633f328 100644 --- a/clang/lib/CodeGen/Targets/Sparc.cpp +++ b/clang/lib/CodeGen/Targets/Sparc.cpp @@ -326,7 +326,7 @@ Address SparcV9ABIInfo::EmitVAArg(CodeGenFunction &CGF, Address VAListAddr, // Update VAList. Address NextPtr = Builder.CreateConstInBoundsByteGEP(Addr, Stride, "ap.next"); - Builder.CreateStore(NextPtr.getPointer(), VAListAddr); + Builder.CreateStore(NextPtr.emitRawPointer(CGF), VAListAddr); return ArgAddr.withElementType(ArgTy); } diff --git a/clang/lib/CodeGen/Targets/SystemZ.cpp b/clang/lib/CodeGen/Targets/SystemZ.cpp index 6eb0c6ef2f7d..deaafc85a315 100644 --- a/clang/lib/CodeGen/Targets/SystemZ.cpp +++ b/clang/lib/CodeGen/Targets/SystemZ.cpp @@ -306,7 +306,7 @@ Address SystemZABIInfo::EmitVAArg(CodeGenFunction &CGF, Address VAListAddr, // Update overflow_arg_area_ptr pointer llvm::Value *NewOverflowArgArea = CGF.Builder.CreateGEP( - OverflowArgArea.getElementType(), OverflowArgArea.getPointer(), + OverflowArgArea.getElementType(), OverflowArgArea.emitRawPointer(CGF), PaddedSizeV, "overflow_arg_area"); CGF.Builder.CreateStore(NewOverflowArgArea, OverflowArgAreaPtr); @@ -382,10 +382,9 @@ Address SystemZABIInfo::EmitVAArg(CodeGenFunction &CGF, Address VAListAddr, Address MemAddr = RawMemAddr.withElementType(DirectTy); // Update overflow_arg_area_ptr pointer - llvm::Value *NewOverflowArgArea = - CGF.Builder.CreateGEP(OverflowArgArea.getElementType(), - OverflowArgArea.getPointer(), PaddedSizeV, - "overflow_arg_area"); + llvm::Value *NewOverflowArgArea = CGF.Builder.CreateGEP( + OverflowArgArea.getElementType(), OverflowArgArea.emitRawPointer(CGF), + PaddedSizeV, "overflow_arg_area"); CGF.Builder.CreateStore(NewOverflowArgArea, OverflowArgAreaPtr); CGF.EmitBranch(ContBlock); diff --git a/clang/lib/CodeGen/Targets/XCore.cpp b/clang/lib/CodeGen/Targets/XCore.cpp index aeb48f851e16..88edb781a947 100644 --- a/clang/lib/CodeGen/Targets/XCore.cpp +++ b/clang/lib/CodeGen/Targets/XCore.cpp @@ -180,7 +180,7 @@ Address XCoreABIInfo::EmitVAArg(CodeGenFunction &CGF, Address VAListAddr, // Increment the VAList. if (!ArgSize.isZero()) { Address APN = Builder.CreateConstInBoundsByteGEP(AP, ArgSize); - Builder.CreateStore(APN.getPointer(), VAListAddr); + Builder.CreateStore(APN.emitRawPointer(CGF), VAListAddr); } return Val; diff --git a/clang/utils/TableGen/MveEmitter.cpp b/clang/utils/TableGen/MveEmitter.cpp index 3a90eee5f1c9..aa20c758d84a 100644 --- a/clang/utils/TableGen/MveEmitter.cpp +++ b/clang/utils/TableGen/MveEmitter.cpp @@ -575,7 +575,7 @@ public: // Emit code to generate this result as a Value *. std::string asValue() override { if (AddressType) - return "(" + varname() + ".getPointer())"; + return "(" + varname() + ".emitRawPointer(*this))"; return Result::asValue(); } bool hasIntegerValue() const override { return Immediate; } diff --git a/llvm/include/llvm/IR/IRBuilder.h b/llvm/include/llvm/IR/IRBuilder.h index 2a0c1e9e8c44..2e2ec9a1c830 100644 --- a/llvm/include/llvm/IR/IRBuilder.h +++ b/llvm/include/llvm/IR/IRBuilder.h @@ -2708,6 +2708,7 @@ public: IRBuilder(const IRBuilder &) = delete; InserterTy &getInserter() { return Inserter; } + const InserterTy &getInserter() const { return Inserter; } }; template -- GitLab From a515ea553f773cbb75e4aabeed7d05cc353345c8 Mon Sep 17 00:00:00 2001 From: Yingwei Zheng Date: Thu, 28 Mar 2024 22:00:04 +0800 Subject: [PATCH 059/788] [OCaml] Fix buildbot failure caused by caa2258. NFC. Closes #86944. --- llvm/test/Bindings/OCaml/core.ml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/llvm/test/Bindings/OCaml/core.ml b/llvm/test/Bindings/OCaml/core.ml index a9abc9d17fe4..64bfa8ee412d 100644 --- a/llvm/test/Bindings/OCaml/core.ml +++ b/llvm/test/Bindings/OCaml/core.ml @@ -252,7 +252,7 @@ let test_constants () = group "constant arithmetic"; (* CHECK: @const_neg = global i64 sub * CHECK: @const_nsw_neg = global i64 sub nsw - * CHECK: @const_nuw_neg = global i64 sub nuw + * CHECK: @const_nuw_neg = global i64 sub * CHECK: @const_not = global i64 xor * CHECK: @const_add = global i64 add * CHECK: @const_nsw_add = global i64 add nsw -- GitLab From ff870aeeb7354fd3f681c17e248131e1065ac407 Mon Sep 17 00:00:00 2001 From: Alfie Richards Date: Thu, 28 Mar 2024 14:06:40 +0000 Subject: [PATCH 060/788] [ARM] Add reference to `ARMAsmParser` in `ARMOperand` (#86110) --- .../lib/Target/ARM/AsmParser/ARMAsmParser.cpp | 495 +++++++++--------- 1 file changed, 258 insertions(+), 237 deletions(-) diff --git a/llvm/lib/Target/ARM/AsmParser/ARMAsmParser.cpp b/llvm/lib/Target/ARM/AsmParser/ARMAsmParser.cpp index d63e53df284b..028db9d17e30 100644 --- a/llvm/lib/Target/ARM/AsmParser/ARMAsmParser.cpp +++ b/llvm/lib/Target/ARM/AsmParser/ARMAsmParser.cpp @@ -72,15 +72,6 @@ using namespace llvm; -namespace llvm { -struct ARMInstrTable { - MCInstrDesc Insts[4445]; - MCOperandInfo OperandInfo[3026]; - MCPhysReg ImplicitOps[130]; -}; -extern const ARMInstrTable ARMDescs; -} // end namespace llvm - namespace { class ARMOperand; @@ -360,11 +351,6 @@ class ARMAsmParser : public MCTargetAsmParser { ITState.CurPosition = ~0U; } - // Return the low-subreg of a given Q register. - unsigned getDRegFromQReg(unsigned QReg) const { - return MRI->getSubReg(QReg, ARM::dsub_0); - } - // Get the condition code corresponding to the current IT block slot. ARMCC::CondCodes currentITCond() { unsigned MaskBit = extractITMaskBit(ITState.Mask, ITState.CurPosition); @@ -586,9 +572,6 @@ class ARMAsmParser : public MCTargetAsmParser { bool hasV8_1MMainline() const { return getSTI().hasFeature(ARM::HasV8_1MMainlineOps); } - bool hasMVE() const { - return getSTI().hasFeature(ARM::HasMVEIntegerOps); - } bool hasMVEFloat() const { return getSTI().hasFeature(ARM::HasMVEFloatOps); } @@ -768,6 +751,19 @@ public: void doBeforeLabelEmit(MCSymbol *Symbol, SMLoc IDLoc) override; void onLabelParsed(MCSymbol *Symbol) override; + + const MCInstrDesc &getInstrDesc(unsigned int Opcode) const { + return MII.get(Opcode); + } + + bool hasMVE() const { return getSTI().hasFeature(ARM::HasMVEIntegerOps); } + + // Return the low-subreg of a given Q register. + unsigned getDRegFromQReg(unsigned QReg) const { + return MRI->getSubReg(QReg, ARM::dsub_0); + } + + const MCRegisterInfo *getMRI() const { return MRI; } }; /// ARMOperand - Instances of this class represent a parsed ARM machine @@ -814,6 +810,8 @@ class ARMOperand : public MCParsedAsmOperand { SMLoc StartLoc, EndLoc, AlignmentLoc; SmallVector Registers; + ARMAsmParser *Parser; + struct CCOp { ARMCC::CondCodes Val; }; @@ -964,7 +962,7 @@ class ARMOperand : public MCParsedAsmOperand { }; public: - ARMOperand(KindTy K) : Kind(K) {} + ARMOperand(KindTy K, ARMAsmParser &Parser) : Kind(K), Parser(&Parser) {} /// getStartLoc - Get the location of the first token of this operand. SMLoc getStartLoc() const override { return StartLoc; } @@ -2043,6 +2041,11 @@ public: bool isProcIFlags() const { return Kind == k_ProcIFlags; } // NEON operands. + bool isAnyVectorList() const { + return Kind == k_VectorList || Kind == k_VectorListAllLanes || + Kind == k_VectorListIndexed; + } + bool isVectorList() const { return Kind == k_VectorList; } bool isSingleSpacedVectorList() const { @@ -2054,6 +2057,9 @@ public: } bool isVecListOneD() const { + // We convert a single D reg to a list containing a D reg + if (isDReg() && !Parser->hasMVE()) + return true; if (!isSingleSpacedVectorList()) return false; return VectorList.Count == 1; } @@ -2065,6 +2071,10 @@ public: } bool isVecListDPair() const { + // We convert a single Q reg to a list with the two corresponding D + // registers + if (isQReg() && !Parser->hasMVE()) + return true; if (!isSingleSpacedVectorList()) return false; return (ARMMCRegisterClasses[ARM::DPairRegClassID] .contains(VectorList.RegNum)); @@ -2542,8 +2552,7 @@ public: RegNum = 0; } else { unsigned NextOpIndex = Inst.getNumOperands(); - const MCInstrDesc &MCID = - ARMDescs.Insts[ARM::INSTRUCTION_LIST_END - 1 - Inst.getOpcode()]; + auto &MCID = Parser->getInstrDesc(Inst.getOpcode()); int TiedOp = MCID.getOperandConstraint(NextOpIndex, MCOI::TIED_TO); assert(TiedOp >= 0 && "Inactive register in vpred_r is not tied to an output!"); @@ -3378,7 +3387,21 @@ public: void addVecListOperands(MCInst &Inst, unsigned N) const { assert(N == 1 && "Invalid number of operands!"); - Inst.addOperand(MCOperand::createReg(VectorList.RegNum)); + + if (isAnyVectorList()) + Inst.addOperand(MCOperand::createReg(VectorList.RegNum)); + else if (isDReg() && !Parser->hasMVE()) { + Inst.addOperand(MCOperand::createReg(Reg.RegNum)); + } else if (isQReg() && !Parser->hasMVE()) { + auto DPair = Parser->getDRegFromQReg(Reg.RegNum); + DPair = Parser->getMRI()->getMatchingSuperReg( + DPair, ARM::dsub_0, &ARMMCRegisterClasses[ARM::DPairRegClassID]); + Inst.addOperand(MCOperand::createReg(DPair)); + } else { + LLVM_DEBUG(dbgs() << "TYPE: " << Kind << "\n"); + llvm_unreachable( + "attempted to add a vector list register with wrong type!"); + } } void addMVEVecListOperands(MCInst &Inst, unsigned N) const { @@ -3607,67 +3630,72 @@ public: void print(raw_ostream &OS) const override; - static std::unique_ptr CreateITMask(unsigned Mask, SMLoc S) { - auto Op = std::make_unique(k_ITCondMask); + static std::unique_ptr CreateITMask(unsigned Mask, SMLoc S, + ARMAsmParser &Parser) { + auto Op = std::make_unique(k_ITCondMask, Parser); Op->ITMask.Mask = Mask; Op->StartLoc = S; Op->EndLoc = S; return Op; } - static std::unique_ptr CreateCondCode(ARMCC::CondCodes CC, - SMLoc S) { - auto Op = std::make_unique(k_CondCode); + static std::unique_ptr + CreateCondCode(ARMCC::CondCodes CC, SMLoc S, ARMAsmParser &Parser) { + auto Op = std::make_unique(k_CondCode, Parser); Op->CC.Val = CC; Op->StartLoc = S; Op->EndLoc = S; return Op; } - static std::unique_ptr CreateVPTPred(ARMVCC::VPTCodes CC, - SMLoc S) { - auto Op = std::make_unique(k_VPTPred); + static std::unique_ptr CreateVPTPred(ARMVCC::VPTCodes CC, SMLoc S, + ARMAsmParser &Parser) { + auto Op = std::make_unique(k_VPTPred, Parser); Op->VCC.Val = CC; Op->StartLoc = S; Op->EndLoc = S; return Op; } - static std::unique_ptr CreateCoprocNum(unsigned CopVal, SMLoc S) { - auto Op = std::make_unique(k_CoprocNum); + static std::unique_ptr CreateCoprocNum(unsigned CopVal, SMLoc S, + ARMAsmParser &Parser) { + auto Op = std::make_unique(k_CoprocNum, Parser); Op->Cop.Val = CopVal; Op->StartLoc = S; Op->EndLoc = S; return Op; } - static std::unique_ptr CreateCoprocReg(unsigned CopVal, SMLoc S) { - auto Op = std::make_unique(k_CoprocReg); + static std::unique_ptr CreateCoprocReg(unsigned CopVal, SMLoc S, + ARMAsmParser &Parser) { + auto Op = std::make_unique(k_CoprocReg, Parser); Op->Cop.Val = CopVal; Op->StartLoc = S; Op->EndLoc = S; return Op; } - static std::unique_ptr CreateCoprocOption(unsigned Val, SMLoc S, - SMLoc E) { - auto Op = std::make_unique(k_CoprocOption); + static std::unique_ptr + CreateCoprocOption(unsigned Val, SMLoc S, SMLoc E, ARMAsmParser &Parser) { + auto Op = std::make_unique(k_CoprocOption, Parser); Op->Cop.Val = Val; Op->StartLoc = S; Op->EndLoc = E; return Op; } - static std::unique_ptr CreateCCOut(unsigned RegNum, SMLoc S) { - auto Op = std::make_unique(k_CCOut); + static std::unique_ptr CreateCCOut(unsigned RegNum, SMLoc S, + ARMAsmParser &Parser) { + auto Op = std::make_unique(k_CCOut, Parser); Op->Reg.RegNum = RegNum; Op->StartLoc = S; Op->EndLoc = S; return Op; } - static std::unique_ptr CreateToken(StringRef Str, SMLoc S) { - auto Op = std::make_unique(k_Token); + static std::unique_ptr CreateToken(StringRef Str, SMLoc S, + ARMAsmParser &Parser) { + auto Op = std::make_unique(k_Token, Parser); Op->Tok.Data = Str.data(); Op->Tok.Length = Str.size(); Op->StartLoc = S; @@ -3676,8 +3704,8 @@ public: } static std::unique_ptr CreateReg(unsigned RegNum, SMLoc S, - SMLoc E) { - auto Op = std::make_unique(k_Register); + SMLoc E, ARMAsmParser &Parser) { + auto Op = std::make_unique(k_Register, Parser); Op->Reg.RegNum = RegNum; Op->StartLoc = S; Op->EndLoc = E; @@ -3686,9 +3714,9 @@ public: static std::unique_ptr CreateShiftedRegister(ARM_AM::ShiftOpc ShTy, unsigned SrcReg, - unsigned ShiftReg, unsigned ShiftImm, SMLoc S, - SMLoc E) { - auto Op = std::make_unique(k_ShiftedRegister); + unsigned ShiftReg, unsigned ShiftImm, SMLoc S, SMLoc E, + ARMAsmParser &Parser) { + auto Op = std::make_unique(k_ShiftedRegister, Parser); Op->RegShiftedReg.ShiftTy = ShTy; Op->RegShiftedReg.SrcReg = SrcReg; Op->RegShiftedReg.ShiftReg = ShiftReg; @@ -3700,8 +3728,9 @@ public: static std::unique_ptr CreateShiftedImmediate(ARM_AM::ShiftOpc ShTy, unsigned SrcReg, - unsigned ShiftImm, SMLoc S, SMLoc E) { - auto Op = std::make_unique(k_ShiftedImmediate); + unsigned ShiftImm, SMLoc S, SMLoc E, + ARMAsmParser &Parser) { + auto Op = std::make_unique(k_ShiftedImmediate, Parser); Op->RegShiftedImm.ShiftTy = ShTy; Op->RegShiftedImm.SrcReg = SrcReg; Op->RegShiftedImm.ShiftImm = ShiftImm; @@ -3711,8 +3740,9 @@ public: } static std::unique_ptr CreateShifterImm(bool isASR, unsigned Imm, - SMLoc S, SMLoc E) { - auto Op = std::make_unique(k_ShifterImmediate); + SMLoc S, SMLoc E, + ARMAsmParser &Parser) { + auto Op = std::make_unique(k_ShifterImmediate, Parser); Op->ShifterImm.isASR = isASR; Op->ShifterImm.Imm = Imm; Op->StartLoc = S; @@ -3720,9 +3750,9 @@ public: return Op; } - static std::unique_ptr CreateRotImm(unsigned Imm, SMLoc S, - SMLoc E) { - auto Op = std::make_unique(k_RotateImmediate); + static std::unique_ptr + CreateRotImm(unsigned Imm, SMLoc S, SMLoc E, ARMAsmParser &Parser) { + auto Op = std::make_unique(k_RotateImmediate, Parser); Op->RotImm.Imm = Imm; Op->StartLoc = S; Op->EndLoc = E; @@ -3730,8 +3760,9 @@ public: } static std::unique_ptr CreateModImm(unsigned Bits, unsigned Rot, - SMLoc S, SMLoc E) { - auto Op = std::make_unique(k_ModifiedImmediate); + SMLoc S, SMLoc E, + ARMAsmParser &Parser) { + auto Op = std::make_unique(k_ModifiedImmediate, Parser); Op->ModImm.Bits = Bits; Op->ModImm.Rot = Rot; Op->StartLoc = S; @@ -3740,17 +3771,20 @@ public: } static std::unique_ptr - CreateConstantPoolImm(const MCExpr *Val, SMLoc S, SMLoc E) { - auto Op = std::make_unique(k_ConstantPoolImmediate); + CreateConstantPoolImm(const MCExpr *Val, SMLoc S, SMLoc E, + ARMAsmParser &Parser) { + auto Op = std::make_unique(k_ConstantPoolImmediate, Parser); Op->Imm.Val = Val; Op->StartLoc = S; Op->EndLoc = E; return Op; } - static std::unique_ptr - CreateBitfield(unsigned LSB, unsigned Width, SMLoc S, SMLoc E) { - auto Op = std::make_unique(k_BitfieldDescriptor); + static std::unique_ptr CreateBitfield(unsigned LSB, + unsigned Width, SMLoc S, + SMLoc E, + ARMAsmParser &Parser) { + auto Op = std::make_unique(k_BitfieldDescriptor, Parser); Op->Bitfield.LSB = LSB; Op->Bitfield.Width = Width; Op->StartLoc = S; @@ -3760,7 +3794,7 @@ public: static std::unique_ptr CreateRegList(SmallVectorImpl> &Regs, - SMLoc StartLoc, SMLoc EndLoc) { + SMLoc StartLoc, SMLoc EndLoc, ARMAsmParser &Parser) { assert(Regs.size() > 0 && "RegList contains no registers?"); KindTy Kind = k_RegisterList; @@ -3783,7 +3817,7 @@ public: assert(llvm::is_sorted(Regs) && "Register list must be sorted by encoding"); - auto Op = std::make_unique(Kind); + auto Op = std::make_unique(Kind, Parser); for (const auto &P : Regs) Op->Registers.push_back(P.second); @@ -3792,11 +3826,10 @@ public: return Op; } - static std::unique_ptr CreateVectorList(unsigned RegNum, - unsigned Count, - bool isDoubleSpaced, - SMLoc S, SMLoc E) { - auto Op = std::make_unique(k_VectorList); + static std::unique_ptr + CreateVectorList(unsigned RegNum, unsigned Count, bool isDoubleSpaced, + SMLoc S, SMLoc E, ARMAsmParser &Parser) { + auto Op = std::make_unique(k_VectorList, Parser); Op->VectorList.RegNum = RegNum; Op->VectorList.Count = Count; Op->VectorList.isDoubleSpaced = isDoubleSpaced; @@ -3807,8 +3840,8 @@ public: static std::unique_ptr CreateVectorListAllLanes(unsigned RegNum, unsigned Count, bool isDoubleSpaced, - SMLoc S, SMLoc E) { - auto Op = std::make_unique(k_VectorListAllLanes); + SMLoc S, SMLoc E, ARMAsmParser &Parser) { + auto Op = std::make_unique(k_VectorListAllLanes, Parser); Op->VectorList.RegNum = RegNum; Op->VectorList.Count = Count; Op->VectorList.isDoubleSpaced = isDoubleSpaced; @@ -3819,8 +3852,9 @@ public: static std::unique_ptr CreateVectorListIndexed(unsigned RegNum, unsigned Count, unsigned Index, - bool isDoubleSpaced, SMLoc S, SMLoc E) { - auto Op = std::make_unique(k_VectorListIndexed); + bool isDoubleSpaced, SMLoc S, SMLoc E, + ARMAsmParser &Parser) { + auto Op = std::make_unique(k_VectorListIndexed, Parser); Op->VectorList.RegNum = RegNum; Op->VectorList.Count = Count; Op->VectorList.LaneIndex = Index; @@ -3830,9 +3864,10 @@ public: return Op; } - static std::unique_ptr - CreateVectorIndex(unsigned Idx, SMLoc S, SMLoc E, MCContext &Ctx) { - auto Op = std::make_unique(k_VectorIndex); + static std::unique_ptr CreateVectorIndex(unsigned Idx, SMLoc S, + SMLoc E, MCContext &Ctx, + ARMAsmParser &Parser) { + auto Op = std::make_unique(k_VectorIndex, Parser); Op->VectorIndex.Val = Idx; Op->StartLoc = S; Op->EndLoc = E; @@ -3840,8 +3875,8 @@ public: } static std::unique_ptr CreateImm(const MCExpr *Val, SMLoc S, - SMLoc E) { - auto Op = std::make_unique(k_Immediate); + SMLoc E, ARMAsmParser &Parser) { + auto Op = std::make_unique(k_Immediate, Parser); Op->Imm.Val = Val; Op->StartLoc = S; Op->EndLoc = E; @@ -3851,8 +3886,9 @@ public: static std::unique_ptr CreateMem(unsigned BaseRegNum, const MCExpr *OffsetImm, unsigned OffsetRegNum, ARM_AM::ShiftOpc ShiftType, unsigned ShiftImm, unsigned Alignment, - bool isNegative, SMLoc S, SMLoc E, SMLoc AlignmentLoc = SMLoc()) { - auto Op = std::make_unique(k_Memory); + bool isNegative, SMLoc S, SMLoc E, ARMAsmParser &Parser, + SMLoc AlignmentLoc = SMLoc()) { + auto Op = std::make_unique(k_Memory, Parser); Op->Memory.BaseRegNum = BaseRegNum; Op->Memory.OffsetImm = OffsetImm; Op->Memory.OffsetRegNum = OffsetRegNum; @@ -3868,8 +3904,8 @@ public: static std::unique_ptr CreatePostIdxReg(unsigned RegNum, bool isAdd, ARM_AM::ShiftOpc ShiftTy, - unsigned ShiftImm, SMLoc S, SMLoc E) { - auto Op = std::make_unique(k_PostIndexRegister); + unsigned ShiftImm, SMLoc S, SMLoc E, ARMAsmParser &Parser) { + auto Op = std::make_unique(k_PostIndexRegister, Parser); Op->PostIdxReg.RegNum = RegNum; Op->PostIdxReg.isAdd = isAdd; Op->PostIdxReg.ShiftTy = ShiftTy; @@ -3879,9 +3915,9 @@ public: return Op; } - static std::unique_ptr CreateMemBarrierOpt(ARM_MB::MemBOpt Opt, - SMLoc S) { - auto Op = std::make_unique(k_MemBarrierOpt); + static std::unique_ptr + CreateMemBarrierOpt(ARM_MB::MemBOpt Opt, SMLoc S, ARMAsmParser &Parser) { + auto Op = std::make_unique(k_MemBarrierOpt, Parser); Op->MBOpt.Val = Opt; Op->StartLoc = S; Op->EndLoc = S; @@ -3889,8 +3925,9 @@ public: } static std::unique_ptr - CreateInstSyncBarrierOpt(ARM_ISB::InstSyncBOpt Opt, SMLoc S) { - auto Op = std::make_unique(k_InstSyncBarrierOpt); + CreateInstSyncBarrierOpt(ARM_ISB::InstSyncBOpt Opt, SMLoc S, + ARMAsmParser &Parser) { + auto Op = std::make_unique(k_InstSyncBarrierOpt, Parser); Op->ISBOpt.Val = Opt; Op->StartLoc = S; Op->EndLoc = S; @@ -3898,33 +3935,36 @@ public: } static std::unique_ptr - CreateTraceSyncBarrierOpt(ARM_TSB::TraceSyncBOpt Opt, SMLoc S) { - auto Op = std::make_unique(k_TraceSyncBarrierOpt); + CreateTraceSyncBarrierOpt(ARM_TSB::TraceSyncBOpt Opt, SMLoc S, + ARMAsmParser &Parser) { + auto Op = std::make_unique(k_TraceSyncBarrierOpt, Parser); Op->TSBOpt.Val = Opt; Op->StartLoc = S; Op->EndLoc = S; return Op; } - static std::unique_ptr CreateProcIFlags(ARM_PROC::IFlags IFlags, - SMLoc S) { - auto Op = std::make_unique(k_ProcIFlags); + static std::unique_ptr + CreateProcIFlags(ARM_PROC::IFlags IFlags, SMLoc S, ARMAsmParser &Parser) { + auto Op = std::make_unique(k_ProcIFlags, Parser); Op->IFlags.Val = IFlags; Op->StartLoc = S; Op->EndLoc = S; return Op; } - static std::unique_ptr CreateMSRMask(unsigned MMask, SMLoc S) { - auto Op = std::make_unique(k_MSRMask); + static std::unique_ptr CreateMSRMask(unsigned MMask, SMLoc S, + ARMAsmParser &Parser) { + auto Op = std::make_unique(k_MSRMask, Parser); Op->MMask.Val = MMask; Op->StartLoc = S; Op->EndLoc = S; return Op; } - static std::unique_ptr CreateBankedReg(unsigned Reg, SMLoc S) { - auto Op = std::make_unique(k_BankedReg); + static std::unique_ptr CreateBankedReg(unsigned Reg, SMLoc S, + ARMAsmParser &Parser) { + auto Op = std::make_unique(k_BankedReg, Parser); Op->BankedReg.Val = Reg; Op->StartLoc = S; Op->EndLoc = S; @@ -4328,12 +4368,11 @@ int ARMAsmParser::tryParseShiftRegister(OperandVector &Operands) { } if (ShiftReg && ShiftTy != ARM_AM::rrx) - Operands.push_back(ARMOperand::CreateShiftedRegister(ShiftTy, SrcReg, - ShiftReg, Imm, - S, EndLoc)); + Operands.push_back(ARMOperand::CreateShiftedRegister( + ShiftTy, SrcReg, ShiftReg, Imm, S, EndLoc, *this)); else Operands.push_back(ARMOperand::CreateShiftedImmediate(ShiftTy, SrcReg, Imm, - S, EndLoc)); + S, EndLoc, *this)); return 0; } @@ -4352,12 +4391,13 @@ bool ARMAsmParser::tryParseRegisterWithWriteBack(OperandVector &Operands) { if (RegNo == -1) return true; - Operands.push_back(ARMOperand::CreateReg(RegNo, RegStartLoc, RegEndLoc)); + Operands.push_back( + ARMOperand::CreateReg(RegNo, RegStartLoc, RegEndLoc, *this)); const AsmToken &ExclaimTok = Parser.getTok(); if (ExclaimTok.is(AsmToken::Exclaim)) { Operands.push_back(ARMOperand::CreateToken(ExclaimTok.getString(), - ExclaimTok.getLoc())); + ExclaimTok.getLoc(), *this)); Parser.Lex(); // Eat exclaim token return false; } @@ -4382,9 +4422,8 @@ bool ARMAsmParser::tryParseRegisterWithWriteBack(OperandVector &Operands) { SMLoc E = Parser.getTok().getEndLoc(); Parser.Lex(); // Eat right bracket token. - Operands.push_back(ARMOperand::CreateVectorIndex(MCE->getValue(), - SIdx, E, - getContext())); + Operands.push_back(ARMOperand::CreateVectorIndex(MCE->getValue(), SIdx, E, + getContext(), *this)); } return false; @@ -4451,7 +4490,8 @@ ParseStatus ARMAsmParser::parseITCondCode(OperandVector &Operands) { return ParseStatus::NoMatch; Parser.Lex(); // Eat the token. - Operands.push_back(ARMOperand::CreateCondCode(ARMCC::CondCodes(CC), S)); + Operands.push_back( + ARMOperand::CreateCondCode(ARMCC::CondCodes(CC), S, *this)); return ParseStatus::Success; } @@ -4473,7 +4513,7 @@ ParseStatus ARMAsmParser::parseCoprocNumOperand(OperandVector &Operands) { return ParseStatus::NoMatch; Parser.Lex(); // Eat identifier token. - Operands.push_back(ARMOperand::CreateCoprocNum(Num, S)); + Operands.push_back(ARMOperand::CreateCoprocNum(Num, S, *this)); return ParseStatus::Success; } @@ -4492,7 +4532,7 @@ ParseStatus ARMAsmParser::parseCoprocRegOperand(OperandVector &Operands) { return ParseStatus::NoMatch; Parser.Lex(); // Eat identifier token. - Operands.push_back(ARMOperand::CreateCoprocReg(Reg, S)); + Operands.push_back(ARMOperand::CreateCoprocReg(Reg, S, *this)); return ParseStatus::Success; } @@ -4523,7 +4563,7 @@ ParseStatus ARMAsmParser::parseCoprocOptionOperand(OperandVector &Operands) { SMLoc E = Parser.getTok().getEndLoc(); Parser.Lex(); // Eat the '}' - Operands.push_back(ARMOperand::CreateCoprocOption(Val, S, E)); + Operands.push_back(ARMOperand::CreateCoprocOption(Val, S, E, *this)); return ParseStatus::Success; } @@ -4726,11 +4766,12 @@ bool ARMAsmParser::parseRegisterList(OperandVector &Operands, bool EnforceOrder, Parser.Lex(); // Eat '}' token. // Push the register list operand. - Operands.push_back(ARMOperand::CreateRegList(Registers, S, E)); + Operands.push_back(ARMOperand::CreateRegList(Registers, S, E, *this)); // The ARM system instruction variants for LDM/STM have a '^' token here. if (Parser.getTok().is(AsmToken::Caret)) { - Operands.push_back(ARMOperand::CreateToken("^",Parser.getTok().getLoc())); + Operands.push_back( + ARMOperand::CreateToken("^", Parser.getTok().getLoc(), *this)); Parser.Lex(); // Eat '^' token. } @@ -4803,16 +4844,15 @@ ParseStatus ARMAsmParser::parseVectorList(OperandVector &Operands) { return Res; switch (LaneKind) { case NoLanes: - Operands.push_back(ARMOperand::CreateReg(Reg, S, E)); + Operands.push_back(ARMOperand::CreateReg(Reg, S, E, *this)); break; case AllLanes: - Operands.push_back(ARMOperand::CreateVectorListAllLanes(Reg, 1, false, - S, E)); + Operands.push_back( + ARMOperand::CreateVectorListAllLanes(Reg, 1, false, S, E, *this)); break; case IndexedLane: - Operands.push_back(ARMOperand::CreateVectorListIndexed(Reg, 1, - LaneIndex, - false, S, E)); + Operands.push_back(ARMOperand::CreateVectorListIndexed( + Reg, 1, LaneIndex, false, S, E, *this)); break; } return ParseStatus::Success; @@ -4824,23 +4864,22 @@ ParseStatus ARMAsmParser::parseVectorList(OperandVector &Operands) { return Res; switch (LaneKind) { case NoLanes: - Operands.push_back(ARMOperand::CreateReg(Reg, S, E)); + Operands.push_back(ARMOperand::CreateReg(Reg, S, E, *this)); break; case AllLanes: Reg = MRI->getMatchingSuperReg(Reg, ARM::dsub_0, &ARMMCRegisterClasses[ARM::DPairRegClassID]); - Operands.push_back(ARMOperand::CreateVectorListAllLanes(Reg, 2, false, - S, E)); + Operands.push_back( + ARMOperand::CreateVectorListAllLanes(Reg, 2, false, S, E, *this)); break; case IndexedLane: - Operands.push_back(ARMOperand::CreateVectorListIndexed(Reg, 2, - LaneIndex, - false, S, E)); + Operands.push_back(ARMOperand::CreateVectorListIndexed( + Reg, 2, LaneIndex, false, S, E, *this)); break; } return ParseStatus::Success; } - Operands.push_back(ARMOperand::CreateReg(Reg, S, E)); + Operands.push_back(ARMOperand::CreateReg(Reg, S, E, *this)); return ParseStatus::Success; } @@ -4994,14 +5033,12 @@ ParseStatus ARMAsmParser::parseVectorList(OperandVector &Operands) { } auto Create = (LaneKind == NoLanes ? ARMOperand::CreateVectorList : ARMOperand::CreateVectorListAllLanes); - Operands.push_back(Create(FirstReg, Count, (Spacing == 2), S, E)); + Operands.push_back(Create(FirstReg, Count, (Spacing == 2), S, E, *this)); break; } case IndexedLane: - Operands.push_back(ARMOperand::CreateVectorListIndexed(FirstReg, Count, - LaneIndex, - (Spacing == 2), - S, E)); + Operands.push_back(ARMOperand::CreateVectorListIndexed( + FirstReg, Count, LaneIndex, (Spacing == 2), S, E, *this)); break; } return ParseStatus::Success; @@ -5068,7 +5105,8 @@ ParseStatus ARMAsmParser::parseMemBarrierOptOperand(OperandVector &Operands) { } else return ParseStatus::Failure; - Operands.push_back(ARMOperand::CreateMemBarrierOpt((ARM_MB::MemBOpt)Opt, S)); + Operands.push_back( + ARMOperand::CreateMemBarrierOpt((ARM_MB::MemBOpt)Opt, S, *this)); return ParseStatus::Success; } @@ -5086,7 +5124,8 @@ ARMAsmParser::parseTraceSyncBarrierOptOperand(OperandVector &Operands) { Parser.Lex(); // Eat identifier token. - Operands.push_back(ARMOperand::CreateTraceSyncBarrierOpt(ARM_TSB::CSYNC, S)); + Operands.push_back( + ARMOperand::CreateTraceSyncBarrierOpt(ARM_TSB::CSYNC, S, *this)); return ParseStatus::Success; } @@ -5131,7 +5170,7 @@ ARMAsmParser::parseInstSyncBarrierOptOperand(OperandVector &Operands) { return ParseStatus::Failure; Operands.push_back(ARMOperand::CreateInstSyncBarrierOpt( - (ARM_ISB::InstSyncBOpt)Opt, S)); + (ARM_ISB::InstSyncBOpt)Opt, S, *this)); return ParseStatus::Success; } @@ -5165,7 +5204,8 @@ ParseStatus ARMAsmParser::parseProcIFlagsOperand(OperandVector &Operands) { } Parser.Lex(); // Eat identifier token. - Operands.push_back(ARMOperand::CreateProcIFlags((ARM_PROC::IFlags)IFlags, S)); + Operands.push_back( + ARMOperand::CreateProcIFlags((ARM_PROC::IFlags)IFlags, S, *this)); return ParseStatus::Success; } @@ -5186,7 +5226,7 @@ ParseStatus ARMAsmParser::parseMSRMaskOperand(OperandVector &Operands) { } unsigned SYSmvalue = Val & 0xFF; Parser.Lex(); - Operands.push_back(ARMOperand::CreateMSRMask(SYSmvalue, S)); + Operands.push_back(ARMOperand::CreateMSRMask(SYSmvalue, S, *this)); return ParseStatus::Success; } @@ -5202,7 +5242,7 @@ ParseStatus ARMAsmParser::parseMSRMaskOperand(OperandVector &Operands) { unsigned SYSmvalue = TheReg->Encoding & 0xFFF; Parser.Lex(); // Eat identifier token. - Operands.push_back(ARMOperand::CreateMSRMask(SYSmvalue, S)); + Operands.push_back(ARMOperand::CreateMSRMask(SYSmvalue, S, *this)); return ParseStatus::Success; } @@ -5265,7 +5305,7 @@ ParseStatus ARMAsmParser::parseMSRMaskOperand(OperandVector &Operands) { FlagsVal |= 16; Parser.Lex(); // Eat identifier token. - Operands.push_back(ARMOperand::CreateMSRMask(FlagsVal, S)); + Operands.push_back(ARMOperand::CreateMSRMask(FlagsVal, S, *this)); return ParseStatus::Success; } @@ -5289,7 +5329,7 @@ ParseStatus ARMAsmParser::parseBankedRegOperand(OperandVector &Operands) { unsigned Encoding = TheReg->Encoding; Parser.Lex(); // Eat identifier token. - Operands.push_back(ARMOperand::CreateBankedReg(Encoding, S)); + Operands.push_back(ARMOperand::CreateBankedReg(Encoding, S, *this)); return ParseStatus::Success; } @@ -5331,7 +5371,7 @@ ParseStatus ARMAsmParser::parsePKHImm(OperandVector &Operands, if (Val < Low || Val > High) return Error(Loc, "immediate value out of range"); - Operands.push_back(ARMOperand::CreateImm(CE, Loc, EndLoc)); + Operands.push_back(ARMOperand::CreateImm(CE, Loc, EndLoc, *this)); return ParseStatus::Success; } @@ -5350,9 +5390,8 @@ ParseStatus ARMAsmParser::parseSetEndImm(OperandVector &Operands) { if (Val == -1) return Error(S, "'be' or 'le' operand expected"); - Operands.push_back(ARMOperand::CreateImm(MCConstantExpr::create(Val, - getContext()), - S, Tok.getEndLoc())); + Operands.push_back(ARMOperand::CreateImm( + MCConstantExpr::create(Val, getContext()), S, Tok.getEndLoc(), *this)); return ParseStatus::Success; } @@ -5407,7 +5446,8 @@ ParseStatus ARMAsmParser::parseShifterImm(OperandVector &Operands) { return Error(ExLoc, "'lsr' shift amount must be in range [0,31]"); } - Operands.push_back(ARMOperand::CreateShifterImm(isASR, Val, S, EndLoc)); + Operands.push_back( + ARMOperand::CreateShifterImm(isASR, Val, S, EndLoc, *this)); return ParseStatus::Success; } @@ -5448,7 +5488,7 @@ ParseStatus ARMAsmParser::parseRotImm(OperandVector &Operands) { if (Val != 8 && Val != 16 && Val != 24 && Val != 0) return Error(ExLoc, "'ror' rotate amount must be 8, 16, or 24"); - Operands.push_back(ARMOperand::CreateRotImm(Val, S, EndLoc)); + Operands.push_back(ARMOperand::CreateRotImm(Val, S, EndLoc, *this)); return ParseStatus::Success; } @@ -5498,9 +5538,8 @@ ParseStatus ARMAsmParser::parseModImm(OperandVector &Operands) { int Enc = ARM_AM::getSOImmVal(Imm1); if (Enc != -1 && Parser.getTok().is(AsmToken::EndOfStatement)) { // We have a match! - Operands.push_back(ARMOperand::CreateModImm((Enc & 0xFF), - (Enc & 0xF00) >> 7, - Sx1, Ex1)); + Operands.push_back(ARMOperand::CreateModImm( + (Enc & 0xFF), (Enc & 0xF00) >> 7, Sx1, Ex1, *this)); return ParseStatus::Success; } @@ -5511,13 +5550,13 @@ ParseStatus ARMAsmParser::parseModImm(OperandVector &Operands) { // instruction with a mod_imm operand. The alias is defined such that the // parser method is shared, that's why we have to do this here. if (Parser.getTok().is(AsmToken::EndOfStatement)) { - Operands.push_back(ARMOperand::CreateImm(Imm1Exp, Sx1, Ex1)); + Operands.push_back(ARMOperand::CreateImm(Imm1Exp, Sx1, Ex1, *this)); return ParseStatus::Success; } } else { // Operands like #(l1 - l2) can only be evaluated at a later stage (via an // MCFixup). Fallback to a plain immediate. - Operands.push_back(ARMOperand::CreateImm(Imm1Exp, Sx1, Ex1)); + Operands.push_back(ARMOperand::CreateImm(Imm1Exp, Sx1, Ex1, *this)); return ParseStatus::Success; } @@ -5551,7 +5590,7 @@ ParseStatus ARMAsmParser::parseModImm(OperandVector &Operands) { Imm2 = CE->getValue(); if (!(Imm2 & ~0x1E)) { // We have a match! - Operands.push_back(ARMOperand::CreateModImm(Imm1, Imm2, S, Ex2)); + Operands.push_back(ARMOperand::CreateModImm(Imm1, Imm2, S, Ex2, *this)); return ParseStatus::Success; } return Error(Sx2, @@ -5606,7 +5645,7 @@ ParseStatus ARMAsmParser::parseBitfield(OperandVector &Operands) { if (Width < 1 || Width > 32 - LSB) return Error(E, "'width' operand must be in the range [1,32-lsb]"); - Operands.push_back(ARMOperand::CreateBitfield(LSB, Width, S, EndLoc)); + Operands.push_back(ARMOperand::CreateBitfield(LSB, Width, S, EndLoc, *this)); return ParseStatus::Success; } @@ -5653,8 +5692,8 @@ ParseStatus ARMAsmParser::parsePostIdxReg(OperandVector &Operands) { E = Parser.getTok().getLoc(); } - Operands.push_back(ARMOperand::CreatePostIdxReg(Reg, isAdd, ShiftTy, - ShiftImm, S, E)); + Operands.push_back( + ARMOperand::CreatePostIdxReg(Reg, isAdd, ShiftTy, ShiftImm, S, E, *this)); return ParseStatus::Success; } @@ -5695,8 +5734,8 @@ ParseStatus ARMAsmParser::parseAM3Offset(OperandVector &Operands) { if (isNegative && Val == 0) Val = std::numeric_limits::min(); - Operands.push_back( - ARMOperand::CreateImm(MCConstantExpr::create(Val, getContext()), S, E)); + Operands.push_back(ARMOperand::CreateImm( + MCConstantExpr::create(Val, getContext()), S, E, *this)); return ParseStatus::Success; } @@ -5720,8 +5759,8 @@ ParseStatus ARMAsmParser::parseAM3Offset(OperandVector &Operands) { return Error(Tok.getLoc(), "register expected"); } - Operands.push_back(ARMOperand::CreatePostIdxReg(Reg, isAdd, ARM_AM::no_shift, - 0, S, Tok.getEndLoc())); + Operands.push_back(ARMOperand::CreatePostIdxReg( + Reg, isAdd, ARM_AM::no_shift, 0, S, Tok.getEndLoc(), *this)); return ParseStatus::Success; } @@ -5780,7 +5819,8 @@ void ARMAsmParser::cvtThumbMultiply(MCInst &Inst, if (CondOutI != 0) { ((ARMOperand &)*Operands[CondOutI]).addCCOutOperands(Inst, 1); } else { - ARMOperand Op = *ARMOperand::CreateCCOut(0, Operands[0]->getEndLoc()); + ARMOperand Op = + *ARMOperand::CreateCCOut(0, Operands[0]->getEndLoc(), *this); Op.addCCOutOperands(Inst, 1); } // Rn @@ -5792,8 +5832,8 @@ void ARMAsmParser::cvtThumbMultiply(MCInst &Inst, if (CondI != 0) { ((ARMOperand &)*Operands[CondI]).addCondCodeOperands(Inst, 2); } else { - ARMOperand Op = - *ARMOperand::CreateCondCode(llvm::ARMCC::AL, Operands[0]->getEndLoc()); + ARMOperand Op = *ARMOperand::CreateCondCode( + llvm::ARMCC::AL, Operands[0]->getEndLoc(), *this); Op.addCondCodeOperands(Inst, 2); } } @@ -5849,8 +5889,8 @@ void ARMAsmParser::cvtThumbBranches(MCInst &Inst, if (CondI != 0) { ((ARMOperand &)*Operands[CondI]).addCondCodeOperands(Inst, 2); } else { - ARMOperand Op = - *ARMOperand::CreateCondCode(llvm::ARMCC::AL, Operands[0]->getEndLoc()); + ARMOperand Op = *ARMOperand::CreateCondCode( + llvm::ARMCC::AL, Operands[0]->getEndLoc(), *this); Op.addCondCodeOperands(Inst, 2); } } @@ -5879,7 +5919,7 @@ void ARMAsmParser::cvtMVEVMOVQtoDReg( .addCondCodeOperands(Inst, 2); // condition code } else { ARMOperand Op = - *ARMOperand::CreateCondCode(ARMCC::AL, Operands[0]->getEndLoc()); + *ARMOperand::CreateCondCode(ARMCC::AL, Operands[0]->getEndLoc(), *this); Op.addCondCodeOperands(Inst, 2); } } @@ -5909,14 +5949,14 @@ bool ARMAsmParser::parseMemory(OperandVector &Operands) { E = Tok.getEndLoc(); Parser.Lex(); // Eat right bracket token. - Operands.push_back(ARMOperand::CreateMem(BaseRegNum, nullptr, 0, - ARM_AM::no_shift, 0, 0, false, - S, E)); + Operands.push_back(ARMOperand::CreateMem( + BaseRegNum, nullptr, 0, ARM_AM::no_shift, 0, 0, false, S, E, *this)); // If there's a pre-indexing writeback marker, '!', just add it as a token // operand. It's rather odd, but syntactically valid. if (Parser.getTok().is(AsmToken::Exclaim)) { - Operands.push_back(ARMOperand::CreateToken("!",Parser.getTok().getLoc())); + Operands.push_back( + ARMOperand::CreateToken("!", Parser.getTok().getLoc(), *this)); Parser.Lex(); // Eat the '!'. } @@ -5967,13 +6007,14 @@ bool ARMAsmParser::parseMemory(OperandVector &Operands) { // Don't worry about range checking the value here. That's handled by // the is*() predicates. Operands.push_back(ARMOperand::CreateMem(BaseRegNum, nullptr, 0, - ARM_AM::no_shift, 0, Align, - false, S, E, AlignmentLoc)); + ARM_AM::no_shift, 0, Align, false, + S, E, *this, AlignmentLoc)); // If there's a pre-indexing writeback marker, '!', just add it as a token // operand. if (Parser.getTok().is(AsmToken::Exclaim)) { - Operands.push_back(ARMOperand::CreateToken("!",Parser.getTok().getLoc())); + Operands.push_back( + ARMOperand::CreateToken("!", Parser.getTok().getLoc(), *this)); Parser.Lex(); // Eat the '!'. } @@ -6009,8 +6050,9 @@ bool ARMAsmParser::parseMemory(OperandVector &Operands) { AdjustedOffset = CE; } else AdjustedOffset = Offset; - Operands.push_back(ARMOperand::CreateMem( - BaseRegNum, AdjustedOffset, 0, ARM_AM::no_shift, 0, 0, false, S, E)); + Operands.push_back(ARMOperand::CreateMem(BaseRegNum, AdjustedOffset, 0, + ARM_AM::no_shift, 0, 0, false, S, + E, *this)); // Now we should have the closing ']' if (Parser.getTok().isNot(AsmToken::RBrac)) @@ -6021,7 +6063,8 @@ bool ARMAsmParser::parseMemory(OperandVector &Operands) { // If there's a pre-indexing writeback marker, '!', just add it as a token // operand. if (Parser.getTok().is(AsmToken::Exclaim)) { - Operands.push_back(ARMOperand::CreateToken("!",Parser.getTok().getLoc())); + Operands.push_back( + ARMOperand::CreateToken("!", Parser.getTok().getLoc(), *this)); Parser.Lex(); // Eat the '!'. } @@ -6060,12 +6103,13 @@ bool ARMAsmParser::parseMemory(OperandVector &Operands) { Operands.push_back(ARMOperand::CreateMem(BaseRegNum, nullptr, OffsetRegNum, ShiftType, ShiftImm, 0, isNegative, - S, E)); + S, E, *this)); // If there's a pre-indexing writeback marker, '!', just add it as a token // operand. if (Parser.getTok().is(AsmToken::Exclaim)) { - Operands.push_back(ARMOperand::CreateToken("!",Parser.getTok().getLoc())); + Operands.push_back( + ARMOperand::CreateToken("!", Parser.getTok().getLoc(), *this)); Parser.Lex(); // Eat the '!'. } @@ -6203,9 +6247,9 @@ ParseStatus ARMAsmParser::parseFPImm(OperandVector &Operands) { // If we had a '-' in front, toggle the sign bit. IntVal ^= (uint64_t)isNegative << 31; Parser.Lex(); // Eat the token. - Operands.push_back(ARMOperand::CreateImm( - MCConstantExpr::create(IntVal, getContext()), - S, Parser.getTok().getLoc())); + Operands.push_back( + ARMOperand::CreateImm(MCConstantExpr::create(IntVal, getContext()), S, + Parser.getTok().getLoc(), *this)); return ParseStatus::Success; } // Also handle plain integers. Instructions which allow floating point @@ -6218,9 +6262,9 @@ ParseStatus ARMAsmParser::parseFPImm(OperandVector &Operands) { float RealVal = ARM_AM::getFPImmFloat(Val); Val = APFloat(RealVal).bitcastToAPInt().getZExtValue(); - Operands.push_back(ARMOperand::CreateImm( - MCConstantExpr::create(Val, getContext()), S, - Parser.getTok().getLoc())); + Operands.push_back( + ARMOperand::CreateImm(MCConstantExpr::create(Val, getContext()), S, + Parser.getTok().getLoc(), *this)); return ParseStatus::Success; } @@ -6266,7 +6310,7 @@ bool ARMAsmParser::parseOperand(OperandVector &Operands, StringRef Mnemonic) { Parser.getTok().getString().equals_insensitive("apsr_nzcv")) { S = Parser.getTok().getLoc(); Parser.Lex(); - Operands.push_back(ARMOperand::CreateToken("APSR_nzcv", S)); + Operands.push_back(ARMOperand::CreateToken("APSR_nzcv", S, *this)); return false; } } @@ -6286,7 +6330,7 @@ bool ARMAsmParser::parseOperand(OperandVector &Operands, StringRef Mnemonic) { if (getParser().parseExpression(IdVal)) return true; E = SMLoc::getFromPointer(Parser.getTok().getLoc().getPointer() - 1); - Operands.push_back(ARMOperand::CreateImm(IdVal, S, E)); + Operands.push_back(ARMOperand::CreateImm(IdVal, S, E, *this)); return false; } case AsmToken::LBrac: @@ -6330,14 +6374,14 @@ bool ARMAsmParser::parseOperand(OperandVector &Operands, StringRef Mnemonic) { getContext()); } E = SMLoc::getFromPointer(Parser.getTok().getLoc().getPointer() - 1); - Operands.push_back(ARMOperand::CreateImm(ImmVal, S, E)); + Operands.push_back(ARMOperand::CreateImm(ImmVal, S, E, *this)); // There can be a trailing '!' on operands that we want as a separate // '!' Token operand. Handle that here. For example, the compatibility // alias for 'srsdb sp!, #imm' is 'srsdb #imm!'. if (Parser.getTok().is(AsmToken::Exclaim)) { - Operands.push_back(ARMOperand::CreateToken(Parser.getTok().getString(), - Parser.getTok().getLoc())); + Operands.push_back(ARMOperand::CreateToken( + Parser.getTok().getString(), Parser.getTok().getLoc(), *this)); Parser.Lex(); // Eat exclaim token } return false; @@ -6362,7 +6406,7 @@ bool ARMAsmParser::parseOperand(OperandVector &Operands, StringRef Mnemonic) { const MCExpr *ExprVal = ARMMCExpr::create(RefKind, SubExprVal, getContext()); E = SMLoc::getFromPointer(Parser.getTok().getLoc().getPointer() - 1); - Operands.push_back(ARMOperand::CreateImm(ExprVal, S, E)); + Operands.push_back(ARMOperand::CreateImm(ExprVal, S, E, *this)); return false; } case AsmToken::Equal: { @@ -6377,7 +6421,8 @@ bool ARMAsmParser::parseOperand(OperandVector &Operands, StringRef Mnemonic) { // execute-only: we assume that assembly programmers know what they are // doing and allow literal pool creation here - Operands.push_back(ARMOperand::CreateConstantPoolImm(SubExprVal, S, E)); + Operands.push_back( + ARMOperand::CreateConstantPoolImm(SubExprVal, S, E, *this)); return false; } } @@ -6913,9 +6958,9 @@ void ARMAsmParser::fixupGNULDRDAlias(StringRef Mnemonic, (PairedReg == ARM::SP && !hasV8Ops())) return; - Operands.insert( - Operands.begin() + IdX + 1, - ARMOperand::CreateReg(PairedReg, Op2.getStartLoc(), Op2.getEndLoc())); + Operands.insert(Operands.begin() + IdX + 1, + ARMOperand::CreateReg(PairedReg, Op2.getStartLoc(), + Op2.getEndLoc(), *this)); } // Dual-register instruction have the following syntax: @@ -6975,7 +7020,7 @@ bool ARMAsmParser::CDEConvertDualRegOperand(StringRef Mnemonic, Operands.erase(Operands.begin() + MnemonicOpsEndInd + 2); Operands[MnemonicOpsEndInd + 1] = - ARMOperand::CreateReg(RPair, Op2.getStartLoc(), Op2.getEndLoc()); + ARMOperand::CreateReg(RPair, Op2.getStartLoc(), Op2.getEndLoc(), *this); return false; } @@ -7048,7 +7093,7 @@ bool ARMAsmParser::ParseInstruction(ParseInstructionInfo &Info, StringRef Name, return Error(NameLoc, "conditional execution not supported in Thumb1"); } - Operands.push_back(ARMOperand::CreateToken(Mnemonic, NameLoc)); + Operands.push_back(ARMOperand::CreateToken(Mnemonic, NameLoc, *this)); // Handle the mask for IT and VPT instructions. In ARMOperand and // MCOperand, this is stored in a format independent of the @@ -7080,7 +7125,7 @@ bool ARMAsmParser::ParseInstruction(ParseInstructionInfo &Info, StringRef Name, if (Pos == 'e') Mask |= 8; } - Operands.push_back(ARMOperand::CreateITMask(Mask, Loc)); + Operands.push_back(ARMOperand::CreateITMask(Mask, Loc, *this)); } // FIXME: This is all a pretty gross hack. We should automatically handle @@ -7120,8 +7165,8 @@ bool ARMAsmParser::ParseInstruction(ParseInstructionInfo &Info, StringRef Name, // Add the carry setting operand, if necessary. if (CanAcceptCarrySet && CarrySetting) { SMLoc Loc = SMLoc::getFromPointer(NameLoc.getPointer() + Mnemonic.size()); - Operands.push_back(ARMOperand::CreateCCOut(CarrySetting ? ARM::CPSR : 0, - Loc)); + Operands.push_back( + ARMOperand::CreateCCOut(CarrySetting ? ARM::CPSR : 0, Loc, *this)); } // Add the predication code operand, if necessary. @@ -7129,7 +7174,7 @@ bool ARMAsmParser::ParseInstruction(ParseInstructionInfo &Info, StringRef Name, SMLoc Loc = SMLoc::getFromPointer(NameLoc.getPointer() + Mnemonic.size() + CarrySetting); Operands.push_back(ARMOperand::CreateCondCode( - ARMCC::CondCodes(PredicationCode), Loc)); + ARMCC::CondCodes(PredicationCode), Loc, *this)); } // Add the VPT predication code operand, if necessary. @@ -7141,14 +7186,14 @@ bool ARMAsmParser::ParseInstruction(ParseInstructionInfo &Info, StringRef Name, SMLoc Loc = SMLoc::getFromPointer(NameLoc.getPointer() + Mnemonic.size() + CarrySetting); Operands.push_back(ARMOperand::CreateVPTPred( - ARMVCC::VPTCodes(VPTPredicationCode), Loc)); + ARMVCC::VPTCodes(VPTPredicationCode), Loc, *this)); } // Add the processor imod operand, if necessary. if (ProcessorIMod) { Operands.push_back(ARMOperand::CreateImm( - MCConstantExpr::create(ProcessorIMod, getContext()), - NameLoc, NameLoc)); + MCConstantExpr::create(ProcessorIMod, getContext()), NameLoc, NameLoc, + *this)); } else if (Mnemonic == "cps" && isMClass()) { return Error(NameLoc, "instruction 'cps' requires effect for M-class"); } @@ -7177,7 +7222,7 @@ bool ARMAsmParser::ParseInstruction(ParseInstructionInfo &Info, StringRef Name, // so discard it to avoid errors that can be caused by the matcher. if (ExtraToken != ".n" && (isThumb() || ExtraToken != ".w")) { SMLoc Loc = SMLoc::getFromPointer(NameLoc.getPointer() + Start); - Operands.push_back(ARMOperand::CreateToken(ExtraToken, Loc)); + Operands.push_back(ARMOperand::CreateToken(ExtraToken, Loc, *this)); } } @@ -7236,9 +7281,9 @@ bool ARMAsmParser::ParseInstruction(ParseInstructionInfo &Info, StringRef Name, SMLoc PLoc = SMLoc::getFromPointer(NameLoc.getPointer() + Mnemonic.size() - 1 + CarrySetting); Operands.insert(Operands.begin(), - ARMOperand::CreateVPTPred(ARMVCC::None, PLoc)); - Operands.insert(Operands.begin(), - ARMOperand::CreateToken(StringRef("vmovlt"), MLoc)); + ARMOperand::CreateVPTPred(ARMVCC::None, PLoc, *this)); + Operands.insert(Operands.begin(), ARMOperand::CreateToken( + StringRef("vmovlt"), MLoc, *this)); } else if (Mnemonic == "vcvt" && PredicationCode == ARMCC::NE && !shouldOmitVectorPredicateOperand(Mnemonic, Operands, MnemonicOpsEndInd)) { @@ -7252,9 +7297,9 @@ bool ARMAsmParser::ParseInstruction(ParseInstructionInfo &Info, StringRef Name, SMLoc PLoc = SMLoc::getFromPointer(NameLoc.getPointer() + Mnemonic.size() - 1 + CarrySetting); Operands.insert(Operands.begin(), - ARMOperand::CreateVPTPred(ARMVCC::Else, PLoc)); + ARMOperand::CreateVPTPred(ARMVCC::Else, PLoc, *this)); Operands.insert(Operands.begin(), - ARMOperand::CreateToken(StringRef("vcvtn"), MLoc)); + ARMOperand::CreateToken(StringRef("vcvtn"), MLoc, *this)); } else if (Mnemonic == "vmul" && PredicationCode == ARMCC::LT && !shouldOmitVectorPredicateOperand(Mnemonic, Operands, MnemonicOpsEndInd)) { @@ -7264,8 +7309,8 @@ bool ARMAsmParser::ParseInstruction(ParseInstructionInfo &Info, StringRef Name, removeCondCode(Operands, MnemonicOpsEndInd); Operands.erase(Operands.begin()); SMLoc MLoc = SMLoc::getFromPointer(NameLoc.getPointer()); - Operands.insert(Operands.begin(), - ARMOperand::CreateToken(StringRef("vmullt"), MLoc)); + Operands.insert(Operands.begin(), ARMOperand::CreateToken( + StringRef("vmullt"), MLoc, *this)); } else if (Mnemonic.starts_with("vcvt") && !Mnemonic.starts_with("vcvta") && !Mnemonic.starts_with("vcvtn") && !Mnemonic.starts_with("vcvtp") && @@ -7291,7 +7336,7 @@ bool ARMAsmParser::ParseInstruction(ParseInstructionInfo &Info, StringRef Name, Mnemonic = Mnemonic.substr(0, 4); Operands.insert(Operands.begin(), - ARMOperand::CreateToken(Mnemonic, MLoc)); + ARMOperand::CreateToken(Mnemonic, MLoc, *this)); } } SMLoc PLoc = SMLoc::getFromPointer(NameLoc.getPointer() + @@ -7299,7 +7344,7 @@ bool ARMAsmParser::ParseInstruction(ParseInstructionInfo &Info, StringRef Name, // Add VPTPred Operands.insert(Operands.begin() + 1, ARMOperand::CreateVPTPred( - ARMVCC::VPTCodes(VPTPredicationCode), PLoc)); + ARMVCC::VPTCodes(VPTPredicationCode), PLoc, *this)); ++MnemonicOpsEndInd; } } else if (CanAcceptVPTPredicationCode) { @@ -7329,7 +7374,7 @@ bool ARMAsmParser::ParseInstruction(ParseInstructionInfo &Info, StringRef Name, Mnemonic = Name.slice(0, Mnemonic.size() + 1); Operands.erase(Operands.begin()); Operands.insert(Operands.begin(), - ARMOperand::CreateToken(Mnemonic, NameLoc)); + ARMOperand::CreateToken(Mnemonic, NameLoc, *this)); } } @@ -7383,9 +7428,8 @@ bool ARMAsmParser::ParseInstruction(ParseInstructionInfo &Info, StringRef Name, unsigned NewReg = MRI->getMatchingSuperReg( Reg1, ARM::gsub_0, &(MRI->getRegClass(ARM::GPRPairRegClassID))); - - Operands[Idx] = - ARMOperand::CreateReg(NewReg, Op1.getStartLoc(), Op2.getEndLoc()); + Operands[Idx] = ARMOperand::CreateReg(NewReg, Op1.getStartLoc(), + Op2.getEndLoc(), *this); Operands.erase(Operands.begin() + Idx + 1); } } @@ -7404,7 +7448,7 @@ bool ARMAsmParser::ParseInstruction(ParseInstructionInfo &Info, StringRef Name, static_cast(*Operands[MnemonicOpsEndInd + 1]).getReg() == ARM::LR && static_cast(*Operands[MnemonicOpsEndInd + 2]).isImm()) { - Operands.front() = ARMOperand::CreateToken(Name, NameLoc); + Operands.front() = ARMOperand::CreateToken(Name, NameLoc, *this); removeCCOut(Operands, MnemonicOpsEndInd); } return false; @@ -13003,29 +13047,6 @@ unsigned ARMAsmParser::validateTargetOperandClass(MCParsedAsmOperand &AsmOp, if (hasV8Ops() && Op.isReg() && Op.getReg() == ARM::SP) return Match_Success; return Match_rGPR; - // Note: This mutates the operand which could cause issues for future - // matches if this one fails later. - // It would be better to do this in addVecList but as this doesn't have access - // to MRI this isn't possible. - // If trying to match a VecListDPair with a Q register, convert Q to list. - case MCK_VecListDPair: - if (Op.isQReg() && !hasMVE()) { - auto DPair = getDRegFromQReg(Op.getReg()); - DPair = MRI->getMatchingSuperReg( - DPair, ARM::dsub_0, &ARMMCRegisterClasses[ARM::DPairRegClassID]); - Op.setVecListDPair(DPair); - return Match_Success; - } - return Match_InvalidOperand; - // Note: This mutates the operand (see above). - // If trying to match a VecListDPair with a D register, convert D singleton - // list. - case MCK_VecListOneD: - if (Op.isDReg() && !hasMVE()) { - Op.setVecListOneD(Op.getReg()); - return Match_Success; - } - return Match_InvalidOperand; } return Match_InvalidOperand; } @@ -13075,13 +13096,13 @@ bool ARMAsmParser::isMnemonicVPTPredicable(StringRef Mnemonic, } std::unique_ptr ARMAsmParser::defaultCondCodeOp() { - return ARMOperand::CreateCondCode(ARMCC::AL, SMLoc()); + return ARMOperand::CreateCondCode(ARMCC::AL, SMLoc(), *this); } std::unique_ptr ARMAsmParser::defaultCCOutOp() { - return ARMOperand::CreateCCOut(0, SMLoc()); + return ARMOperand::CreateCCOut(0, SMLoc(), *this); } std::unique_ptr ARMAsmParser::defaultVPTPredOp() { - return ARMOperand::CreateVPTPred(ARMVCC::None, SMLoc()); + return ARMOperand::CreateVPTPred(ARMVCC::None, SMLoc(), *this); } -- GitLab From d7975c9d93fb4a69c0bd79d7d5b3f6be77a25c73 Mon Sep 17 00:00:00 2001 From: Alexey Bataev Date: Thu, 28 Mar 2024 10:35:15 -0400 Subject: [PATCH 061/788] [SLP]Add better minbitwidth analysis for udiv/urem instructions. Adds improved bitwidth analysis for udiv/urem instructions. The analysis is based on similar version in InstCombiner. Reviewers: RKSimon Reviewed By: RKSimon Pull Request: https://github.com/llvm/llvm-project/pull/85928 --- .../Transforms/Vectorize/SLPVectorizer.cpp | 22 +++++++++++++++++++ .../X86/reorder-possible-strided-node.ll | 8 ++----- 2 files changed, 24 insertions(+), 6 deletions(-) diff --git a/llvm/lib/Transforms/Vectorize/SLPVectorizer.cpp b/llvm/lib/Transforms/Vectorize/SLPVectorizer.cpp index 961380ce4ad9..c055091feeb4 100644 --- a/llvm/lib/Transforms/Vectorize/SLPVectorizer.cpp +++ b/llvm/lib/Transforms/Vectorize/SLPVectorizer.cpp @@ -14190,6 +14190,28 @@ bool BoUpSLP::collectValuesToDemote( return false; break; } + case Instruction::UDiv: + case Instruction::URem: { + if (ITE->UserTreeIndices.size() > 1 && !IsPotentiallyTruncated(I, BitWidth)) + return false; + // UDiv and URem can be truncated if all the truncated bits are zero. + if (!AttemptCheckBitwidth( + [&](unsigned BitWidth, unsigned OrigBitWidth) { + assert(BitWidth <= OrigBitWidth && "Unexpected bitwidths!"); + APInt Mask = APInt::getBitsSetFrom(OrigBitWidth, BitWidth); + return MaskedValueIsZero(I->getOperand(0), Mask, + SimplifyQuery(*DL)) && + MaskedValueIsZero(I->getOperand(1), Mask, + SimplifyQuery(*DL)); + }, + NeedToExit)) + return false; + if (NeedToExit) + return true; + if (!ProcessOperands({I->getOperand(0), I->getOperand(1)}, NeedToExit)) + return false; + break; + } // We can demote selects if we can demote their true and false values. case Instruction::Select: { diff --git a/llvm/test/Transforms/SLPVectorizer/X86/reorder-possible-strided-node.ll b/llvm/test/Transforms/SLPVectorizer/X86/reorder-possible-strided-node.ll index 4a23abf182e8..cfbbe14186b5 100644 --- a/llvm/test/Transforms/SLPVectorizer/X86/reorder-possible-strided-node.ll +++ b/llvm/test/Transforms/SLPVectorizer/X86/reorder-possible-strided-node.ll @@ -116,9 +116,7 @@ define void @test_div() { ; CHECK-NEXT: [[TMP1:%.*]] = load <4 x i32>, ptr [[ARRAYIDX22]], align 4 ; CHECK-NEXT: [[TMP2:%.*]] = shufflevector <4 x i32> [[TMP1]], <4 x i32> poison, <4 x i32> ; CHECK-NEXT: [[TMP3:%.*]] = mul <4 x i32> [[TMP2]], [[TMP0]] -; CHECK-NEXT: [[TMP4:%.*]] = zext <4 x i32> [[TMP3]] to <4 x i64> -; CHECK-NEXT: [[TMP5:%.*]] = udiv <4 x i64> [[TMP4]], -; CHECK-NEXT: [[TMP6:%.*]] = trunc <4 x i64> [[TMP5]] to <4 x i32> +; CHECK-NEXT: [[TMP6:%.*]] = udiv <4 x i32> [[TMP3]], ; CHECK-NEXT: store <4 x i32> [[TMP6]], ptr getelementptr inbounds ([4 x i32], ptr null, i64 8, i64 0), align 16 ; CHECK-NEXT: ret void ; @@ -170,9 +168,7 @@ define void @test_rem() { ; CHECK-NEXT: [[TMP1:%.*]] = load <4 x i32>, ptr [[ARRAYIDX22]], align 4 ; CHECK-NEXT: [[TMP2:%.*]] = shufflevector <4 x i32> [[TMP1]], <4 x i32> poison, <4 x i32> ; CHECK-NEXT: [[TMP3:%.*]] = mul <4 x i32> [[TMP2]], [[TMP0]] -; CHECK-NEXT: [[TMP4:%.*]] = zext <4 x i32> [[TMP3]] to <4 x i64> -; CHECK-NEXT: [[TMP5:%.*]] = urem <4 x i64> [[TMP4]], -; CHECK-NEXT: [[TMP6:%.*]] = trunc <4 x i64> [[TMP5]] to <4 x i32> +; CHECK-NEXT: [[TMP6:%.*]] = urem <4 x i32> [[TMP3]], ; CHECK-NEXT: store <4 x i32> [[TMP6]], ptr getelementptr inbounds ([4 x i32], ptr null, i64 8, i64 0), align 16 ; CHECK-NEXT: ret void ; -- GitLab From d7753989eaa38e8b7a4ff01d8fced726eea3e34b Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Andrzej=20Warzy=C5=84ski?= Date: Thu, 28 Mar 2024 14:52:08 +0000 Subject: [PATCH 062/788] [mlir][linalg] Add e2e test for linalg.mmt4d + pack/unpack (#84964) This is a follow-up for #81790. This patch basically extends: * test/Integration/Dialect/Linalg/CPU/mmt4d.mlir with pack/unpack ops so that to overall computation is a matrix multiplication (as opposed to linalg.mmt4d). For comparison (and to make it easier to verify correctness), linalg.matmul is also included in the test. --- .../Dialect/Linalg/CPU/pack-unpack-mmt4d.mlir | 173 ++++++++++++++++++ 1 file changed, 173 insertions(+) create mode 100644 mlir/test/Integration/Dialect/Linalg/CPU/pack-unpack-mmt4d.mlir diff --git a/mlir/test/Integration/Dialect/Linalg/CPU/pack-unpack-mmt4d.mlir b/mlir/test/Integration/Dialect/Linalg/CPU/pack-unpack-mmt4d.mlir new file mode 100644 index 000000000000..5680882dccb1 --- /dev/null +++ b/mlir/test/Integration/Dialect/Linalg/CPU/pack-unpack-mmt4d.mlir @@ -0,0 +1,173 @@ +// DEFINE: %{compile} = mlir-opt %s \ +// DEFINE: -transform-interpreter -test-transform-dialect-erase-schedule \ +// DEFINE: -one-shot-bufferize="bufferize-function-boundaries" \ +// DEFINE: -buffer-deallocation-pipeline="private-function-dynamic-ownership" \ +// DEFINE: -cse -canonicalize -test-lower-to-llvm +// DEFINE: %{entry_point} = main +// DEFINE: %{run} = mlir-cpu-runner -e %{entry_point} -entry-point-result=void \ +// DEFINE: -shared-libs=%mlir_runner_utils,%mlir_c_runner_utils + +// RUN: %{compile} | %{run} | FileCheck %s + +/// End-to-end test for computing matrix-multiplication using linalg.mmt4d. In +/// particular, demonstrates how the following MLIR sequence (implemented in @mmt4d): +/// +/// A_pack = tensor.pack A +/// B_pack = tensor.pack B +/// C_pack = tensor.pack C +/// out_pack = linalg.mmt4d(A_pack, B_pack, C_pack) +/// +/// is equivalent to: +/// +/// linalg.matmul(A, B, C) +/// +/// (implemented in @matmul). + +func.func @main() { + // Allocate and initialise the inputs + %A_alloc = tensor.empty() : tensor<7x16xi32> + %B_alloc = tensor.empty() : tensor<16x13xi32> + + %three = arith.constant 3 : i32 + %four = arith.constant 4 : i32 + %A = linalg.fill ins(%three : i32) outs(%A_alloc : tensor<7x16xi32>) -> tensor<7x16xi32> + %B = linalg.fill ins(%four : i32) outs(%B_alloc : tensor<16x13xi32>) -> tensor<16x13xi32> + %C = arith.constant dense<[ + [ 1, 8, 15, 22, 29, 36, 43, 50, 57, 64, 71, 78, 85], + [ 2, 9, 16, 23, 30, 37, 44, 51, 58, 65, 72, 79, 86], + [ 3, 10, 17, 24, 31, 38, 45, 52, 59, 66, 73, 80, 87], + [ 4, 11, 18, 25, 32, 39, 46, 53, 60, 67, 74, 81, 88], + [ 5, 12, 19, 26, 33, 40, 47, 54, 61, 68, 75, 82, 89], + [ 6, 13, 20, 27, 34, 41, 48, 55, 62, 69, 76, 83, 90], + [ 7, 14, 21, 28, 35, 42, 49, 56, 63, 70, 77, 84, 91] + ]> : tensor<7x13xi32> + + // Matrix multiplication via linalg.mmt4d + // CHECK: Unranked Memref + // CHECK: [193, 200, 207, 214, 221, 228, 235, 242, 249, 256, 263, 270, 277] + // CHECK: [194, 201, 208, 215, 222, 229, 236, 243, 250, 257, 264, 271, 278] + // CHECK: [195, 202, 209, 216, 223, 230, 237, 244, 251, 258, 265, 272, 279] + // CHECK: [196, 203, 210, 217, 224, 231, 238, 245, 252, 259, 266, 273, 280] + // CHECK: [197, 204, 211, 218, 225, 232, 239, 246, 253, 260, 267, 274, 281] + // CHECK: [198, 205, 212, 219, 226, 233, 240, 247, 254, 261, 268, 275, 282] + // CHECK: [199, 206, 213, 220, 227, 234, 241, 248, 255, 262, 269, 276, 283] + %C_mmt4d = func.call @mmt4d(%A, %B, %C) : (tensor<7x16xi32>, tensor<16x13xi32>, tensor<7x13xi32>) -> tensor<7x13xi32> + %xf = tensor.cast %C_mmt4d : tensor<7x13xi32> to tensor<*xi32> + call @printMemrefI32(%xf) : (tensor<*xi32>) -> () + + // Matrix multiplication with linalg.matmul + // CHECK: Unranked Memref + // CHECK: [193, 200, 207, 214, 221, 228, 235, 242, 249, 256, 263, 270, 277] + // CHECK: [194, 201, 208, 215, 222, 229, 236, 243, 250, 257, 264, 271, 278] + // CHECK: [195, 202, 209, 216, 223, 230, 237, 244, 251, 258, 265, 272, 279] + // CHECK: [196, 203, 210, 217, 224, 231, 238, 245, 252, 259, 266, 273, 280] + // CHECK: [197, 204, 211, 218, 225, 232, 239, 246, 253, 260, 267, 274, 281] + // CHECK: [198, 205, 212, 219, 226, 233, 240, 247, 254, 261, 268, 275, 282] + // CHECK: [199, 206, 213, 220, 227, 234, 241, 248, 255, 262, 269, 276, 283] + %C_matmul = func.call @matmul(%A, %B, %C) : (tensor<7x16xi32>, tensor<16x13xi32>, tensor<7x13xi32>) -> tensor<7x13xi32> + %xf_2 = tensor.cast %C_matmul : tensor<7x13xi32> to tensor<*xi32> + call @printMemrefI32(%xf_2) : (tensor<*xi32>) -> () + + return +} + +func.func private @matmul(%A: tensor<7x16xi32>, %B: tensor<16x13xi32>, %C: tensor<7x13xi32>) -> tensor<7x13xi32> { + %C_matmul = linalg.matmul ins(%A, %B: tensor<7x16xi32>, tensor<16x13xi32>) + outs(%C: tensor<7x13xi32>) -> tensor<7x13xi32> + + return %C_matmul : tensor<7x13xi32> +} + +func.func private @mmt4d(%A: tensor<7x16xi32>, %B: tensor<16x13xi32>, %C: tensor<7x13xi32>) -> tensor<7x13xi32> { + %zero = arith.constant 0 : i32 + + %A_pack_empty = tensor.empty() : tensor<2x16x8x1xi32> + %B_pack_empty = tensor.empty() : tensor<2x16x8x1xi32> + %C_pack_empty = tensor.empty() : tensor<2x2x8x8xi32> + + // Pack matrices + %A_pack = tensor.pack %A padding_value(%zero : i32) inner_dims_pos = [0, 1] inner_tiles = [8, 1] into %A_pack_empty : tensor<7x16xi32> -> tensor<2x16x8x1xi32> + %B_pack = tensor.pack %B padding_value(%zero : i32) outer_dims_perm = [1, 0] inner_dims_pos = [1, 0] inner_tiles = [8, 1] into %B_pack_empty : tensor<16x13xi32> -> tensor<2x16x8x1xi32> + %C_pack = tensor.pack %C padding_value(%zero : i32) outer_dims_perm = [0, 1] inner_dims_pos = [0, 1] inner_tiles = [8, 8] into %C_pack_empty : tensor<7x13xi32> -> tensor<2x2x8x8xi32> + + // MMT4D + %mmt4d = linalg.mmt4d ins(%A_pack, %B_pack : tensor<2x16x8x1xi32>, tensor<2x16x8x1xi32>) outs(%C_pack : tensor<2x2x8x8xi32>) -> tensor<2x2x8x8xi32> + + // Unpack output + %C_out_empty = tensor.empty() : tensor<7x13xi32> + %C_out_unpack = tensor.unpack %mmt4d outer_dims_perm = [0, 1] inner_dims_pos = [0, 1] inner_tiles = [8, 8] into %C_out_empty : tensor<2x2x8x8xi32> -> tensor<7x13xi32> + + return %C_out_unpack : tensor<7x13xi32> +} + +module @transforms attributes { transform.with_named_sequence } { + transform.named_sequence @__transform_main(%module: !transform.any_op {transform.readonly}) { + %mmt4d = transform.collect_matching @match_mmt4d in %module : (!transform.any_op) -> (!transform.any_op) + %func = transform.get_parent_op %mmt4d {isolated_from_above} : (!transform.any_op) -> !transform.op<"func.func"> + + // Step 1: Tile + // Tile parallel dims + %tiled_linalg_op_p, %loops:4 = transform.structured.tile_using_for %mmt4d[1, 1, 0, 8, 8, 0] + : (!transform.any_op) -> (!transform.any_op, !transform.any_op, !transform.any_op, !transform.any_op, !transform.any_op) + // Tile reduction dims + %tiled_linalg_op_r, %loops2:2 = transform.structured.tile_using_for %tiled_linalg_op_p[0, 0, 1, 0, 0, 1] + : (!transform.any_op) -> (!transform.any_op, !transform.any_op, !transform.any_op) + + // Step 2: Vectorize + transform.structured.vectorize %tiled_linalg_op_r : !transform.any_op + + // Step 3: Simplify + // vector.multi_reduction --> vector.contract + // Generates a 6-dim vector.contract with the dim matching the original MMT4D Op + // and with the following split into parallel and reduction dims: + // * parallel, parallel, reduction, parallel, parallel, reduction + transform.apply_patterns to %func { + transform.apply_patterns.vector.reduction_to_contract + // Reduce the rank of xfer ops. This transforms vector.contract to be + // more matmul-like and to enable the lowering to outer product Ops. + transform.apply_patterns.vector.transfer_permutation_patterns + } : !transform.op<"func.func"> + + // Hoisting and LICM - not strictly required + %func_h = transform.structured.hoist_redundant_vector_transfers %func + : (!transform.op<"func.func">) -> !transform.op<"func.func"> + %all_loops = transform.structured.match interface{LoopLikeInterface} in %func_h + : (!transform.op<"func.func">) -> !transform.any_op + transform.apply_licm to %all_loops : !transform.any_op + transform.loop.hoist_loop_invariant_subsets %all_loops : !transform.any_op + + // Simplify the 6-dim vector.contract into a 3-dim matmul-like + // vector.contract with the following split into parallel and reduction + // dims: + // * parallel, parallel, reduction + transform.apply_patterns to %func_h { + transform.apply_patterns.vector.reduction_to_contract + transform.apply_patterns.vector.cast_away_vector_leading_one_dim + transform.apply_patterns.canonicalization + } : !transform.op<"func.func"> + + // Step 4. Lower tensor.pack + %pack = transform.structured.match ops{["tensor.pack"]} in %func_h + : (!transform.op<"func.func">) -> !transform.op<"tensor.pack"> + transform.structured.lower_pack %pack : (!transform.op<"tensor.pack">) + -> (!transform.op<"tensor.pad">, !transform.op<"tensor.expand_shape">, !transform.op<"linalg.transpose">) + + // Step 5. Lower tensor.unpack + %unpack = transform.structured.match ops{["tensor.unpack"]} in %func_h + : (!transform.op<"func.func">) -> !transform.op<"tensor.unpack"> + transform.structured.lower_unpack %unpack : (!transform.op<"tensor.unpack">) + -> (!transform.op<"tensor.empty">, + !transform.op<"linalg.transpose">, + !transform.op<"tensor.collapse_shape">, + !transform.op<"tensor.extract_slice">) + transform.yield + } + + transform.named_sequence @match_mmt4d( + %entry: !transform.any_op {transform.readonly}) -> !transform.any_op { + transform.match.operation_name %entry ["linalg.mmt4d"] : !transform.any_op + transform.yield %entry : !transform.any_op + } +} + +func.func private @printMemrefI32(%ptr : tensor<*xi32>) -- GitLab From ffed554f2d6590acd5cc8d66af916ec1938326b9 Mon Sep 17 00:00:00 2001 From: Ed Maste Date: Thu, 28 Mar 2024 10:52:50 -0400 Subject: [PATCH 063/788] [libc++] Switch FreeBSD to C++26 (#86658) --- libcxx/utils/ci/buildkite-pipeline.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/libcxx/utils/ci/buildkite-pipeline.yml b/libcxx/utils/ci/buildkite-pipeline.yml index 31e794e67d33..c43e41441872 100644 --- a/libcxx/utils/ci/buildkite-pipeline.yml +++ b/libcxx/utils/ci/buildkite-pipeline.yml @@ -207,7 +207,7 @@ steps: - group: ':freebsd: FreeBSD' steps: - label: FreeBSD 13 amd64 - command: libcxx/utils/ci/run-buildbot generic-cxx23 + command: libcxx/utils/ci/run-buildbot generic-cxx26 env: CC: clang17 CXX: clang++17 -- GitLab From d3aa92ed142409266ebcc9cbc20e5f2c2d0209c0 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Andrzej=20Warzy=C5=84ski?= Date: Thu, 28 Mar 2024 14:53:21 +0000 Subject: [PATCH 064/788] [mlir][vector] Add support for scalable vectors to VectorLinearize (#86786) Adds support for scalable vectors to patterns defined in VectorLineralize.cpp. Linearization is disable in 2 notable cases: * vectors with more than 1 scalable dimension (we cannot represent vscale^2), * vectors initialised with arith.constant that's not a vector splat (such arith.constant Ops cannot be flattened). --- .../mlir/Dialect/Vector/Utils/VectorUtils.h | 10 +++ .../Vector/Transforms/VectorLinearize.cpp | 12 +++- mlir/lib/Dialect/Vector/Utils/VectorUtils.cpp | 5 ++ mlir/test/Dialect/Vector/linearize.mlir | 61 ++++++++++++++++++- .../Dialect/Vector/TestVectorTransforms.cpp | 4 +- 5 files changed, 86 insertions(+), 6 deletions(-) diff --git a/mlir/include/mlir/Dialect/Vector/Utils/VectorUtils.h b/mlir/include/mlir/Dialect/Vector/Utils/VectorUtils.h index 2c548fb67402..f88fbdf9e627 100644 --- a/mlir/include/mlir/Dialect/Vector/Utils/VectorUtils.h +++ b/mlir/include/mlir/Dialect/Vector/Utils/VectorUtils.h @@ -170,6 +170,16 @@ public: PatternRewriter &rewriter) const = 0; }; +/// Returns true if the input Vector type can be linearized. +/// +/// Linearization is meant in the sense of flattening vectors, e.g.: +/// * vector -> vector +/// In this sense, Vectors that are either: +/// * already linearized, or +/// * contain more than 1 scalable dimensions, +/// are not linearizable. +bool isLinearizableVector(VectorType type); + } // namespace vector /// Constructs a permutation map of invariant memref indices to vector diff --git a/mlir/lib/Dialect/Vector/Transforms/VectorLinearize.cpp b/mlir/lib/Dialect/Vector/Transforms/VectorLinearize.cpp index 38536de43f13..4fa5b8a4865b 100644 --- a/mlir/lib/Dialect/Vector/Transforms/VectorLinearize.cpp +++ b/mlir/lib/Dialect/Vector/Transforms/VectorLinearize.cpp @@ -49,6 +49,12 @@ struct LinearizeConstant final : OpConversionPattern { Location loc = constOp.getLoc(); auto resType = getTypeConverter()->convertType(constOp.getType()); + + if (resType.isScalable() && !isa(constOp.getValue())) + return rewriter.notifyMatchFailure( + loc, + "Cannot linearize a constant scalable vector that's not a splat"); + if (!resType) return rewriter.notifyMatchFailure(loc, "can't convert return type"); if (!isLessThanTargetBitWidth(constOp, targetVectorBitWidth)) @@ -104,11 +110,11 @@ void mlir::vector::populateVectorLinearizeTypeConversionsAndLegality( ConversionTarget &target, unsigned targetBitWidth) { typeConverter.addConversion([](VectorType type) -> std::optional { - // Ignore scalable vectors for now. - if (type.getRank() <= 1 || type.isScalable()) + if (!isLinearizableVector(type)) return type; - return VectorType::get(type.getNumElements(), type.getElementType()); + return VectorType::get(type.getNumElements(), type.getElementType(), + type.isScalable()); }); auto materializeCast = [](OpBuilder &builder, Type type, ValueRange inputs, diff --git a/mlir/lib/Dialect/Vector/Utils/VectorUtils.cpp b/mlir/lib/Dialect/Vector/Utils/VectorUtils.cpp index 63ed0947cf6c..ebc6f5cbcaa9 100644 --- a/mlir/lib/Dialect/Vector/Utils/VectorUtils.cpp +++ b/mlir/lib/Dialect/Vector/Utils/VectorUtils.cpp @@ -317,3 +317,8 @@ SmallVector vector::getMixedSizesXfer(bool hasTensorSemantics, : memref::getMixedSizes(rewriter, loc, base); return mixedSourceDims; } + +bool vector::isLinearizableVector(VectorType type) { + auto numScalableDims = llvm::count(type.getScalableDims(), true); + return (type.getRank() > 1) && (numScalableDims <= 1); +} diff --git a/mlir/test/Dialect/Vector/linearize.mlir b/mlir/test/Dialect/Vector/linearize.mlir index 1b225c7a97d2..f0e9b3a05c06 100644 --- a/mlir/test/Dialect/Vector/linearize.mlir +++ b/mlir/test/Dialect/Vector/linearize.mlir @@ -1,5 +1,5 @@ -// RUN: mlir-opt %s -split-input-file -test-vector-linearize | FileCheck %s --check-prefixes=ALL,DEFAULT -// RUN: mlir-opt %s -split-input-file -test-vector-linearize=target-vector-bitwidth=128 | FileCheck %s --check-prefixes=ALL,BW-128 +// RUN: mlir-opt %s -split-input-file -test-vector-linearize -verify-diagnostics | FileCheck %s --check-prefixes=ALL,DEFAULT +// RUN: mlir-opt %s -split-input-file -test-vector-linearize=target-vector-bitwidth=128 -verify-diagnostics | FileCheck %s --check-prefixes=ALL,BW-128 // RUN: mlir-opt %s -split-input-file -test-vector-linearize=target-vector-bitwidth=0 | FileCheck %s --check-prefixes=ALL,BW-0 // ALL-LABEL: test_linearize @@ -97,3 +97,60 @@ func.func @test_tensor_no_linearize(%arg0: tensor<2x2xf32>, %arg1: tensor<2x2xf3 return %0, %arg0 : tensor<2x2xf32>, tensor<2x2xf32> } + +// ----- + +// ALL-LABEL: func.func @test_scalable_linearize( +// ALL-SAME: %[[ARG_0:.*]]: vector<2x[2]xf32>) -> vector<2x[2]xf32> { +func.func @test_scalable_linearize(%arg0: vector<2x[2]xf32>) -> vector<2x[2]xf32> { + // DEFAULT: %[[SC:.*]] = vector.shape_cast %[[ARG_0]] : vector<2x[2]xf32> to vector<[4]xf32> + // DEFAULT: %[[CST:.*]] = arith.constant dense<3.000000e+00> : vector<[4]xf32> + // BW-128: %[[SC:.*]] = vector.shape_cast %[[ARG_0]] : vector<2x[2]xf32> to vector<[4]xf32> + // BW-128: %[[CST:.*]] = arith.constant dense<3.000000e+00> : vector<[4]xf32> + // BW-0: %[[CST:.*]] = arith.constant dense<3.000000e+00> : vector<2x[2]xf32> + %0 = arith.constant dense<[[3., 3.], [3., 3.]]> : vector<2x[2]xf32> + + // DEFAULT: %[[SIN:.*]] = math.sin %[[SC]] : vector<[4]xf32> + // BW-128: %[[SIN:.*]] = math.sin %[[SC]] : vector<[4]xf32> + // BW-0: %[[SIN:.*]] = math.sin %[[ARG_0]] : vector<2x[2]xf32> + %1 = math.sin %arg0 : vector<2x[2]xf32> + + // DEFAULT: %[[ADDF:.*]] = arith.addf %[[SIN]], %[[CST]] : vector<[4]xf32> + // BW-128: %[[ADDF:.*]] = arith.addf %[[SIN]], %[[CST]] : vector<[4]xf32> + // BW-0: %[[RES:.*]] = arith.addf %[[CST]], %[[SIN]] : vector<2x[2]xf32> + %2 = arith.addf %0, %1 : vector<2x[2]xf32> + + // DEFAULT: %[[RES:.*]] = vector.shape_cast %[[ADDF]] : vector<[4]xf32> to vector<2x[2]xf32> + // BW-128: %[[RES:.*]] = vector.shape_cast %[[ADDF]] : vector<[4]xf32> to vector<2x[2]xf32> + // ALL: return %[[RES]] : vector<2x[2]xf32> + return %2 : vector<2x[2]xf32> +} + +// ----- + +// ALL-LABEL: func.func @test_scalable_no_linearize( +// ALL-SAME: %[[VAL_0:.*]]: vector<[2]x[2]xf32>) -> vector<[2]x[2]xf32> { +func.func @test_scalable_no_linearize(%arg0: vector<[2]x[2]xf32>) -> vector<[2]x[2]xf32> { + // ALL: %[[CST:.*]] = arith.constant dense<2.000000e+00> : vector<[2]x[2]xf32> + %0 = arith.constant dense<[[2., 2.], [2., 2.]]> : vector<[2]x[2]xf32> + + // ALL: %[[SIN:.*]] = math.sin %[[VAL_0]] : vector<[2]x[2]xf32> + %1 = math.sin %arg0 : vector<[2]x[2]xf32> + + // ALL: %[[RES:.*]] = arith.addf %[[CST]], %[[SIN]] : vector<[2]x[2]xf32> + %2 = arith.addf %0, %1 : vector<[2]x[2]xf32> + + // ALL: return %[[RES]] : vector<[2]x[2]xf32> + return %2 : vector<[2]x[2]xf32> +} + +// ----- + +func.func @test_scalable_no_linearize(%arg0: vector<2x[2]xf32>) -> vector<2x[2]xf32> { + // expected-error@+1 {{failed to legalize operation 'arith.constant' that was explicitly marked illegal}} + %0 = arith.constant dense<[[1., 1.], [3., 3.]]> : vector<2x[2]xf32> + %1 = math.sin %arg0 : vector<2x[2]xf32> + %2 = arith.addf %0, %1 : vector<2x[2]xf32> + + return %2 : vector<2x[2]xf32> +} diff --git a/mlir/test/lib/Dialect/Vector/TestVectorTransforms.cpp b/mlir/test/lib/Dialect/Vector/TestVectorTransforms.cpp index f14fb18706d1..006225999105 100644 --- a/mlir/test/lib/Dialect/Vector/TestVectorTransforms.cpp +++ b/mlir/test/lib/Dialect/Vector/TestVectorTransforms.cpp @@ -489,7 +489,9 @@ struct TestFlattenVectorTransferPatterns Option targetVectorBitwidth{ *this, "target-vector-bitwidth", llvm::cl::desc( - "Minimum vector bitwidth to enable the flattening transformation"), + "Minimum vector bitwidth to enable the flattening transformation. " + "For scalable vectors this is the base size, i.e. the size " + "corresponding to vscale=1."), llvm::cl::init(std::numeric_limits::max())}; void runOnOperation() override { -- GitLab From ae280281ce9f14f413ced0e44158a6fd41a98243 Mon Sep 17 00:00:00 2001 From: martinboehme Date: Thu, 28 Mar 2024 16:05:11 +0100 Subject: [PATCH 065/788] [clang][dataflow] Fix for value constructor in class derived from optional. (#86942) The constructor `Derived(int)` in the newly added test `ClassDerivedFromOptionalValueConstructor` is not a template, and this used to cause an assertion failure in `valueOrConversionHasValue()` because `F.getTemplateSpecializationArgs()` returns null. (This is modeled after the `MaybeAlign(Align Value)` constructor, which similarly causes an assertion failure in the analysis when assigning an `Align` to a `MaybeAlign`.) To fix this, we can simply look at the type of the destination type which we're constructing or assigning to (instead of the function template argument), and this not only fixes this specific case but actually simplifies the implementation. I've added some additional tests for the case of assigning to a nested optional because we didn't have coverage for these and I wanted to make sure I didn't break anything. --- .../Models/UncheckedOptionalAccessModel.cpp | 45 ++++++------ .../UncheckedOptionalAccessModelTest.cpp | 69 +++++++++++++++++++ 2 files changed, 92 insertions(+), 22 deletions(-) diff --git a/clang/lib/Analysis/FlowSensitive/Models/UncheckedOptionalAccessModel.cpp b/clang/lib/Analysis/FlowSensitive/Models/UncheckedOptionalAccessModel.cpp index dbf4878622eb..cadb1ceb2d85 100644 --- a/clang/lib/Analysis/FlowSensitive/Models/UncheckedOptionalAccessModel.cpp +++ b/clang/lib/Analysis/FlowSensitive/Models/UncheckedOptionalAccessModel.cpp @@ -512,27 +512,26 @@ void constructOptionalValue(const Expr &E, Environment &Env, /// Returns a symbolic value for the "has_value" property of an `optional` /// value that is constructed/assigned from a value of type `U` or `optional` /// where `T` is constructible from `U`. -BoolValue &valueOrConversionHasValue(const FunctionDecl &F, const Expr &E, +BoolValue &valueOrConversionHasValue(QualType DestType, const Expr &E, const MatchFinder::MatchResult &MatchRes, LatticeTransferState &State) { - assert(F.getTemplateSpecializationArgs() != nullptr); - assert(F.getTemplateSpecializationArgs()->size() > 0); - - const int TemplateParamOptionalWrappersCount = - countOptionalWrappers(*MatchRes.Context, F.getTemplateSpecializationArgs() - ->get(0) - .getAsType() - .getNonReferenceType()); + const int DestTypeOptionalWrappersCount = + countOptionalWrappers(*MatchRes.Context, DestType); const int ArgTypeOptionalWrappersCount = countOptionalWrappers( *MatchRes.Context, E.getType().getNonReferenceType()); - // Check if this is a constructor/assignment call for `optional` with - // argument of type `U` such that `T` is constructible from `U`. - if (TemplateParamOptionalWrappersCount == ArgTypeOptionalWrappersCount) + // Is this an constructor of the form `template optional(U &&)` / + // assignment of the form `template optional& operator=(U &&)` + // (where `T` is assignable / constructible from `U`)? + // We recognize this because the number of optionals in the optional being + // assigned to is different from the function argument type. + if (DestTypeOptionalWrappersCount != ArgTypeOptionalWrappersCount) return State.Env.getBoolLiteralValue(true); - // This is a constructor/assignment call for `optional` with argument of - // type `optional` such that `T` is constructible from `U`. + // Otherwise, this must be a constructor of the form + // `template optional &&)` / assignment of the form + // `template optional& operator=(optional &&) + // (where, again, `T` is assignable / constructible from `U`). auto *Loc = State.Env.get(E); if (auto *HasValueVal = getHasValue(State.Env, Loc)) return *HasValueVal; @@ -544,10 +543,11 @@ void transferValueOrConversionConstructor( LatticeTransferState &State) { assert(E->getNumArgs() > 0); - constructOptionalValue(*E, State.Env, - valueOrConversionHasValue(*E->getConstructor(), - *E->getArg(0), MatchRes, - State)); + constructOptionalValue( + *E, State.Env, + valueOrConversionHasValue( + E->getConstructor()->getThisType()->getPointeeType(), *E->getArg(0), + MatchRes, State)); } void transferAssignment(const CXXOperatorCallExpr *E, BoolValue &HasValueVal, @@ -566,10 +566,11 @@ void transferValueOrConversionAssignment( const CXXOperatorCallExpr *E, const MatchFinder::MatchResult &MatchRes, LatticeTransferState &State) { assert(E->getNumArgs() > 1); - transferAssignment(E, - valueOrConversionHasValue(*E->getDirectCallee(), - *E->getArg(1), MatchRes, State), - State); + transferAssignment( + E, + valueOrConversionHasValue(E->getArg(0)->getType().getNonReferenceType(), + *E->getArg(1), MatchRes, State), + State); } void transferNulloptAssignment(const CXXOperatorCallExpr *E, diff --git a/clang/unittests/Analysis/FlowSensitive/UncheckedOptionalAccessModelTest.cpp b/clang/unittests/Analysis/FlowSensitive/UncheckedOptionalAccessModelTest.cpp index 9430730004db..f16472ef1714 100644 --- a/clang/unittests/Analysis/FlowSensitive/UncheckedOptionalAccessModelTest.cpp +++ b/clang/unittests/Analysis/FlowSensitive/UncheckedOptionalAccessModelTest.cpp @@ -2798,6 +2798,59 @@ TEST_P(UncheckedOptionalAccessTest, OptionalValueOptional) { )"); } +TEST_P(UncheckedOptionalAccessTest, NestedOptionalAssignValue) { + ExpectDiagnosticsFor( + R"( + #include "unchecked_optional_access_test.h" + + using OptionalInt = $ns::$optional; + + void target($ns::$optional opt) { + if (!opt) return; + + // Accessing the outer optional is OK now. + *opt; + + // But accessing the nested optional is still unsafe because we haven't + // checked it. + **opt; // [[unsafe]] + + *opt = 1; + + // Accessing the nested optional is safe after assigning a value to it. + **opt; + } + )"); +} + +TEST_P(UncheckedOptionalAccessTest, NestedOptionalAssignOptional) { + ExpectDiagnosticsFor( + R"( + #include "unchecked_optional_access_test.h" + + using OptionalInt = $ns::$optional; + + void target($ns::$optional opt) { + if (!opt) return; + + // Accessing the outer optional is OK now. + *opt; + + // But accessing the nested optional is still unsafe because we haven't + // checked it. + **opt; // [[unsafe]] + + // Assign from `optional` so that we trigger conversion assignment + // instead of move assignment. + *opt = $ns::$optional(); + + // Accessing the nested optional is still unsafe after assigning an empty + // optional to it. + **opt; // [[unsafe]] + } + )"); +} + // Tests that structs can be nested. We use an optional field because its easy // to use in a test, but the type of the field shouldn't matter. TEST_P(UncheckedOptionalAccessTest, OptionalValueStruct) { @@ -3443,6 +3496,22 @@ TEST_P(UncheckedOptionalAccessTest, ClassDerivedPrivatelyFromOptional) { ast_matchers::hasName("Method")); } +TEST_P(UncheckedOptionalAccessTest, ClassDerivedFromOptionalValueConstructor) { + ExpectDiagnosticsFor(R"( + #include "unchecked_optional_access_test.h" + + struct Derived : public $ns::$optional { + Derived(int); + }; + + void target(Derived opt) { + *opt; // [[unsafe]] + opt = 1; + *opt; + } + )"); +} + // FIXME: Add support for: // - constructors (copy, move) // - assignment operators (default, copy, move) -- GitLab From e251f56a4d808340765112dd78edc6e6619dd05b Mon Sep 17 00:00:00 2001 From: Fraser Cormack Date: Thu, 28 Mar 2024 15:11:30 +0000 Subject: [PATCH 066/788] [libclc] Make CMake messages better fit into LLVM (#86945) The libclc project is currently only properly supported as an external project. However, when trying to get it to also build in-tree, the CMake configuration messages it outputs stand out amongst the rest of the LLVM projects and sub-projects. This commit makes all messages clear that they belong to the libclc project, as well as turning them into 'STATUS' messages where appropriate. --- libclc/CMakeLists.txt | 19 +++++++++---------- 1 file changed, 9 insertions(+), 10 deletions(-) diff --git a/libclc/CMakeLists.txt b/libclc/CMakeLists.txt index 745b848fba49..9236f09d3667 100644 --- a/libclc/CMakeLists.txt +++ b/libclc/CMakeLists.txt @@ -45,7 +45,7 @@ option( ENABLE_RUNTIME_SUBNORMAL "Enable runtime linking of subnormal support." find_package(LLVM REQUIRED HINTS "${LLVM_CMAKE_DIR}") include(AddLLVM) -message( "LLVM version: ${LLVM_PACKAGE_VERSION}" ) +message( STATUS "libclc LLVM version: ${LLVM_PACKAGE_VERSION}" ) if( ${LLVM_PACKAGE_VERSION} VERSION_LESS ${LIBCLC_MIN_LLVM} ) message( FATAL_ERROR "libclc needs at least LLVM ${LIBCLC_MIN_LLVM}" ) @@ -67,14 +67,13 @@ find_program( LLVM_OPT opt PATHS ${LLVM_TOOLS_BINARY_DIR} NO_DEFAULT_PATH ) find_program( LLVM_SPIRV llvm-spirv PATHS ${LLVM_TOOLS_BINARY_DIR} NO_DEFAULT_PATH ) # Print toolchain -message( "clang: ${LLVM_CLANG}" ) -message( "llvm-as: ${LLVM_AS}" ) -message( "llvm-link: ${LLVM_LINK}" ) -message( "opt: ${LLVM_OPT}" ) -message( "llvm-spirv: ${LLVM_SPIRV}" ) -message( "" ) +message( STATUS "libclc toolchain - clang: ${LLVM_CLANG}" ) +message( STATUS "libclc toolchain - llvm-as: ${LLVM_AS}" ) +message( STATUS "libclc toolchain - llvm-link: ${LLVM_LINK}" ) +message( STATUS "libclc toolchain - opt: ${LLVM_OPT}" ) +message( STATUS "libclc toolchain - llvm-spirv: ${LLVM_SPIRV}" ) if( NOT LLVM_CLANG OR NOT LLVM_OPT OR NOT LLVM_AS OR NOT LLVM_LINK ) - message( FATAL_ERROR "toolchain incomplete!" ) + message( FATAL_ERROR "libclc toolchain incomplete!" ) endif() list( SORT LIBCLC_TARGETS_TO_BUILD ) @@ -182,7 +181,7 @@ add_custom_target( "clspv-generate_convert.cl" DEPENDS clspv-convert.cl ) enable_testing() foreach( t ${LIBCLC_TARGETS_TO_BUILD} ) - message( "BUILDING ${t}" ) + message( STATUS "libclc target '${t}' is enabled" ) string( REPLACE "-" ";" TRIPLE ${t} ) list( GET TRIPLE 0 ARCH ) list( GET TRIPLE 1 VENDOR ) @@ -265,7 +264,7 @@ foreach( t ${LIBCLC_TARGETS_TO_BUILD} ) set( mcpu "-mcpu=${d}" ) set( arch_suffix "${d}-${t}" ) endif() - message( " DEVICE: ${d} ( ${${d}_aliases} )" ) + message( STATUS " device: ${d} ( ${${d}_aliases} )" ) if ( ${ARCH} STREQUAL "spirv" OR ${ARCH} STREQUAL "spirv64" ) if( ${ARCH} STREQUAL "spirv" ) -- GitLab From 94b5c118b3da99012e00d3e2d7c74784de9fc7ab Mon Sep 17 00:00:00 2001 From: Jonas Paulsson Date: Thu, 28 Mar 2024 16:14:35 +0100 Subject: [PATCH 067/788] [ISel] Move handling of atomic loads from SystemZ to DAGCombiner (NFC). (#86484) The folding of sign/zero extensions into an atomic load by specifying an extension type is not target specific, and therefore belongs in the DAGCombiner rather than in the SystemZ backend. - Handle atomic loads similarly to regular loads by adding AtomicLoadExtActions with set/get methods. - Move SystemZ extendAtomicLoad() to DagCombiner.cpp. --- llvm/include/llvm/CodeGen/TargetLowering.h | 50 +++++++++++++++++++ llvm/lib/CodeGen/SelectionDAG/DAGCombiner.cpp | 41 +++++++++++++++ llvm/lib/CodeGen/TargetLoweringBase.cpp | 6 +++ .../Target/SystemZ/SystemZISelLowering.cpp | 42 ++++------------ 4 files changed, 106 insertions(+), 33 deletions(-) diff --git a/llvm/include/llvm/CodeGen/TargetLowering.h b/llvm/include/llvm/CodeGen/TargetLowering.h index 59fad88f91b1..a4dc09744618 100644 --- a/llvm/include/llvm/CodeGen/TargetLowering.h +++ b/llvm/include/llvm/CodeGen/TargetLowering.h @@ -1454,6 +1454,28 @@ public: getLoadExtAction(ExtType, ValVT, MemVT) == Custom; } + /// Same as getLoadExtAction, but for atomic loads. + LegalizeAction getAtomicLoadExtAction(unsigned ExtType, EVT ValVT, + EVT MemVT) const { + if (ValVT.isExtended() || MemVT.isExtended()) return Expand; + unsigned ValI = (unsigned)ValVT.getSimpleVT().SimpleTy; + unsigned MemI = (unsigned)MemVT.getSimpleVT().SimpleTy; + assert(ExtType < ISD::LAST_LOADEXT_TYPE && ValI < MVT::VALUETYPE_SIZE && + MemI < MVT::VALUETYPE_SIZE && "Table isn't big enough!"); + unsigned Shift = 4 * ExtType; + LegalizeAction Action = + (LegalizeAction)((AtomicLoadExtActions[ValI][MemI] >> Shift) & 0xf); + assert((Action == Legal || Action == Expand) && + "Unsupported atomic load extension action."); + return Action; + } + + /// Return true if the specified atomic load with extension is legal on + /// this target. + bool isAtomicLoadExtLegal(unsigned ExtType, EVT ValVT, EVT MemVT) const { + return getAtomicLoadExtAction(ExtType, ValVT, MemVT) == Legal; + } + /// Return how this store with truncation should be treated: either it is /// legal, needs to be promoted to a larger size, needs to be expanded to some /// other code sequence, or the target has a custom expander for it. @@ -2536,6 +2558,30 @@ protected: setLoadExtAction(ExtTypes, ValVT, MemVT, Action); } + /// Let target indicate that an extending atomic load of the specified type + /// is legal. + void setAtomicLoadExtAction(unsigned ExtType, MVT ValVT, MVT MemVT, + LegalizeAction Action) { + assert(ExtType < ISD::LAST_LOADEXT_TYPE && ValVT.isValid() && + MemVT.isValid() && "Table isn't big enough!"); + assert((unsigned)Action < 0x10 && "too many bits for bitfield array"); + unsigned Shift = 4 * ExtType; + AtomicLoadExtActions[ValVT.SimpleTy][MemVT.SimpleTy] &= + ~((uint16_t)0xF << Shift); + AtomicLoadExtActions[ValVT.SimpleTy][MemVT.SimpleTy] |= + ((uint16_t)Action << Shift); + } + void setAtomicLoadExtAction(ArrayRef ExtTypes, MVT ValVT, MVT MemVT, + LegalizeAction Action) { + for (auto ExtType : ExtTypes) + setAtomicLoadExtAction(ExtType, ValVT, MemVT, Action); + } + void setAtomicLoadExtAction(ArrayRef ExtTypes, MVT ValVT, + ArrayRef MemVTs, LegalizeAction Action) { + for (auto MemVT : MemVTs) + setAtomicLoadExtAction(ExtTypes, ValVT, MemVT, Action); + } + /// Indicate that the specified truncating store does not work with the /// specified type and indicate what to do about it. void setTruncStoreAction(MVT ValVT, MVT MemVT, LegalizeAction Action) { @@ -3521,6 +3567,10 @@ private: /// for each of the 4 load ext types. uint16_t LoadExtActions[MVT::VALUETYPE_SIZE][MVT::VALUETYPE_SIZE]; + /// Similar to LoadExtActions, but for atomic loads. Only Legal or Expand + /// (default) values are supported. + uint16_t AtomicLoadExtActions[MVT::VALUETYPE_SIZE][MVT::VALUETYPE_SIZE]; + /// For each value type pair keep a LegalizeAction that indicates whether a /// truncating store of a specific value type and truncating type is legal. LegalizeAction TruncStoreActions[MVT::VALUETYPE_SIZE][MVT::VALUETYPE_SIZE]; diff --git a/llvm/lib/CodeGen/SelectionDAG/DAGCombiner.cpp b/llvm/lib/CodeGen/SelectionDAG/DAGCombiner.cpp index 6dd3fbb3c97e..2f46b23a97c6 100644 --- a/llvm/lib/CodeGen/SelectionDAG/DAGCombiner.cpp +++ b/llvm/lib/CodeGen/SelectionDAG/DAGCombiner.cpp @@ -13149,6 +13149,37 @@ tryToFoldExtOfMaskedLoad(SelectionDAG &DAG, const TargetLowering &TLI, EVT VT, return NewLoad; } +// fold ([s|z]ext (atomic_load)) -> ([s|z]ext (truncate ([s|z]ext atomic_load))) +static SDValue tryToFoldExtOfAtomicLoad(SelectionDAG &DAG, + const TargetLowering &TLI, EVT VT, + SDValue N0, + ISD::LoadExtType ExtLoadType) { + auto *ALoad = dyn_cast(N0); + if (!ALoad || ALoad->getOpcode() != ISD::ATOMIC_LOAD) + return {}; + EVT MemoryVT = ALoad->getMemoryVT(); + if (!TLI.isAtomicLoadExtLegal(ExtLoadType, VT, MemoryVT)) + return {}; + // Can't fold into ALoad if it is already extending differently. + ISD::LoadExtType ALoadExtTy = ALoad->getExtensionType(); + if ((ALoadExtTy == ISD::ZEXTLOAD && ExtLoadType == ISD::SEXTLOAD) || + (ALoadExtTy == ISD::SEXTLOAD && ExtLoadType == ISD::ZEXTLOAD)) + return {}; + + EVT OrigVT = ALoad->getValueType(0); + assert(OrigVT.getSizeInBits() < VT.getSizeInBits() && "VT should be wider."); + auto *NewALoad = cast(DAG.getAtomic( + ISD::ATOMIC_LOAD, SDLoc(ALoad), MemoryVT, VT, ALoad->getChain(), + ALoad->getBasePtr(), ALoad->getMemOperand())); + NewALoad->setExtensionType(ExtLoadType); + DAG.ReplaceAllUsesOfValueWith( + SDValue(ALoad, 0), + DAG.getNode(ISD::TRUNCATE, SDLoc(ALoad), OrigVT, SDValue(NewALoad, 0))); + // Update the chain uses. + DAG.ReplaceAllUsesOfValueWith(SDValue(ALoad, 1), SDValue(NewALoad, 1)); + return SDValue(NewALoad, 0); +} + static SDValue foldExtendedSignBitTest(SDNode *N, SelectionDAG &DAG, bool LegalOperations) { assert((N->getOpcode() == ISD::SIGN_EXTEND || @@ -13420,6 +13451,11 @@ SDValue DAGCombiner::visitSIGN_EXTEND(SDNode *N) { DAG, *this, TLI, VT, LegalOperations, N, N0, ISD::SEXTLOAD)) return foldedExt; + // Try to simplify (sext (atomic_load x)). + if (SDValue foldedExt = + tryToFoldExtOfAtomicLoad(DAG, TLI, VT, N0, ISD::SEXTLOAD)) + return foldedExt; + // fold (sext (and/or/xor (load x), cst)) -> // (and/or/xor (sextload x), (sext cst)) if (ISD::isBitwiseLogicOp(N0.getOpcode()) && @@ -13731,6 +13767,11 @@ SDValue DAGCombiner::visitZERO_EXTEND(SDNode *N) { if (SDValue ExtLoad = CombineExtLoad(N)) return ExtLoad; + // Try to simplify (zext (atomic_load x)). + if (SDValue foldedExt = + tryToFoldExtOfAtomicLoad(DAG, TLI, VT, N0, ISD::ZEXTLOAD)) + return foldedExt; + // fold (zext (and/or/xor (load x), cst)) -> // (and/or/xor (zextload x), (zext cst)) // Unless (and (load x) cst) will match as a zextload already and has diff --git a/llvm/lib/CodeGen/TargetLoweringBase.cpp b/llvm/lib/CodeGen/TargetLoweringBase.cpp index b16e78daf586..f64ded4f2cf9 100644 --- a/llvm/lib/CodeGen/TargetLoweringBase.cpp +++ b/llvm/lib/CodeGen/TargetLoweringBase.cpp @@ -823,6 +823,12 @@ void TargetLoweringBase::initActions() { std::fill(std::begin(TargetDAGCombineArray), std::end(TargetDAGCombineArray), 0); + // Let extending atomic loads be unsupported by default. + for (MVT ValVT : MVT::all_valuetypes()) + for (MVT MemVT : MVT::all_valuetypes()) + setAtomicLoadExtAction({ISD::SEXTLOAD, ISD::ZEXTLOAD}, ValVT, MemVT, + Expand); + // We're somewhat special casing MVT::i2 and MVT::i4. Ideally we want to // remove this and targets should individually set these types if not legal. for (ISD::NodeType NT : enum_seq(ISD::DELETED_NODE, ISD::BUILTIN_OP_END, diff --git a/llvm/lib/Target/SystemZ/SystemZISelLowering.cpp b/llvm/lib/Target/SystemZ/SystemZISelLowering.cpp index da4bcd7f0c66..6496fe766101 100644 --- a/llvm/lib/Target/SystemZ/SystemZISelLowering.cpp +++ b/llvm/lib/Target/SystemZ/SystemZISelLowering.cpp @@ -293,6 +293,15 @@ SystemZTargetLowering::SystemZTargetLowering(const TargetMachine &TM, setOperationAction(ISD::ATOMIC_LOAD, MVT::i128, Custom); setOperationAction(ISD::ATOMIC_STORE, MVT::i128, Custom); + // Mark sign/zero extending atomic loads as legal, which will make + // DAGCombiner fold extensions into atomic loads if possible. + setAtomicLoadExtAction({ISD::SEXTLOAD, ISD::ZEXTLOAD}, MVT::i64, + {MVT::i8, MVT::i16, MVT::i32}, Legal); + setAtomicLoadExtAction({ISD::SEXTLOAD, ISD::ZEXTLOAD}, MVT::i32, + {MVT::i8, MVT::i16}, Legal); + setAtomicLoadExtAction({ISD::SEXTLOAD, ISD::ZEXTLOAD}, MVT::i16, + MVT::i8, Legal); + // We can use the CC result of compare-and-swap to implement // the "success" result of ATOMIC_CMP_SWAP_WITH_SUCCESS. setOperationAction(ISD::ATOMIC_CMP_SWAP_WITH_SUCCESS, MVT::i32, Custom); @@ -6614,27 +6623,6 @@ SDValue SystemZTargetLowering::combineTruncateExtract( return SDValue(); } -// Replace ALoad with a new ATOMIC_LOAD with a result that is extended to VT -// per ETy. -static SDValue extendAtomicLoad(AtomicSDNode *ALoad, EVT VT, SelectionDAG &DAG, - ISD::LoadExtType ETy) { - if (VT.getSizeInBits() > 64) - return SDValue(); - EVT OrigVT = ALoad->getValueType(0); - assert(OrigVT.getSizeInBits() < VT.getSizeInBits() && "VT should be wider."); - EVT MemoryVT = ALoad->getMemoryVT(); - auto *NewALoad = dyn_cast(DAG.getAtomic( - ISD::ATOMIC_LOAD, SDLoc(ALoad), MemoryVT, VT, ALoad->getChain(), - ALoad->getBasePtr(), ALoad->getMemOperand())); - NewALoad->setExtensionType(ETy); - DAG.ReplaceAllUsesOfValueWith( - SDValue(ALoad, 0), - DAG.getNode(ISD::TRUNCATE, SDLoc(ALoad), OrigVT, SDValue(NewALoad, 0))); - // Update the chain uses. - DAG.ReplaceAllUsesOfValueWith(SDValue(ALoad, 1), SDValue(NewALoad, 1)); - return SDValue(NewALoad, 0); -} - SDValue SystemZTargetLowering::combineZERO_EXTEND( SDNode *N, DAGCombinerInfo &DCI) const { // Convert (zext (select_ccmask C1, C2)) into (select_ccmask C1', C2') @@ -6681,12 +6669,6 @@ SDValue SystemZTargetLowering::combineZERO_EXTEND( } } - // Fold into ATOMIC_LOAD unless it is already sign extending. - if (auto *ALoad = dyn_cast(N0)) - if (ALoad->getOpcode() == ISD::ATOMIC_LOAD && - ALoad->getExtensionType() != ISD::SEXTLOAD) - return extendAtomicLoad(ALoad, VT, DAG, ISD::ZEXTLOAD); - return SDValue(); } @@ -6739,12 +6721,6 @@ SDValue SystemZTargetLowering::combineSIGN_EXTEND( } } - // Fold into ATOMIC_LOAD unless it is already zero extending. - if (auto *ALoad = dyn_cast(N0)) - if (ALoad->getOpcode() == ISD::ATOMIC_LOAD && - ALoad->getExtensionType() != ISD::ZEXTLOAD) - return extendAtomicLoad(ALoad, VT, DAG, ISD::SEXTLOAD); - return SDValue(); } -- GitLab From f566b079f171f28366a66b8afa4a975bc4005529 Mon Sep 17 00:00:00 2001 From: Jerry Wu Date: Thu, 28 Mar 2024 15:18:47 +0000 Subject: [PATCH 068/788] [MLIR] Add pattern to fold insert_slice of extract_slice (#86328) Fold the `tensor.insert_slice` of `tensor.extract_slice` into `tensor_extract_slice` when the `insert_slice` simply expand some unit dims dropped by the `extract_slice`. --- ...eConsecutiveInsertExtractSlicePatterns.cpp | 101 +++++++++++++++++- mlir/lib/Dialect/Tensor/Utils/Utils.cpp | 8 +- ...redundant-insert-slice-rank-expansion.mlir | 65 +++++++++++ 3 files changed, 168 insertions(+), 6 deletions(-) diff --git a/mlir/lib/Dialect/Tensor/Transforms/MergeConsecutiveInsertExtractSlicePatterns.cpp b/mlir/lib/Dialect/Tensor/Transforms/MergeConsecutiveInsertExtractSlicePatterns.cpp index 5257310f5b00..59aa43222175 100644 --- a/mlir/lib/Dialect/Tensor/Transforms/MergeConsecutiveInsertExtractSlicePatterns.cpp +++ b/mlir/lib/Dialect/Tensor/Transforms/MergeConsecutiveInsertExtractSlicePatterns.cpp @@ -78,12 +78,12 @@ struct MergeConsecutiveInsertSlice : public OpRewritePattern { } }; -/// Drop redundant rank expansion. I.e., rank expansions that are directly -/// followed by rank reductions. E.g.: +/// Drop redundant rank expansion of insert_slice that are directly followed +/// by extract_slice. E.g.: /// %0 = tensor.insert_slice ... : tensor<5x10xf32> into tensor<1x1x5x10xf32> /// %1 = tensor.extract_slice %0[0, 0, 2, 3] [1, 1, 2, 2] [1, 1, 1, 1] /// : tensor<1x1x5x10xf32> to tensor<2x2xf32> -struct DropRedundantInsertSliceRankExpansion +struct DropRedundantRankExpansionOnExtractSliceOfInsertSlice : public OpRewritePattern { using OpRewritePattern::OpRewritePattern; @@ -134,6 +134,97 @@ struct DropRedundantInsertSliceRankExpansion return success(); } }; + +/// Drop redundant rank expansion of insert_slice that direclty follows +/// extract_slice. +/// +/// This can be done when the insert_slice op purely expands ranks (adds unit +/// dims) and the extrace_slice drops corresponding unit dims. For example: +/// +/// %extracted_slice = tensor.extract_slice %in[0, 0] [1, 8] [1, 1] +/// : tensor<2x8xf32> to tensor<8xf32> +/// %inserted_slice = tensor.insert_slice %extracted_slice +/// into %dest[0, 0] [1, 8] [1, 1] +/// : tensor<8xf32> into tensor<1x8xf32> +/// +/// can be folded into: +/// +/// %extracted_slice = tensor.extract_slice %in[0, 0] [1, 8] [1, 1] +/// : tensor<2x8xf32> to tensor<1x8xf32> +struct DropRedundantRankExpansionOnInsertSliceOfExtractSlice final + : public OpRewritePattern { + using OpRewritePattern::OpRewritePattern; + + LogicalResult matchAndRewrite(tensor::InsertSliceOp insertSliceOp, + PatternRewriter &rewriter) const { + auto extractSliceOp = + insertSliceOp.getSource().getDefiningOp(); + if (!extractSliceOp) { + return rewriter.notifyMatchFailure(insertSliceOp, + "source is not extract_slice"); + } + + // Can't fold if the extract_slice op has other users. + if (!extractSliceOp->hasOneUse()) { + return rewriter.notifyMatchFailure(insertSliceOp, + "source has multi-uses"); + } + + // Check if the insert_slice op purely expands ranks (add unit dims). + if (!isCastLikeInsertSliceOp(insertSliceOp)) { + return rewriter.notifyMatchFailure(insertSliceOp, + "insert_slice is not cast-like"); + } + + llvm::SmallBitVector extractDroppedDims = extractSliceOp.getDroppedDims(); + llvm::SmallBitVector insertDroppedDims = insertSliceOp.getDroppedDims(); + // Can't fold if the insert_slice op expands to more dims. + if (extractDroppedDims.size() < insertDroppedDims.size()) { + return rewriter.notifyMatchFailure(insertSliceOp, + "insert_slice expands more dims"); + } + + // Try to match the extract dropped dims to the insert dropped dims. This is + // done by scanning the dims of extract_slice and find the left-most one can + // match the dim of insert_slice. If a match is found, advance the dim of + // insert_slice to match the next one. + unsigned insertDimPos = 0; + for (unsigned extractDimPos = 0; extractDimPos < extractDroppedDims.size(); + ++extractDimPos) { + // Matched all dims. + if (insertDimPos == insertDroppedDims.size()) + break; + + bool isExtractDropped = extractDroppedDims[extractDimPos]; + bool isInsertDropped = insertDroppedDims[insertDimPos]; + // Match if both sides drop/keep the dim. Advance and match the next dim + // of insert_slice. + if (isExtractDropped == isInsertDropped) { + insertDimPos += 1; + } else if (!isExtractDropped && isInsertDropped) { + // Not enough extract dropped dims to match the insert dropped dims. + return rewriter.notifyMatchFailure(insertSliceOp, + "insert_slice drops more unit dims"); + } + // If the dim is dropped by extract_slice and not by insert_slice, look + // the next dim of extract_slice to see if it can match the current dim of + // insert_slice. + } + // Can't match some insert dims. + if (insertDimPos != insertDroppedDims.size()) { + return rewriter.notifyMatchFailure(insertSliceOp, + "insert_slice has unmatched dims"); + } + + rewriter.replaceOpWithNewOp( + insertSliceOp, insertSliceOp.getType(), extractSliceOp.getSource(), + extractSliceOp.getMixedOffsets(), extractSliceOp.getMixedSizes(), + extractSliceOp.getMixedStrides()); + rewriter.eraseOp(extractSliceOp); + + return success(); + } +}; } // namespace void mlir::tensor::populateMergeConsecutiveInsertExtractSlicePatterns( @@ -146,5 +237,7 @@ void mlir::tensor::populateMergeConsecutiveInsertExtractSlicePatterns( void mlir::tensor::populateDropRedundantInsertSliceRankExpansionPatterns( RewritePatternSet &patterns) { - patterns.add(patterns.getContext()); + patterns.add( + patterns.getContext()); } diff --git a/mlir/lib/Dialect/Tensor/Utils/Utils.cpp b/mlir/lib/Dialect/Tensor/Utils/Utils.cpp index 186f85d2ce20..2dd91e2f7a17 100644 --- a/mlir/lib/Dialect/Tensor/Utils/Utils.cpp +++ b/mlir/lib/Dialect/Tensor/Utils/Utils.cpp @@ -142,11 +142,15 @@ mlir::tensor::getUnPackInverseSrcPerm(UnPackOp unpackOp, bool mlir::tensor::isCastLikeInsertSliceOp(InsertSliceOp op) { llvm::SmallBitVector droppedDims = op.getDroppedDims(); int64_t srcDim = 0; + RankedTensorType resultType = op.getDestType(); // Source dims and destination dims (apart from dropped dims) must have the // same size. - for (int64_t resultDim = 0; resultDim < op.getDestType().getRank(); - ++resultDim) { + for (int64_t resultDim = 0; resultDim < resultType.getRank(); ++resultDim) { if (droppedDims.test(resultDim)) { + // InsertSlice may expand unit dimensions that result from inserting a + // size-1 slice into a non-size-1 result dimension. + if (resultType.getDimSize(resultDim) != 1) + return false; continue; } FailureOr equalDimSize = ValueBoundsConstraintSet::areEqual( diff --git a/mlir/test/Dialect/Tensor/drop-redundant-insert-slice-rank-expansion.mlir b/mlir/test/Dialect/Tensor/drop-redundant-insert-slice-rank-expansion.mlir index e337fdd93214..88e55062f477 100644 --- a/mlir/test/Dialect/Tensor/drop-redundant-insert-slice-rank-expansion.mlir +++ b/mlir/test/Dialect/Tensor/drop-redundant-insert-slice-rank-expansion.mlir @@ -9,3 +9,68 @@ func.func @test_drop_rank_expansion(%src: tensor<128x480xf32>, %dest: tensor<1x1 %extracted_slice = tensor.extract_slice %inserted_slice[0, 0, 0, 0] [1, 1, 123, 456] [1, 1, 1, 1] : tensor<1x1x128x480xf32> to tensor<123x456xf32> return %extracted_slice : tensor<123x456xf32> } + +// ----- + +func.func @fold_casting_insert_slice_of_extract_slice(%in : tensor, %dest : tensor<8x1x8xf32>) -> tensor<8x1x8xf32> { + %extracted_slice = tensor.extract_slice %in[0, 0, 0, 0] [1, 8, 1, 8] [1, 1, 1, 1] : tensor to tensor<8x8xf32> + %inserted_slice = tensor.insert_slice %extracted_slice into %dest[0, 0, 0] [8, 1, 8] [1, 1, 1] : tensor<8x8xf32> into tensor<8x1x8xf32> + return %inserted_slice : tensor<8x1x8xf32> +} +// CHECK-LABEL: func.func @fold_casting_insert_slice_of_extract_slice( +// CHECK-SAME: %[[ARG0:.*]]: tensor +// CHECK: %[[EXTRACTED_SLICE:.*]] = tensor.extract_slice %[[ARG0]][0, 0, 0, 0] [1, 8, 1, 8] [1, 1, 1, 1] +// CHECK-SAME: : tensor to tensor<8x1x8xf32> +// CHECK: return %[[EXTRACTED_SLICE]] : tensor<8x1x8xf32> + +// ----- + +func.func @fold_casting_insert_slice_of_strided_extract_slice(%in : tensor, %dest : tensor<1x4x8xf32>) -> tensor<1x4x8xf32> { + %extracted_slice = tensor.extract_slice %in[0, 0, 0, 0] [1, 4, 1, 8] [1, 2, 1, 1] : tensor to tensor<4x8xf32> + %inserted_slice = tensor.insert_slice %extracted_slice into %dest[0, 0, 0] [1, 4, 8] [1, 1, 1] : tensor<4x8xf32> into tensor<1x4x8xf32> + return %inserted_slice : tensor<1x4x8xf32> +} +// CHECK-LABEL: func.func @fold_casting_insert_slice_of_strided_extract_slice( +// CHECK-SAME: %[[ARG0:.*]]: tensor +// CHECK: %[[EXTRACTED_SLICE:.*]] = tensor.extract_slice %[[ARG0]][0, 0, 0, 0] [1, 4, 1, 8] [1, 2, 1, 1] +// CHECK-SAME: : tensor to tensor<1x4x8xf32> +// CHECK: return %[[EXTRACTED_SLICE]] : tensor<1x4x8xf32> + +// ----- + +func.func @no_fold_more_unit_dims_insert_slice_of_extract_slice(%in : tensor, %dest : tensor<1x1x8x8xf32>) -> tensor<1x1x8x8xf32> { + %extracted_slice = tensor.extract_slice %in[0, 0, 0] [1, 8, 8] [1, 1, 1] : tensor to tensor<8x8xf32> + %inserted_slice = tensor.insert_slice %extracted_slice into %dest[0, 0, 0, 0] [1, 1, 8, 8] [1, 1, 1, 1] : tensor<8x8xf32> into tensor<1x1x8x8xf32> + return %inserted_slice : tensor<1x1x8x8xf32> +} +// CHECK-LABEL: func.func @no_fold_more_unit_dims_insert_slice_of_extract_slice( +// CHECK-SAME: %[[ARG0:.*]]: tensor +// CHECK: %[[EXTRACTED_SLICE:.*]] = tensor.extract_slice %[[ARG0]] +// CHECK: %[[INSERTED_SLICE:.*]] = tensor.insert_slice %[[EXTRACTED_SLICE]] +// CHECK: return %[[INSERTED_SLICE]] : tensor<1x1x8x8xf32> + +// ----- + +func.func @no_fold_strided_insert_slice_of_extract_slice(%in : tensor, %dest : tensor<1x4x4xf32>) -> tensor<1x4x4xf32> { + %extracted_slice = tensor.extract_slice %in[0, 0, 0, 0] [1, 8, 1, 8] [1, 1, 1, 1] : tensor to tensor<8x8xf32> + %inserted_slice = tensor.insert_slice %extracted_slice into %dest[0, 0, 0] [1, 8, 8] [1, 2, 2] : tensor<8x8xf32> into tensor<1x4x4xf32> + return %inserted_slice : tensor<1x4x4xf32> +} +// CHECK-LABEL: func.func @no_fold_strided_insert_slice_of_extract_slice( +// CHECK-SAME: %[[ARG0:.*]]: tensor +// CHECK: %[[EXTRACTED_SLICE:.*]] = tensor.extract_slice %[[ARG0]] +// CHECK: %[[INSERTED_SLICE:.*]] = tensor.insert_slice %[[EXTRACTED_SLICE]] +// CHECK: return %[[INSERTED_SLICE]] : tensor<1x4x4xf32> + +// ----- + +func.func @no_fold_non_casting_insert_slice_of_extract_slice(%in : tensor<1x1x1x8x8xf32>, %dest : tensor<2x8x8xf32>) -> tensor<2x8x8xf32> { + %extracted_slice = tensor.extract_slice %in[0, 0, 0, 0, 0] [1, 1, 1, 8, 8] [1, 1, 1, 1, 1] : tensor<1x1x1x8x8xf32> to tensor<8x8xf32> + %inserted_slice = tensor.insert_slice %extracted_slice into %dest[0, 0, 0] [1, 8, 8] [1, 1, 1] : tensor<8x8xf32> into tensor<2x8x8xf32> + return %inserted_slice : tensor<2x8x8xf32> +} +// CHECK-LABEL: func.func @no_fold_non_casting_insert_slice_of_extract_slice( +// CHECK-SAME: %[[ARG0:.*]]: tensor<1x1x1x8x8xf32> +// CHECK: %[[EXTRACTED_SLICE:.*]] = tensor.extract_slice %[[ARG0]] +// CHECK: %[[INSERTED_SLICE:.*]] = tensor.insert_slice %[[EXTRACTED_SLICE]] +// CHECK: return %[[INSERTED_SLICE]] : tensor<2x8x8xf32> -- GitLab From f90813543b57a9753c549ac0aac083b879b94230 Mon Sep 17 00:00:00 2001 From: Craig Topper Date: Thu, 28 Mar 2024 08:37:19 -0700 Subject: [PATCH 069/788] [MCP] Use MachineInstr::all_defs instead of MachineInstr::defs in hasOverlappingMultipleDef. (#86889) defs does not return the defs for inline assembly. We need to use all_defs to find them. Fixes #86880. --- llvm/lib/CodeGen/MachineCopyPropagation.cpp | 2 +- llvm/test/CodeGen/X86/pr86880.mir | 21 +++++++++++++++++++++ 2 files changed, 22 insertions(+), 1 deletion(-) create mode 100644 llvm/test/CodeGen/X86/pr86880.mir diff --git a/llvm/lib/CodeGen/MachineCopyPropagation.cpp b/llvm/lib/CodeGen/MachineCopyPropagation.cpp index 9a0ab300b21b..65c067e4874b 100644 --- a/llvm/lib/CodeGen/MachineCopyPropagation.cpp +++ b/llvm/lib/CodeGen/MachineCopyPropagation.cpp @@ -640,7 +640,7 @@ bool MachineCopyPropagation::hasImplicitOverlap(const MachineInstr &MI, /// The umull instruction is unpredictable unless RdHi and RdLo are different. bool MachineCopyPropagation::hasOverlappingMultipleDef( const MachineInstr &MI, const MachineOperand &MODef, Register Def) { - for (const MachineOperand &MIDef : MI.defs()) { + for (const MachineOperand &MIDef : MI.all_defs()) { if ((&MIDef != &MODef) && MIDef.isReg() && TRI->regsOverlap(Def, MIDef.getReg())) return true; diff --git a/llvm/test/CodeGen/X86/pr86880.mir b/llvm/test/CodeGen/X86/pr86880.mir new file mode 100644 index 000000000000..92ebf9a265bb --- /dev/null +++ b/llvm/test/CodeGen/X86/pr86880.mir @@ -0,0 +1,21 @@ +# NOTE: Assertions have been autogenerated by utils/update_mir_test_checks.py UTC_ARGS: --version 4 +# RUN: llc -mtriple=x86_64-- -run-pass=machine-cp -o - %s | FileCheck %s + +--- +name: foo +tracksRegLiveness: true +body: | + bb.0: + liveins: $eax + + ; CHECK-LABEL: name: foo + ; CHECK: liveins: $eax + ; CHECK-NEXT: {{ $}} + ; CHECK-NEXT: INLINEASM &"", 0 /* attdialect */, 10 /* regdef */, implicit-def dead $eax, 2686986 /* regdef:GR32_NOREX2 */, def renamable $r15d, 10 /* regdef */, implicit-def dead $ecx, 10 /* regdef */, implicit-def dead $edx, 2147483657 /* reguse tiedto:$0 */, $eax(tied-def 3) + ; CHECK-NEXT: renamable $ecx = COPY killed renamable $r15d + ; CHECK-NEXT: NOOP implicit $ecx + INLINEASM &"", 0 /* attdialect */, 10 /* regdef */, implicit-def dead $eax, 2686986 /* regdef:GR32_NOREX2 */, def renamable $r15d, 10 /* regdef */, implicit-def dead $ecx, 10 /* regdef */, implicit-def dead $edx, 2147483657 /* reguse tiedto:$0 */, $eax(tied-def 3) + renamable $ecx = COPY killed renamable $r15d + NOOP implicit $ecx + +... -- GitLab From 152fcf6e77c9b83ac5cae1c0d7c0a9cf5680c7bd Mon Sep 17 00:00:00 2001 From: Craig Topper Date: Thu, 28 Mar 2024 08:38:18 -0700 Subject: [PATCH 070/788] [RISCV] Add validation of SPIMM for cm.push/pop. (#84989) This checks the immediate is a multiple of 16 bytes. --- llvm/lib/Target/RISCV/MCTargetDesc/RISCVBaseInfo.h | 3 ++- llvm/lib/Target/RISCV/RISCVInstrInfo.cpp | 3 +++ llvm/lib/Target/RISCV/RISCVInstrInfoZc.td | 6 ++++-- 3 files changed, 9 insertions(+), 3 deletions(-) diff --git a/llvm/lib/Target/RISCV/MCTargetDesc/RISCVBaseInfo.h b/llvm/lib/Target/RISCV/MCTargetDesc/RISCVBaseInfo.h index c65b51218772..92f405b5f6ac 100644 --- a/llvm/lib/Target/RISCV/MCTargetDesc/RISCVBaseInfo.h +++ b/llvm/lib/Target/RISCV/MCTargetDesc/RISCVBaseInfo.h @@ -297,7 +297,8 @@ enum OperandType : unsigned { OPERAND_RVKRNUM_0_7, OPERAND_RVKRNUM_1_10, OPERAND_RVKRNUM_2_14, - OPERAND_LAST_RISCV_IMM = OPERAND_RVKRNUM_2_14, + OPERAND_SPIMM, + OPERAND_LAST_RISCV_IMM = OPERAND_SPIMM, // Operand is either a register or uimm5, this is used by V extension pseudo // instructions to represent a value that be passed as AVL to either vsetvli // or vsetivli. diff --git a/llvm/lib/Target/RISCV/RISCVInstrInfo.cpp b/llvm/lib/Target/RISCV/RISCVInstrInfo.cpp index 14c2d41e80f1..5582de51b17d 100644 --- a/llvm/lib/Target/RISCV/RISCVInstrInfo.cpp +++ b/llvm/lib/Target/RISCV/RISCVInstrInfo.cpp @@ -2050,6 +2050,9 @@ bool RISCVInstrInfo::verifyInstruction(const MachineInstr &MI, case RISCVOp::OPERAND_RVKRNUM_2_14: Ok = Imm >= 2 && Imm <= 14; break; + case RISCVOp::OPERAND_SPIMM: + Ok = (Imm & 0xf) == 0; + break; } if (!Ok) { ErrInfo = "Invalid immediate"; diff --git a/llvm/lib/Target/RISCV/RISCVInstrInfoZc.td b/llvm/lib/Target/RISCV/RISCVInstrInfoZc.td index a327bd3d0c28..2a4448d7881f 100644 --- a/llvm/lib/Target/RISCV/RISCVInstrInfoZc.td +++ b/llvm/lib/Target/RISCV/RISCVInstrInfoZc.td @@ -71,10 +71,11 @@ def rlist : Operand { }]; } -def stackadj : Operand { +def stackadj : RISCVOp { let ParserMatchClass = StackAdjAsmOperand; let PrintMethod = "printStackAdj"; let DecoderMethod = "decodeZcmpSpimm"; + let OperandType = "OPERAND_SPIMM"; let MCOperandPredicate = [{ int64_t Imm; if (!MCOp.evaluateAsConstantImm(Imm)) @@ -83,10 +84,11 @@ def stackadj : Operand { }]; } -def negstackadj : Operand { +def negstackadj : RISCVOp { let ParserMatchClass = NegStackAdjAsmOperand; let PrintMethod = "printNegStackAdj"; let DecoderMethod = "decodeZcmpSpimm"; + let OperandType = "OPERAND_SPIMM"; let MCOperandPredicate = [{ int64_t Imm; if (!MCOp.evaluateAsConstantImm(Imm)) -- GitLab From 7789ec067dfcb07cc1f2222f48d9bb8e004c0d72 Mon Sep 17 00:00:00 2001 From: Nick Desaulniers Date: Thu, 28 Mar 2024 08:43:11 -0700 Subject: [PATCH 071/788] [libc] s/NULL/nullptr (#86867) Otherwise we need to pull in stddef.h for the declaration of NULL. --- libc/src/__support/char_vector.h | 8 ++++---- libc/src/stdlib/str_from_util.h | 2 +- libc/src/stdlib/strtod.cpp | 2 +- libc/src/stdlib/strtof.cpp | 2 +- libc/src/stdlib/strtold.cpp | 2 +- 5 files changed, 8 insertions(+), 8 deletions(-) diff --git a/libc/src/__support/char_vector.h b/libc/src/__support/char_vector.h index 955abdc1fa5a..d39310e09dd7 100644 --- a/libc/src/__support/char_vector.h +++ b/libc/src/__support/char_vector.h @@ -11,8 +11,8 @@ #include "src/__support/common.h" // LIBC_INLINE -#include -#include // For allocation. +#include // size_t +#include // malloc, realloc, free namespace LIBC_NAMESPACE { @@ -46,7 +46,7 @@ public: if (cur_str == local_buffer) { char *new_str; new_str = reinterpret_cast(malloc(cur_buff_size)); - if (new_str == NULL) { + if (new_str == nullptr) { return false; } // TODO: replace with inline memcpy @@ -55,7 +55,7 @@ public: cur_str = new_str; } else { cur_str = reinterpret_cast(realloc(cur_str, cur_buff_size)); - if (cur_str == NULL) { + if (cur_str == nullptr) { return false; } } diff --git a/libc/src/stdlib/str_from_util.h b/libc/src/stdlib/str_from_util.h index c4c1c0a0ba4e..58afa98afc08 100644 --- a/libc/src/stdlib/str_from_util.h +++ b/libc/src/stdlib/str_from_util.h @@ -11,7 +11,7 @@ // %{a,A,e,E,f,F,g,G}, are not allowed and any code that does otherwise results // in undefined behaviour(including use of a '%%' conversion specifier); which // in this case is that the buffer string is simply populated with the format -// string. The case of the input being NULL should be handled in the calling +// string. The case of the input being nullptr should be handled in the calling // function (strfromf, strfromd, strfroml) itself. #ifndef LLVM_LIBC_SRC_STDLIB_STRFROM_UTIL_H diff --git a/libc/src/stdlib/strtod.cpp b/libc/src/stdlib/strtod.cpp index db5e0edefb5b..461f7feb5bf6 100644 --- a/libc/src/stdlib/strtod.cpp +++ b/libc/src/stdlib/strtod.cpp @@ -19,7 +19,7 @@ LLVM_LIBC_FUNCTION(double, strtod, if (result.has_error()) libc_errno = result.error; - if (str_end != NULL) + if (str_end != nullptr) *str_end = const_cast(str + result.parsed_len); return result.value; diff --git a/libc/src/stdlib/strtof.cpp b/libc/src/stdlib/strtof.cpp index 2cc8829f63d3..554d096879c5 100644 --- a/libc/src/stdlib/strtof.cpp +++ b/libc/src/stdlib/strtof.cpp @@ -19,7 +19,7 @@ LLVM_LIBC_FUNCTION(float, strtof, if (result.has_error()) libc_errno = result.error; - if (str_end != NULL) + if (str_end != nullptr) *str_end = const_cast(str + result.parsed_len); return result.value; diff --git a/libc/src/stdlib/strtold.cpp b/libc/src/stdlib/strtold.cpp index 7378963f21b2..9c3e1db90067 100644 --- a/libc/src/stdlib/strtold.cpp +++ b/libc/src/stdlib/strtold.cpp @@ -19,7 +19,7 @@ LLVM_LIBC_FUNCTION(long double, strtold, if (result.has_error()) libc_errno = result.error; - if (str_end != NULL) + if (str_end != nullptr) *str_end = const_cast(str + result.parsed_len); return result.value; -- GitLab From 276335389133d6acf5f9d7d2f8ce09f9c610cb9c Mon Sep 17 00:00:00 2001 From: Fangrui Song Date: Thu, 28 Mar 2024 09:10:34 -0700 Subject: [PATCH 072/788] [Object,ELFType] Rename TargetEndianness to Endianness (#86604) `TargetEndianness` is long and unwieldy. "Target" in the name is confusing. Rename it to "Endianness". I cannot find noticeable out-of-tree users of `TargetEndianness`, but keep `TargetEndianness` to make this patch safer. `TargetEndianness` will be removed by a subsequent change. --- lld/ELF/Arch/Mips.cpp | 6 +- lld/ELF/DWARF.h | 2 +- lld/ELF/InputFiles.cpp | 6 +- lld/ELF/InputSection.cpp | 4 +- lld/ELF/SyntheticSections.cpp | 4 +- .../llvm/ExecutionEngine/Orc/ExecutionUtils.h | 2 +- llvm/include/llvm/Object/ELFObjectFile.h | 16 ++- llvm/include/llvm/Object/ELFTypes.h | 101 +++++++++--------- .../JITLink/ELFLinkGraphBuilder.h | 2 +- .../ExecutionEngine/Orc/ExecutionUtils.cpp | 4 +- llvm/lib/InterfaceStub/ELFObjHandler.cpp | 2 +- llvm/lib/ObjCopy/ELF/ELFObject.cpp | 15 ++- llvm/lib/ObjectYAML/ELFEmitter.cpp | 58 +++++----- llvm/tools/llvm-readobj/DwarfCFIEHPrinter.h | 9 +- llvm/tools/llvm-readobj/ELFDumper.cpp | 37 +++---- 15 files changed, 130 insertions(+), 138 deletions(-) diff --git a/lld/ELF/Arch/Mips.cpp b/lld/ELF/Arch/Mips.cpp index b02ad10649d9..e36e9d59a740 100644 --- a/lld/ELF/Arch/Mips.cpp +++ b/lld/ELF/Arch/Mips.cpp @@ -380,7 +380,7 @@ bool MIPS::needsThunk(RelExpr expr, RelType type, const InputFile *file, template int64_t MIPS::getImplicitAddend(const uint8_t *buf, RelType type) const { - const endianness e = ELFT::TargetEndianness; + const endianness e = ELFT::Endianness; switch (type) { case R_MIPS_32: case R_MIPS_REL32: @@ -521,7 +521,7 @@ static uint64_t fixupCrossModeJump(uint8_t *loc, RelType type, uint64_t val) { // to a microMIPS target and vice versa. In that cases jump // instructions need to be replaced by their "cross-mode" // equivalents. - const endianness e = ELFT::TargetEndianness; + const endianness e = ELFT::Endianness; bool isMicroTgt = val & 0x1; bool isCrossJump = (isMicroTgt && isBranchReloc(type)) || (!isMicroTgt && isMicroBranchReloc(type)); @@ -567,7 +567,7 @@ static uint64_t fixupCrossModeJump(uint8_t *loc, RelType type, uint64_t val) { template void MIPS::relocate(uint8_t *loc, const Relocation &rel, uint64_t val) const { - const endianness e = ELFT::TargetEndianness; + const endianness e = ELFT::Endianness; RelType type = rel.type; if (ELFT::Is64Bits || config->mipsN32Abi) diff --git a/lld/ELF/DWARF.h b/lld/ELF/DWARF.h index 1b9a3e3f7794..d56895277bcc 100644 --- a/lld/ELF/DWARF.h +++ b/lld/ELF/DWARF.h @@ -74,7 +74,7 @@ public: StringRef getLineStrSection() const override { return lineStrSection; } bool isLittleEndian() const override { - return ELFT::TargetEndianness == llvm::endianness::little; + return ELFT::Endianness == llvm::endianness::little; } std::optional find(const llvm::DWARFSection &sec, diff --git a/lld/ELF/InputFiles.cpp b/lld/ELF/InputFiles.cpp index 42761b6e1209..725c6f166fff 100644 --- a/lld/ELF/InputFiles.cpp +++ b/lld/ELF/InputFiles.cpp @@ -971,8 +971,8 @@ template static uint32_t readAndFeatures(const InputSection &sec) { const uint8_t *place = desc.data(); if (desc.size() < 8) reportFatal(place, "program property is too short"); - uint32_t type = read32(desc.data()); - uint32_t size = read32(desc.data() + 4); + uint32_t type = read32(desc.data()); + uint32_t size = read32(desc.data() + 4); desc = desc.slice(8); if (desc.size() < size) reportFatal(place, "program property is too short"); @@ -983,7 +983,7 @@ template static uint32_t readAndFeatures(const InputSection &sec) { // accumulate the bits set. if (size < 4) reportFatal(place, "FEATURE_1_AND entry is too short"); - featuresSet |= read32(desc.data()); + featuresSet |= read32(desc.data()); } // Padding is present in the note descriptor, if necessary. diff --git a/lld/ELF/InputSection.cpp b/lld/ELF/InputSection.cpp index c34bf08757b1..4f88313b868b 100644 --- a/lld/ELF/InputSection.cpp +++ b/lld/ELF/InputSection.cpp @@ -1258,10 +1258,10 @@ void EhInputSection::split(ArrayRef rels) { msg = "CIE/FDE too small"; break; } - uint64_t size = endian::read32(d.data()); + uint64_t size = endian::read32(d.data()); if (size == 0) // ZERO terminator break; - uint32_t id = endian::read32(d.data() + 4); + uint32_t id = endian::read32(d.data() + 4); size += 4; if (LLVM_UNLIKELY(size > d.size())) { // If it is 0xFFFFFFFF, the next 8 bytes contain the size instead, diff --git a/lld/ELF/SyntheticSections.cpp b/lld/ELF/SyntheticSections.cpp index 650bd6cd3900..8708bfeef8fa 100644 --- a/lld/ELF/SyntheticSections.cpp +++ b/lld/ELF/SyntheticSections.cpp @@ -415,7 +415,7 @@ void EhFrameSection::addRecords(EhInputSection *sec, ArrayRef rels) { for (EhSectionPiece &cie : sec->cies) offsetToCie[cie.inputOff] = addCie(cie, rels); for (EhSectionPiece &fde : sec->fdes) { - uint32_t id = endian::read32(fde.data().data() + 4); + uint32_t id = endian::read32(fde.data().data() + 4); CieRecord *rec = offsetToCie[fde.inputOff + 4 - id]; if (!rec) fatal(toString(sec) + ": invalid CIE reference"); @@ -448,7 +448,7 @@ void EhFrameSection::iterateFDEWithLSDAAux( if (hasLSDA(cie)) ciesWithLSDA.insert(cie.inputOff); for (EhSectionPiece &fde : sec.fdes) { - uint32_t id = endian::read32(fde.data().data() + 4); + uint32_t id = endian::read32(fde.data().data() + 4); if (!ciesWithLSDA.contains(fde.inputOff + 4 - id)) continue; diff --git a/llvm/include/llvm/ExecutionEngine/Orc/ExecutionUtils.h b/llvm/include/llvm/ExecutionEngine/Orc/ExecutionUtils.h index f7c286bec778..ed30a792e9e9 100644 --- a/llvm/include/llvm/ExecutionEngine/Orc/ExecutionUtils.h +++ b/llvm/include/llvm/ExecutionEngine/Orc/ExecutionUtils.h @@ -352,7 +352,7 @@ private: : ES(ES), L(L) {} static Expected getTargetPointerSize(const Triple &TT); - static Expected getTargetEndianness(const Triple &TT); + static Expected getEndianness(const Triple &TT); Expected> createStubsGraph(const SymbolMap &Resolved); diff --git a/llvm/include/llvm/Object/ELFObjectFile.h b/llvm/include/llvm/Object/ELFObjectFile.h index f57a7ab8882a..1d457be93741 100644 --- a/llvm/include/llvm/Object/ELFObjectFile.h +++ b/llvm/include/llvm/Object/ELFObjectFile.h @@ -419,7 +419,7 @@ protected: if (Contents[0] != ELFAttrs::Format_Version || Contents.size() == 1) return Error::success(); - if (Error E = Attributes.parse(Contents, ELFT::TargetEndianness)) + if (Error E = Attributes.parse(Contents, ELFT::Endianness)) return E; break; } @@ -482,7 +482,7 @@ public: bool isDyldType() const { return isDyldELFObject; } static bool classof(const Binary *v) { return v->getType() == - getELFType(ELFT::TargetEndianness == llvm::endianness::little, + getELFType(ELFT::Endianness == llvm::endianness::little, ELFT::Is64Bits); } @@ -1155,10 +1155,9 @@ ELFObjectFile::ELFObjectFile(MemoryBufferRef Object, ELFFile EF, const Elf_Shdr *DotDynSymSec, const Elf_Shdr *DotSymtabSec, const Elf_Shdr *DotSymtabShndx) - : ELFObjectFileBase( - getELFType(ELFT::TargetEndianness == llvm::endianness::little, - ELFT::Is64Bits), - Object), + : ELFObjectFileBase(getELFType(ELFT::Endianness == llvm::endianness::little, + ELFT::Is64Bits), + Object), EF(EF), DotDynSymSec(DotDynSymSec), DotSymtabSec(DotSymtabSec), DotSymtabShndxSec(DotSymtabShndx) {} @@ -1226,8 +1225,7 @@ uint8_t ELFObjectFile::getBytesInAddress() const { template StringRef ELFObjectFile::getFileFormatName() const { - constexpr bool IsLittleEndian = - ELFT::TargetEndianness == llvm::endianness::little; + constexpr bool IsLittleEndian = ELFT::Endianness == llvm::endianness::little; switch (EF.getHeader().e_ident[ELF::EI_CLASS]) { case ELF::ELFCLASS32: switch (EF.getHeader().e_machine) { @@ -1305,7 +1303,7 @@ StringRef ELFObjectFile::getFileFormatName() const { } template Triple::ArchType ELFObjectFile::getArch() const { - bool IsLittleEndian = ELFT::TargetEndianness == llvm::endianness::little; + bool IsLittleEndian = ELFT::Endianness == llvm::endianness::little; switch (EF.getHeader().e_machine) { case ELF::EM_68K: return Triple::m68k; diff --git a/llvm/include/llvm/Object/ELFTypes.h b/llvm/include/llvm/Object/ELFTypes.h index 4986ecf8323d..4617b70a2f12 100644 --- a/llvm/include/llvm/Object/ELFTypes.h +++ b/llvm/include/llvm/Object/ELFTypes.h @@ -52,6 +52,7 @@ private: public: static const endianness TargetEndianness = E; + static const endianness Endianness = E; static const bool Is64Bits = Is64; using uint = std::conditional_t; @@ -145,9 +146,9 @@ using ELF64BE = ELFType; // Section header. template struct Elf_Shdr_Base; -template -struct Elf_Shdr_Base> { - LLVM_ELF_IMPORT_TYPES(TargetEndianness, false) +template +struct Elf_Shdr_Base> { + LLVM_ELF_IMPORT_TYPES(Endianness, false) Elf_Word sh_name; // Section name (index into string table) Elf_Word sh_type; // Section type (SHT_*) Elf_Word sh_flags; // Section flags (SHF_*) @@ -160,9 +161,9 @@ struct Elf_Shdr_Base> { Elf_Word sh_entsize; // Size of records contained within the section }; -template -struct Elf_Shdr_Base> { - LLVM_ELF_IMPORT_TYPES(TargetEndianness, true) +template +struct Elf_Shdr_Base> { + LLVM_ELF_IMPORT_TYPES(Endianness, true) Elf_Word sh_name; // Section name (index into string table) Elf_Word sh_type; // Section type (SHT_*) Elf_Xword sh_flags; // Section flags (SHF_*) @@ -190,9 +191,9 @@ struct Elf_Shdr_Impl : Elf_Shdr_Base { template struct Elf_Sym_Base; -template -struct Elf_Sym_Base> { - LLVM_ELF_IMPORT_TYPES(TargetEndianness, false) +template +struct Elf_Sym_Base> { + LLVM_ELF_IMPORT_TYPES(Endianness, false) Elf_Word st_name; // Symbol name (index into string table) Elf_Addr st_value; // Value or address associated with the symbol Elf_Word st_size; // Size of the symbol @@ -201,9 +202,9 @@ struct Elf_Sym_Base> { Elf_Half st_shndx; // Which section (header table index) it's defined in }; -template -struct Elf_Sym_Base> { - LLVM_ELF_IMPORT_TYPES(TargetEndianness, true) +template +struct Elf_Sym_Base> { + LLVM_ELF_IMPORT_TYPES(Endianness, true) Elf_Word st_name; // Symbol name (index into string table) unsigned char st_info; // Symbol's type and binding attributes unsigned char st_other; // Must be zero; reserved @@ -349,9 +350,9 @@ struct Elf_Vernaux_Impl { /// table section (.dynamic) look like. template struct Elf_Dyn_Base; -template -struct Elf_Dyn_Base> { - LLVM_ELF_IMPORT_TYPES(TargetEndianness, false) +template +struct Elf_Dyn_Base> { + LLVM_ELF_IMPORT_TYPES(Endianness, false) Elf_Sword d_tag; union { Elf_Word d_val; @@ -359,9 +360,9 @@ struct Elf_Dyn_Base> { } d_un; }; -template -struct Elf_Dyn_Base> { - LLVM_ELF_IMPORT_TYPES(TargetEndianness, true) +template +struct Elf_Dyn_Base> { + LLVM_ELF_IMPORT_TYPES(Endianness, true) Elf_Sxword d_tag; union { Elf_Xword d_val; @@ -381,9 +382,9 @@ struct Elf_Dyn_Impl : Elf_Dyn_Base { uintX_t getPtr() const { return d_un.d_ptr; } }; -template -struct Elf_Rel_Impl, false> { - LLVM_ELF_IMPORT_TYPES(TargetEndianness, false) +template +struct Elf_Rel_Impl, false> { + LLVM_ELF_IMPORT_TYPES(Endianness, false) static const bool IsRela = false; Elf_Addr r_offset; // Location (file byte offset, or program virtual addr) Elf_Word r_info; // Symbol table index and type of relocation to apply @@ -416,17 +417,17 @@ struct Elf_Rel_Impl, false> { } }; -template -struct Elf_Rel_Impl, true> - : public Elf_Rel_Impl, false> { - LLVM_ELF_IMPORT_TYPES(TargetEndianness, false) +template +struct Elf_Rel_Impl, true> + : public Elf_Rel_Impl, false> { + LLVM_ELF_IMPORT_TYPES(Endianness, false) static const bool IsRela = true; Elf_Sword r_addend; // Compute value for relocatable field by adding this }; -template -struct Elf_Rel_Impl, false> { - LLVM_ELF_IMPORT_TYPES(TargetEndianness, true) +template +struct Elf_Rel_Impl, false> { + LLVM_ELF_IMPORT_TYPES(Endianness, true) static const bool IsRela = false; Elf_Addr r_offset; // Location (file byte offset, or program virtual addr) Elf_Xword r_info; // Symbol table index and type of relocation to apply @@ -469,10 +470,10 @@ struct Elf_Rel_Impl, false> { } }; -template -struct Elf_Rel_Impl, true> - : public Elf_Rel_Impl, false> { - LLVM_ELF_IMPORT_TYPES(TargetEndianness, true) +template +struct Elf_Rel_Impl, true> + : public Elf_Rel_Impl, false> { + LLVM_ELF_IMPORT_TYPES(Endianness, true) static const bool IsRela = true; Elf_Sxword r_addend; // Compute value for relocatable field by adding this. }; @@ -504,9 +505,9 @@ struct Elf_Ehdr_Impl { unsigned char getDataEncoding() const { return e_ident[ELF::EI_DATA]; } }; -template -struct Elf_Phdr_Impl> { - LLVM_ELF_IMPORT_TYPES(TargetEndianness, false) +template +struct Elf_Phdr_Impl> { + LLVM_ELF_IMPORT_TYPES(Endianness, false) Elf_Word p_type; // Type of segment Elf_Off p_offset; // FileOffset where segment is located, in bytes Elf_Addr p_vaddr; // Virtual Address of beginning of segment @@ -517,9 +518,9 @@ struct Elf_Phdr_Impl> { Elf_Word p_align; // Segment alignment constraint }; -template -struct Elf_Phdr_Impl> { - LLVM_ELF_IMPORT_TYPES(TargetEndianness, true) +template +struct Elf_Phdr_Impl> { + LLVM_ELF_IMPORT_TYPES(Endianness, true) Elf_Word p_type; // Type of segment Elf_Word p_flags; // Segment flags Elf_Off p_offset; // FileOffset where segment is located, in bytes @@ -574,17 +575,17 @@ struct Elf_GnuHash_Impl { // Compressed section headers. // http://www.sco.com/developers/gabi/latest/ch4.sheader.html#compression_header -template -struct Elf_Chdr_Impl> { - LLVM_ELF_IMPORT_TYPES(TargetEndianness, false) +template +struct Elf_Chdr_Impl> { + LLVM_ELF_IMPORT_TYPES(Endianness, false) Elf_Word ch_type; Elf_Word ch_size; Elf_Word ch_addralign; }; -template -struct Elf_Chdr_Impl> { - LLVM_ELF_IMPORT_TYPES(TargetEndianness, true) +template +struct Elf_Chdr_Impl> { + LLVM_ELF_IMPORT_TYPES(Endianness, true) Elf_Word ch_type; Elf_Word ch_reserved; Elf_Xword ch_size; @@ -742,17 +743,17 @@ template struct Elf_CGProfile_Impl { template struct Elf_Mips_RegInfo; -template -struct Elf_Mips_RegInfo> { - LLVM_ELF_IMPORT_TYPES(TargetEndianness, false) +template +struct Elf_Mips_RegInfo> { + LLVM_ELF_IMPORT_TYPES(Endianness, false) Elf_Word ri_gprmask; // bit-mask of used general registers Elf_Word ri_cprmask[4]; // bit-mask of used co-processor registers Elf_Addr ri_gp_value; // gp register value }; -template -struct Elf_Mips_RegInfo> { - LLVM_ELF_IMPORT_TYPES(TargetEndianness, true) +template +struct Elf_Mips_RegInfo> { + LLVM_ELF_IMPORT_TYPES(Endianness, true) Elf_Word ri_gprmask; // bit-mask of used general registers Elf_Word ri_pad; // unused padding field Elf_Word ri_cprmask[4]; // bit-mask of used co-processor registers diff --git a/llvm/lib/ExecutionEngine/JITLink/ELFLinkGraphBuilder.h b/llvm/lib/ExecutionEngine/JITLink/ELFLinkGraphBuilder.h index e1b11dfcfc21..5dae60062939 100644 --- a/llvm/lib/ExecutionEngine/JITLink/ELFLinkGraphBuilder.h +++ b/llvm/lib/ExecutionEngine/JITLink/ELFLinkGraphBuilder.h @@ -193,7 +193,7 @@ ELFLinkGraphBuilder::ELFLinkGraphBuilder( StringRef FileName, LinkGraph::GetEdgeKindNameFunction GetEdgeKindName) : ELFLinkGraphBuilderBase(std::make_unique( FileName.str(), Triple(std::move(TT)), std::move(Features), - ELFT::Is64Bits ? 8 : 4, llvm::endianness(ELFT::TargetEndianness), + ELFT::Is64Bits ? 8 : 4, llvm::endianness(ELFT::Endianness), std::move(GetEdgeKindName))), Obj(Obj) { LLVM_DEBUG( diff --git a/llvm/lib/ExecutionEngine/Orc/ExecutionUtils.cpp b/llvm/lib/ExecutionEngine/Orc/ExecutionUtils.cpp index 3952445bb1aa..670c8cf996fd 100644 --- a/llvm/lib/ExecutionEngine/Orc/ExecutionUtils.cpp +++ b/llvm/lib/ExecutionEngine/Orc/ExecutionUtils.cpp @@ -545,7 +545,7 @@ DLLImportDefinitionGenerator::getTargetPointerSize(const Triple &TT) { } Expected -DLLImportDefinitionGenerator::getTargetEndianness(const Triple &TT) { +DLLImportDefinitionGenerator::getEndianness(const Triple &TT) { switch (TT.getArch()) { case Triple::x86_64: return llvm::endianness::little; @@ -562,7 +562,7 @@ DLLImportDefinitionGenerator::createStubsGraph(const SymbolMap &Resolved) { auto PointerSize = getTargetPointerSize(TT); if (!PointerSize) return PointerSize.takeError(); - auto Endianness = getTargetEndianness(TT); + auto Endianness = getEndianness(TT); if (!Endianness) return Endianness.takeError(); diff --git a/llvm/lib/InterfaceStub/ELFObjHandler.cpp b/llvm/lib/InterfaceStub/ELFObjHandler.cpp index c1256563d0d6..9c81a8832c0f 100644 --- a/llvm/lib/InterfaceStub/ELFObjHandler.cpp +++ b/llvm/lib/InterfaceStub/ELFObjHandler.cpp @@ -57,7 +57,7 @@ static void initELFHeader(typename ELFT::Ehdr &ElfHeader, uint16_t Machine) { ElfHeader.e_ident[EI_MAG2] = ElfMagic[EI_MAG2]; ElfHeader.e_ident[EI_MAG3] = ElfMagic[EI_MAG3]; ElfHeader.e_ident[EI_CLASS] = ELFT::Is64Bits ? ELFCLASS64 : ELFCLASS32; - bool IsLittleEndian = ELFT::TargetEndianness == llvm::endianness::little; + bool IsLittleEndian = ELFT::Endianness == llvm::endianness::little; ElfHeader.e_ident[EI_DATA] = IsLittleEndian ? ELFDATA2LSB : ELFDATA2MSB; ElfHeader.e_ident[EI_VERSION] = EV_CURRENT; ElfHeader.e_ident[EI_OSABI] = ELFOSABI_NONE; diff --git a/llvm/lib/ObjCopy/ELF/ELFObject.cpp b/llvm/lib/ObjCopy/ELF/ELFObject.cpp index 9547cc10d2a0..8b6a0035dae3 100644 --- a/llvm/lib/ObjCopy/ELF/ELFObject.cpp +++ b/llvm/lib/ObjCopy/ELF/ELFObject.cpp @@ -33,6 +33,7 @@ using namespace llvm; using namespace llvm::ELF; using namespace llvm::objcopy::elf; using namespace llvm::object; +using namespace llvm::support; template void ELFWriter::writePhdr(const Segment &Seg) { uint8_t *B = reinterpret_cast(Buf->getBufferStart()) + @@ -1175,9 +1176,9 @@ template Error ELFSectionWriter::visit(const GroupSection &Sec) { ELF::Elf32_Word *Buf = reinterpret_cast(Out.getBufferStart() + Sec.Offset); - support::endian::write32(Buf++, Sec.FlagWord); + endian::write32(Buf++, Sec.FlagWord); for (SectionBase *S : Sec.GroupMembers) - support::endian::write32(Buf++, S->Index); + endian::write32(Buf++, S->Index); return Error::success(); } @@ -1522,10 +1523,9 @@ Error ELFBuilder::initGroupSection(GroupSection *GroupSec) { reinterpret_cast(GroupSec->Contents.data()); const ELF::Elf32_Word *End = Word + GroupSec->Contents.size() / sizeof(ELF::Elf32_Word); - GroupSec->setFlagWord( - support::endian::read32(Word++)); + GroupSec->setFlagWord(endian::read32(Word++)); for (; Word != End; ++Word) { - uint32_t Index = support::endian::read32(Word); + uint32_t Index = support::endian::read32(Word); Expected Sec = SecTable.getSection( Index, "group member index " + Twine(Index) + " in section '" + GroupSec->Name + "' is invalid"); @@ -1993,9 +1993,8 @@ template void ELFWriter::writeEhdr() { Ehdr.e_ident[EI_MAG2] = 'L'; Ehdr.e_ident[EI_MAG3] = 'F'; Ehdr.e_ident[EI_CLASS] = ELFT::Is64Bits ? ELFCLASS64 : ELFCLASS32; - Ehdr.e_ident[EI_DATA] = ELFT::TargetEndianness == llvm::endianness::big - ? ELFDATA2MSB - : ELFDATA2LSB; + Ehdr.e_ident[EI_DATA] = + ELFT::Endianness == llvm::endianness::big ? ELFDATA2MSB : ELFDATA2LSB; Ehdr.e_ident[EI_VERSION] = EV_CURRENT; Ehdr.e_ident[EI_OSABI] = Obj.OSABI; Ehdr.e_ident[EI_ABIVERSION] = Obj.ABIVersion; diff --git a/llvm/lib/ObjectYAML/ELFEmitter.cpp b/llvm/lib/ObjectYAML/ELFEmitter.cpp index 58a725f8d877..b7118a543fae 100644 --- a/llvm/lib/ObjectYAML/ELFEmitter.cpp +++ b/llvm/lib/ObjectYAML/ELFEmitter.cpp @@ -1314,7 +1314,7 @@ void ELFState::writeSectionContent(Elf_Shdr &SHeader, if (!ELFT::Is64Bits && E > UINT32_MAX) reportError(Section.Name + ": the value is too large for 32-bits: 0x" + Twine::utohexstr(E)); - CBA.write(E, ELFT::TargetEndianness); + CBA.write(E, ELFT::Endianness); } SHeader.sh_size = sizeof(uintX_t) * Section.Entries->size(); @@ -1333,7 +1333,7 @@ void ELFState::writeSectionContent( return; for (uint32_t E : *Shndx.Entries) - CBA.write(E, ELFT::TargetEndianness); + CBA.write(E, ELFT::Endianness); SHeader.sh_size = Shndx.Entries->size() * SHeader.sh_entsize; } @@ -1357,7 +1357,7 @@ void ELFState::writeSectionContent(Elf_Shdr &SHeader, SectionIndex = llvm::ELF::GRP_COMDAT; else SectionIndex = toSectionIndex(Member.sectionNameOrType, Section.Name); - CBA.write(SectionIndex, ELFT::TargetEndianness); + CBA.write(SectionIndex, ELFT::Endianness); } SHeader.sh_size = SHeader.sh_entsize * Section.Members->size(); } @@ -1370,7 +1370,7 @@ void ELFState::writeSectionContent(Elf_Shdr &SHeader, return; for (uint16_t Version : *Section.Entries) - CBA.write(Version, ELFT::TargetEndianness); + CBA.write(Version, ELFT::Endianness); SHeader.sh_size = Section.Entries->size() * SHeader.sh_entsize; } @@ -1382,7 +1382,7 @@ void ELFState::writeSectionContent( return; for (const ELFYAML::StackSizeEntry &E : *Section.Entries) { - CBA.write(E.Address, ELFT::TargetEndianness); + CBA.write(E.Address, ELFT::Endianness); SHeader.sh_size += sizeof(uintX_t) + CBA.writeULEB128(E.Size); } } @@ -1444,7 +1444,7 @@ void ELFState::writeSectionContent( uint64_t TotalNumBlocks = 0; for (const ELFYAML::BBAddrMapEntry::BBRangeEntry &BBR : *E.BBRanges) { // Write the base address of the range. - CBA.write(BBR.BaseAddress, ELFT::TargetEndianness); + CBA.write(BBR.BaseAddress, ELFT::Endianness); // Write number of BBEntries (number of basic blocks in this basic block // range). This is overridden by the 'NumBlocks' YAML field when // specified. @@ -1558,7 +1558,7 @@ void ELFState::writeSectionContent( return; for (const ELFYAML::CallGraphEntryWeight &E : *Section.Entries) { - CBA.write(E.Weight, ELFT::TargetEndianness); + CBA.write(E.Weight, ELFT::Endianness); SHeader.sh_size += sizeof(object::Elf_CGProfile_Impl); } } @@ -1572,15 +1572,15 @@ void ELFState::writeSectionContent(Elf_Shdr &SHeader, CBA.write( Section.NBucket.value_or(llvm::yaml::Hex64(Section.Bucket->size())), - ELFT::TargetEndianness); + ELFT::Endianness); CBA.write( Section.NChain.value_or(llvm::yaml::Hex64(Section.Chain->size())), - ELFT::TargetEndianness); + ELFT::Endianness); for (uint32_t Val : *Section.Bucket) - CBA.write(Val, ELFT::TargetEndianness); + CBA.write(Val, ELFT::Endianness); for (uint32_t Val : *Section.Chain) - CBA.write(Val, ELFT::TargetEndianness); + CBA.write(Val, ELFT::Endianness); SHeader.sh_size = (2 + Section.Bucket->size() + Section.Chain->size()) * 4; } @@ -1687,8 +1687,8 @@ void ELFState::writeSectionContent( return; for (const ELFYAML::ARMIndexTableEntry &E : *Section.Entries) { - CBA.write(E.Offset, ELFT::TargetEndianness); - CBA.write(E.Value, ELFT::TargetEndianness); + CBA.write(E.Offset, ELFT::Endianness); + CBA.write(E.Value, ELFT::Endianness); } SHeader.sh_size = Section.Entries->size() * 8; } @@ -1729,8 +1729,8 @@ void ELFState::writeSectionContent(Elf_Shdr &SHeader, return; for (const ELFYAML::DynamicEntry &DE : *Section.Entries) { - CBA.write(DE.Tag, ELFT::TargetEndianness); - CBA.write(DE.Val, ELFT::TargetEndianness); + CBA.write(DE.Tag, ELFT::Endianness); + CBA.write(DE.Val, ELFT::Endianness); } SHeader.sh_size = 2 * sizeof(uintX_t) * Section.Entries->size(); } @@ -1758,18 +1758,18 @@ void ELFState::writeSectionContent(Elf_Shdr &SHeader, for (const ELFYAML::NoteEntry &NE : *Section.Notes) { // Write name size. if (NE.Name.empty()) - CBA.write(0, ELFT::TargetEndianness); + CBA.write(0, ELFT::Endianness); else - CBA.write(NE.Name.size() + 1, ELFT::TargetEndianness); + CBA.write(NE.Name.size() + 1, ELFT::Endianness); // Write description size. if (NE.Desc.binary_size() == 0) - CBA.write(0, ELFT::TargetEndianness); + CBA.write(0, ELFT::Endianness); else - CBA.write(NE.Desc.binary_size(), ELFT::TargetEndianness); + CBA.write(NE.Desc.binary_size(), ELFT::Endianness); // Write type. - CBA.write(NE.Type, ELFT::TargetEndianness); + CBA.write(NE.Type, ELFT::Endianness); // Write name, null terminator and padding. if (!NE.Name.empty()) { @@ -1803,35 +1803,35 @@ void ELFState::writeSectionContent(Elf_Shdr &SHeader, // be used to override this field, which is useful for producing broken // objects. if (Section.Header->NBuckets) - CBA.write(*Section.Header->NBuckets, ELFT::TargetEndianness); + CBA.write(*Section.Header->NBuckets, ELFT::Endianness); else - CBA.write(Section.HashBuckets->size(), ELFT::TargetEndianness); + CBA.write(Section.HashBuckets->size(), ELFT::Endianness); // Write the index of the first symbol in the dynamic symbol table accessible // via the hash table. - CBA.write(Section.Header->SymNdx, ELFT::TargetEndianness); + CBA.write(Section.Header->SymNdx, ELFT::Endianness); // Write the number of words in the Bloom filter. As above, the "MaskWords" // property can be used to set this field to any value. if (Section.Header->MaskWords) - CBA.write(*Section.Header->MaskWords, ELFT::TargetEndianness); + CBA.write(*Section.Header->MaskWords, ELFT::Endianness); else - CBA.write(Section.BloomFilter->size(), ELFT::TargetEndianness); + CBA.write(Section.BloomFilter->size(), ELFT::Endianness); // Write the shift constant used by the Bloom filter. - CBA.write(Section.Header->Shift2, ELFT::TargetEndianness); + CBA.write(Section.Header->Shift2, ELFT::Endianness); // We've finished writing the header. Now write the Bloom filter. for (llvm::yaml::Hex64 Val : *Section.BloomFilter) - CBA.write(Val, ELFT::TargetEndianness); + CBA.write(Val, ELFT::Endianness); // Write an array of hash buckets. for (llvm::yaml::Hex32 Val : *Section.HashBuckets) - CBA.write(Val, ELFT::TargetEndianness); + CBA.write(Val, ELFT::Endianness); // Write an array of hash values. for (llvm::yaml::Hex32 Val : *Section.HashValues) - CBA.write(Val, ELFT::TargetEndianness); + CBA.write(Val, ELFT::Endianness); SHeader.sh_size = 16 /*Header size*/ + Section.BloomFilter->size() * sizeof(typename ELFT::uint) + diff --git a/llvm/tools/llvm-readobj/DwarfCFIEHPrinter.h b/llvm/tools/llvm-readobj/DwarfCFIEHPrinter.h index 2e89463e68d5..94a44e3afccb 100644 --- a/llvm/tools/llvm-readobj/DwarfCFIEHPrinter.h +++ b/llvm/tools/llvm-readobj/DwarfCFIEHPrinter.h @@ -113,7 +113,7 @@ void PrinterContext::printEHFrameHdr(const Elf_Phdr *EHFramePHdr) const { if (!Content) reportError(Content.takeError(), ObjF.getFileName()); - DataExtractor DE(*Content, ELFT::TargetEndianness == llvm::endianness::little, + DataExtractor DE(*Content, ELFT::Endianness == llvm::endianness::little, ELFT::Is64Bits ? 8 : 4); DictScope D(W, "Header"); @@ -186,10 +186,9 @@ void PrinterContext::printEHFrame(const Elf_Shdr *EHFrameShdr) const { // Construct DWARFDataExtractor to handle relocations ("PC Begin" fields). std::unique_ptr DICtx = DWARFContext::create( ObjF, DWARFContext::ProcessDebugRelocations::Process, nullptr); - DWARFDataExtractor DE(DICtx->getDWARFObj(), - DICtx->getDWARFObj().getEHFrameSection(), - ELFT::TargetEndianness == llvm::endianness::little, - ELFT::Is64Bits ? 8 : 4); + DWARFDataExtractor DE( + DICtx->getDWARFObj(), DICtx->getDWARFObj().getEHFrameSection(), + ELFT::Endianness == llvm::endianness::little, ELFT::Is64Bits ? 8 : 4); DWARFDebugFrame EHFrame(Triple::ArchType(ObjF.getArch()), /*IsEH=*/true, /*EHFrameAddress=*/Address); if (Error E = EHFrame.parse(DE)) diff --git a/llvm/tools/llvm-readobj/ELFDumper.cpp b/llvm/tools/llvm-readobj/ELFDumper.cpp index d1c05f437042..4b406ef12aec 100644 --- a/llvm/tools/llvm-readobj/ELFDumper.cpp +++ b/llvm/tools/llvm-readobj/ELFDumper.cpp @@ -74,6 +74,7 @@ using namespace llvm; using namespace llvm::object; +using namespace llvm::support; using namespace ELF; #define LLVM_READOBJ_ENUM_CASE(ns, enum) \ @@ -3419,13 +3420,13 @@ template void ELFDumper::printStackMap() const { return; } - if (Error E = StackMapParser::validateHeader( - *ContentOrErr)) { + if (Error E = + StackMapParser::validateHeader(*ContentOrErr)) { Warn(std::move(E)); return; } - prettyPrintStackMap(W, StackMapParser(*ContentOrErr)); + prettyPrintStackMap(W, StackMapParser(*ContentOrErr)); } template @@ -5145,7 +5146,7 @@ static std::string getGNUProperty(uint32_t Type, uint32_t DataSize, OS << format("", DataSize); return OS.str(); } - PrData = support::endian::read32(Data.data()); + PrData = endian::read32(Data.data()); if (PrData == 0) { OS << ""; return OS.str(); @@ -5169,7 +5170,7 @@ static std::string getGNUProperty(uint32_t Type, uint32_t DataSize, OS << format("", DataSize); return OS.str(); } - PrData = support::endian::read32(Data.data()); + PrData = endian::read32(Data.data()); if (PrData == 0) { OS << ""; return OS.str(); @@ -5195,7 +5196,7 @@ static std::string getGNUProperty(uint32_t Type, uint32_t DataSize, OS << format("", DataSize); return OS.str(); } - PrData = support::endian::read32(Data.data()); + PrData = endian::read32(Data.data()); if (PrData == 0) { OS << ""; return OS.str(); @@ -5374,10 +5375,8 @@ static bool printAArch64Note(raw_ostream &OS, uint32_t NoteType, return false; } - uint64_t Platform = - support::endian::read64(Desc.data() + 0); - uint64_t Version = - support::endian::read64(Desc.data() + 8); + uint64_t Platform = endian::read64(Desc.data() + 0); + uint64_t Version = endian::read64(Desc.data() + 8); OS << format("platform 0x%" PRIx64 ", version 0x%" PRIx64, Platform, Version); if (Desc.size() > 16) @@ -5457,16 +5456,14 @@ getFreeBSDNote(uint32_t NoteType, ArrayRef Desc, bool IsCore) { case ELF::NT_FREEBSD_ABI_TAG: if (Desc.size() != 4) return std::nullopt; - return FreeBSDNote{ - "ABI tag", - utostr(support::endian::read32(Desc.data()))}; + return FreeBSDNote{"ABI tag", + utostr(endian::read32(Desc.data()))}; case ELF::NT_FREEBSD_ARCH_TAG: return FreeBSDNote{"Arch tag", toStringRef(Desc).str()}; case ELF::NT_FREEBSD_FEATURE_CTL: { if (Desc.size() != 4) return std::nullopt; - unsigned Value = - support::endian::read32(Desc.data()); + unsigned Value = endian::read32(Desc.data()); std::string FlagsStr; raw_string_ostream OS(FlagsStr); printFlags(Value, ArrayRef(FreeBSDFeatureCtlFlags), OS); @@ -6053,7 +6050,7 @@ template void GNUELFDumper::printNotes() { } else if (Name == "CORE") { if (Type == ELF::NT_FILE) { DataExtractor DescExtractor( - Descriptor, ELFT::TargetEndianness == llvm::endianness::little, + Descriptor, ELFT::Endianness == llvm::endianness::little, sizeof(Elf_Addr)); if (Expected NoteOrErr = readCoreNote(DescExtractor)) { printCoreNote(OS, *NoteOrErr); @@ -7714,10 +7711,8 @@ static bool printAarch64NoteLLVMStyle(uint32_t NoteType, ArrayRef Desc, if (Desc.size() < 16) return false; - uint64_t platform = - support::endian::read64(Desc.data() + 0); - uint64_t version = - support::endian::read64(Desc.data() + 8); + uint64_t platform = endian::read64(Desc.data() + 0); + uint64_t version = endian::read64(Desc.data() + 8); W.printNumber("Platform", platform); W.printNumber("Version", version); @@ -7852,7 +7847,7 @@ template void LLVMELFDumper::printNotes() { } else if (Name == "CORE") { if (Type == ELF::NT_FILE) { DataExtractor DescExtractor( - Descriptor, ELFT::TargetEndianness == llvm::endianness::little, + Descriptor, ELFT::Endianness == llvm::endianness::little, sizeof(Elf_Addr)); if (Expected N = readCoreNote(DescExtractor)) { printCoreNoteLLVMStyle(*N, W); -- GitLab From 0f61051f541a5b8cfce25c84262dfdbadb9ca688 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Nathan=20Gau=C3=ABr?= Date: Thu, 28 Mar 2024 17:18:05 +0100 Subject: [PATCH 073/788] [clang][HLSL][SPRI-V] Add convergence intrinsics (#80680) MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit HLSL has wave operations and other kind of function which required the control flow to either be converged, or respect certain constraints as where and how to re-converge. At the HLSL level, the convergence are mostly obvious: the control flow is expected to re-converge at the end of a scope. Once translated to IR, HLSL scopes disapear. This means we need a way to communicate convergence restrictions down to the backend. For this, the SPIR-V backend uses convergence intrinsics. So this commit adds some code to generate convergence intrinsics when required. --------- Signed-off-by: Nathan Gauër --- clang/include/clang/Basic/Builtins.td | 6 ++ clang/lib/CodeGen/CGBuiltin.cpp | 93 +++++++++++++++++++ clang/lib/CodeGen/CGCall.cpp | 3 + clang/lib/CodeGen/CGLoopInfo.h | 7 +- clang/lib/CodeGen/CodeGenFunction.h | 19 ++++ clang/lib/Headers/hlsl/hlsl_intrinsics.h | 7 +- .../wave_get_lane_index_do_while.hlsl | 40 ++++++++ .../builtins/wave_get_lane_index_simple.hlsl | 14 +++ .../builtins/wave_get_lane_index_subcall.hlsl | 21 +++++ llvm/include/llvm/IR/IntrinsicInst.h | 13 +++ 10 files changed, 221 insertions(+), 2 deletions(-) create mode 100644 clang/test/CodeGenHLSL/builtins/wave_get_lane_index_do_while.hlsl create mode 100644 clang/test/CodeGenHLSL/builtins/wave_get_lane_index_simple.hlsl create mode 100644 clang/test/CodeGenHLSL/builtins/wave_get_lane_index_subcall.hlsl diff --git a/clang/include/clang/Basic/Builtins.td b/clang/include/clang/Basic/Builtins.td index 52c0dd52c28b..f421223ff087 100644 --- a/clang/include/clang/Basic/Builtins.td +++ b/clang/include/clang/Basic/Builtins.td @@ -4599,6 +4599,12 @@ def HLSLWaveActiveCountBits : LangBuiltin<"HLSL_LANG"> { let Prototype = "unsigned int(bool)"; } +def HLSLWaveGetLaneIndex : LangBuiltin<"HLSL_LANG"> { + let Spellings = ["__builtin_hlsl_wave_get_lane_index"]; + let Attributes = [NoThrow, Const]; + let Prototype = "unsigned int()"; +} + def HLSLClamp : LangBuiltin<"HLSL_LANG"> { let Spellings = ["__builtin_hlsl_elementwise_clamp"]; let Attributes = [NoThrow, Const]; diff --git a/clang/lib/CodeGen/CGBuiltin.cpp b/clang/lib/CodeGen/CGBuiltin.cpp index 5ab5917c0c8d..287e763bad82 100644 --- a/clang/lib/CodeGen/CGBuiltin.cpp +++ b/clang/lib/CodeGen/CGBuiltin.cpp @@ -1131,8 +1131,92 @@ struct BitTest { static BitTest decodeBitTestBuiltin(unsigned BuiltinID); }; + +// Returns the first convergence entry/loop/anchor instruction found in |BB|. +// std::nullptr otherwise. +llvm::IntrinsicInst *getConvergenceToken(llvm::BasicBlock *BB) { + for (auto &I : *BB) { + auto *II = dyn_cast(&I); + if (II && isConvergenceControlIntrinsic(II->getIntrinsicID())) + return II; + } + return nullptr; +} + } // namespace +llvm::CallBase * +CodeGenFunction::addConvergenceControlToken(llvm::CallBase *Input, + llvm::Value *ParentToken) { + llvm::Value *bundleArgs[] = {ParentToken}; + llvm::OperandBundleDef OB("convergencectrl", bundleArgs); + auto Output = llvm::CallBase::addOperandBundle( + Input, llvm::LLVMContext::OB_convergencectrl, OB, Input); + Input->replaceAllUsesWith(Output); + Input->eraseFromParent(); + return Output; +} + +llvm::IntrinsicInst * +CodeGenFunction::emitConvergenceLoopToken(llvm::BasicBlock *BB, + llvm::Value *ParentToken) { + CGBuilderTy::InsertPoint IP = Builder.saveIP(); + Builder.SetInsertPoint(&BB->front()); + auto CB = Builder.CreateIntrinsic( + llvm::Intrinsic::experimental_convergence_loop, {}, {}); + Builder.restoreIP(IP); + + auto I = addConvergenceControlToken(CB, ParentToken); + return cast(I); +} + +llvm::IntrinsicInst * +CodeGenFunction::getOrEmitConvergenceEntryToken(llvm::Function *F) { + auto *BB = &F->getEntryBlock(); + auto *token = getConvergenceToken(BB); + if (token) + return token; + + // Adding a convergence token requires the function to be marked as + // convergent. + F->setConvergent(); + + CGBuilderTy::InsertPoint IP = Builder.saveIP(); + Builder.SetInsertPoint(&BB->front()); + auto I = Builder.CreateIntrinsic( + llvm::Intrinsic::experimental_convergence_entry, {}, {}); + assert(isa(I)); + Builder.restoreIP(IP); + + return cast(I); +} + +llvm::IntrinsicInst * +CodeGenFunction::getOrEmitConvergenceLoopToken(const LoopInfo *LI) { + assert(LI != nullptr); + + auto *token = getConvergenceToken(LI->getHeader()); + if (token) + return token; + + llvm::IntrinsicInst *PII = + LI->getParent() + ? emitConvergenceLoopToken( + LI->getHeader(), getOrEmitConvergenceLoopToken(LI->getParent())) + : getOrEmitConvergenceEntryToken(LI->getHeader()->getParent()); + + return emitConvergenceLoopToken(LI->getHeader(), PII); +} + +llvm::CallBase * +CodeGenFunction::addControlledConvergenceToken(llvm::CallBase *Input) { + llvm::Value *ParentToken = + LoopStack.hasInfo() + ? getOrEmitConvergenceLoopToken(&LoopStack.getInfo()) + : getOrEmitConvergenceEntryToken(Input->getFunction()); + return addConvergenceControlToken(Input, ParentToken); +} + BitTest BitTest::decodeBitTestBuiltin(unsigned BuiltinID) { switch (BuiltinID) { // Main portable variants. @@ -5809,6 +5893,15 @@ RValue CodeGenFunction::EmitBuiltinExpr(const GlobalDecl GD, unsigned BuiltinID, {NDRange, Kernel, Block})); } + case Builtin::BI__builtin_hlsl_wave_get_lane_index: { + auto *CI = EmitRuntimeCall(CGM.CreateRuntimeFunction( + llvm::FunctionType::get(IntTy, {}, false), "__hlsl_wave_get_lane_index", + {}, false, true)); + if (getTarget().getTriple().isSPIRVLogical()) + CI = dyn_cast(addControlledConvergenceToken(CI)); + return RValue::get(CI); + } + case Builtin::BI__builtin_store_half: case Builtin::BI__builtin_store_halff: { Value *Val = EmitScalarExpr(E->getArg(0)); diff --git a/clang/lib/CodeGen/CGCall.cpp b/clang/lib/CodeGen/CGCall.cpp index fb0078214b07..a5fe39633679 100644 --- a/clang/lib/CodeGen/CGCall.cpp +++ b/clang/lib/CodeGen/CGCall.cpp @@ -5715,6 +5715,9 @@ RValue CodeGenFunction::EmitCall(const CGFunctionInfo &CallInfo, if (!CI->getType()->isVoidTy()) CI->setName("call"); + if (getTarget().getTriple().isSPIRVLogical() && CI->isConvergent()) + CI = addControlledConvergenceToken(CI); + // Update largest vector width from the return type. LargestVectorWidth = std::max(LargestVectorWidth, getMaxVectorWidth(CI->getType())); diff --git a/clang/lib/CodeGen/CGLoopInfo.h b/clang/lib/CodeGen/CGLoopInfo.h index a1c8c7e5307f..0fe33b289130 100644 --- a/clang/lib/CodeGen/CGLoopInfo.h +++ b/clang/lib/CodeGen/CGLoopInfo.h @@ -110,6 +110,10 @@ public: /// been processed. void finish(); + /// Returns the first outer loop containing this loop if any, nullptr + /// otherwise. + const LoopInfo *getParent() const { return Parent; } + private: /// Loop ID metadata. llvm::TempMDTuple TempLoopID; @@ -291,12 +295,13 @@ public: /// Set no progress for the next loop pushed. void setMustProgress(bool P) { StagedAttrs.MustProgress = P; } -private: /// Returns true if there is LoopInfo on the stack. bool hasInfo() const { return !Active.empty(); } /// Return the LoopInfo for the current loop. HasInfo should be called /// first to ensure LoopInfo is present. const LoopInfo &getInfo() const { return *Active.back(); } + +private: /// The set of attributes that will be applied to the next pushed loop. LoopAttributes StagedAttrs; /// Stack of active loops. diff --git a/clang/lib/CodeGen/CodeGenFunction.h b/clang/lib/CodeGen/CodeGenFunction.h index 8dd6da5f85f1..e2a7e28c8211 100644 --- a/clang/lib/CodeGen/CodeGenFunction.h +++ b/clang/lib/CodeGen/CodeGenFunction.h @@ -4985,6 +4985,25 @@ public: llvm::Value *emitBoolVecConversion(llvm::Value *SrcVec, unsigned NumElementsDst, const llvm::Twine &Name = ""); + // Adds a convergence_ctrl token to |Input| and emits the required parent + // convergence instructions. + llvm::CallBase *addControlledConvergenceToken(llvm::CallBase *Input); + +private: + // Emits a convergence_loop instruction for the given |BB|, with |ParentToken| + // as it's parent convergence instr. + llvm::IntrinsicInst *emitConvergenceLoopToken(llvm::BasicBlock *BB, + llvm::Value *ParentToken); + // Adds a convergence_ctrl token with |ParentToken| as parent convergence + // instr to the call |Input|. + llvm::CallBase *addConvergenceControlToken(llvm::CallBase *Input, + llvm::Value *ParentToken); + // Find the convergence_entry instruction |F|, or emits ones if none exists. + // Returns the convergence instruction. + llvm::IntrinsicInst *getOrEmitConvergenceEntryToken(llvm::Function *F); + // Find the convergence_loop instruction for the loop defined by |LI|, or + // emits one if none exists. Returns the convergence instruction. + llvm::IntrinsicInst *getOrEmitConvergenceLoopToken(const LoopInfo *LI); private: llvm::MDNode *getRangeForLoadFromType(QualType Ty); diff --git a/clang/lib/Headers/hlsl/hlsl_intrinsics.h b/clang/lib/Headers/hlsl/hlsl_intrinsics.h index d47eab453f87..ecf20f6f1136 100644 --- a/clang/lib/Headers/hlsl/hlsl_intrinsics.h +++ b/clang/lib/Headers/hlsl/hlsl_intrinsics.h @@ -1389,7 +1389,12 @@ float4 trunc(float4); /// true, across all active lanes in the current wave. _HLSL_AVAILABILITY(shadermodel, 6.0) _HLSL_BUILTIN_ALIAS(__builtin_hlsl_wave_active_count_bits) -uint WaveActiveCountBits(bool Val); +__attribute__((convergent)) uint WaveActiveCountBits(bool Val); + +/// \brief Returns the index of the current lane within the current wave. +_HLSL_AVAILABILITY(shadermodel, 6.0) +_HLSL_BUILTIN_ALIAS(__builtin_hlsl_wave_get_lane_index) +__attribute__((convergent)) uint WaveGetLaneIndex(); } // namespace hlsl #endif //_HLSL_HLSL_INTRINSICS_H_ diff --git a/clang/test/CodeGenHLSL/builtins/wave_get_lane_index_do_while.hlsl b/clang/test/CodeGenHLSL/builtins/wave_get_lane_index_do_while.hlsl new file mode 100644 index 000000000000..9481b0d60a27 --- /dev/null +++ b/clang/test/CodeGenHLSL/builtins/wave_get_lane_index_do_while.hlsl @@ -0,0 +1,40 @@ +// RUN: %clang_cc1 -std=hlsl2021 -finclude-default-header -x hlsl -triple \ +// RUN: spirv-pc-vulkan-library %s -emit-llvm -disable-llvm-passes -o - | FileCheck %s + +// CHECK: define spir_func void @main() [[A0:#[0-9]+]] { +void main() { +// CHECK: entry: +// CHECK: %[[CT_ENTRY:[0-9]+]] = call token @llvm.experimental.convergence.entry() +// CHECK: br label %[[LABEL_WHILE_COND:.+]] + int cond = 0; + +// CHECK: [[LABEL_WHILE_COND]]: +// CHECK: %[[CT_LOOP:[0-9]+]] = call token @llvm.experimental.convergence.loop() [ "convergencectrl"(token %[[CT_ENTRY]]) ] +// CHECK: br label %[[LABEL_WHILE_BODY:.+]] + while (true) { + +// CHECK: [[LABEL_WHILE_BODY]]: +// CHECK: br i1 {{%.+}}, label %[[LABEL_IF_THEN:.+]], label %[[LABEL_IF_END:.+]] + +// CHECK: [[LABEL_IF_THEN]]: +// CHECK: call i32 @__hlsl_wave_get_lane_index() [ "convergencectrl"(token %[[CT_LOOP]]) ] +// CHECK: br label %[[LABEL_WHILE_END:.+]] + if (cond == 2) { + uint index = WaveGetLaneIndex(); + break; + } + +// CHECK: [[LABEL_IF_END]]: +// CHECK: br label %[[LABEL_WHILE_COND]] + cond++; + } + +// CHECK: [[LABEL_WHILE_END]]: +// CHECK: ret void +} + +// CHECK-DAG: declare i32 @__hlsl_wave_get_lane_index() [[A1:#[0-9]+]] + +// CHECK-DAG: attributes [[A0]] = {{{.*}}convergent{{.*}}} +// CHECK-DAG: attributes [[A1]] = {{{.*}}convergent{{.*}}} + diff --git a/clang/test/CodeGenHLSL/builtins/wave_get_lane_index_simple.hlsl b/clang/test/CodeGenHLSL/builtins/wave_get_lane_index_simple.hlsl new file mode 100644 index 000000000000..8f52d81091c1 --- /dev/null +++ b/clang/test/CodeGenHLSL/builtins/wave_get_lane_index_simple.hlsl @@ -0,0 +1,14 @@ +// RUN: %clang_cc1 -std=hlsl2021 -finclude-default-header -x hlsl -triple \ +// RUN: spirv-pc-vulkan-library %s -emit-llvm -disable-llvm-passes -o - | FileCheck %s + +// CHECK: define spir_func noundef i32 @_Z6test_1v() [[A0:#[0-9]+]] { +// CHECK: %[[CI:[0-9]+]] = call token @llvm.experimental.convergence.entry() +// CHECK: call i32 @__hlsl_wave_get_lane_index() [ "convergencectrl"(token %[[CI]]) ] +uint test_1() { + return WaveGetLaneIndex(); +} + +// CHECK: declare i32 @__hlsl_wave_get_lane_index() [[A1:#[0-9]+]] + +// CHECK-DAG: attributes [[A0]] = { {{.*}}convergent{{.*}} } +// CHECK-DAG: attributes [[A1]] = { {{.*}}convergent{{.*}} } diff --git a/clang/test/CodeGenHLSL/builtins/wave_get_lane_index_subcall.hlsl b/clang/test/CodeGenHLSL/builtins/wave_get_lane_index_subcall.hlsl new file mode 100644 index 000000000000..379c8f118f52 --- /dev/null +++ b/clang/test/CodeGenHLSL/builtins/wave_get_lane_index_subcall.hlsl @@ -0,0 +1,21 @@ +// RUN: %clang_cc1 -std=hlsl2021 -finclude-default-header -x hlsl -triple \ +// RUN: spirv-pc-vulkan-library %s -emit-llvm -disable-llvm-passes -o - | FileCheck %s + +// CHECK: define spir_func noundef i32 @_Z6test_1v() [[A0:#[0-9]+]] { +// CHECK: %[[C1:[0-9]+]] = call token @llvm.experimental.convergence.entry() +// CHECK: call i32 @__hlsl_wave_get_lane_index() [ "convergencectrl"(token %[[C1]]) ] +uint test_1() { + return WaveGetLaneIndex(); +} + +// CHECK-DAG: declare i32 @__hlsl_wave_get_lane_index() [[A1:#[0-9]+]] + +// CHECK: define spir_func noundef i32 @_Z6test_2v() [[A0]] { +// CHECK: %[[C2:[0-9]+]] = call token @llvm.experimental.convergence.entry() +// CHECK: call spir_func noundef i32 @_Z6test_1v() [ "convergencectrl"(token %[[C2]]) ] +uint test_2() { + return test_1(); +} + +// CHECK-DAG: attributes [[A0]] = {{{.*}}convergent{{.*}}} +// CHECK-DAG: attributes [[A1]] = {{{.*}}convergent{{.*}}} diff --git a/llvm/include/llvm/IR/IntrinsicInst.h b/llvm/include/llvm/IR/IntrinsicInst.h index c07b83a81a63..4f22720f1c55 100644 --- a/llvm/include/llvm/IR/IntrinsicInst.h +++ b/llvm/include/llvm/IR/IntrinsicInst.h @@ -1782,6 +1782,19 @@ public: static bool classof(const Value *V) { return isa(V) && classof(cast(V)); } + + // Returns the convergence intrinsic referenced by |I|'s convergencectrl + // attribute if any. + static IntrinsicInst *getParentConvergenceToken(Instruction *I) { + auto *CI = dyn_cast(I); + if (!CI) + return nullptr; + + auto Bundle = CI->getOperandBundle(llvm::LLVMContext::OB_convergencectrl); + assert(Bundle->Inputs.size() == 1 && + Bundle->Inputs[0]->getType()->isTokenTy()); + return dyn_cast(Bundle->Inputs[0].get()); + } }; } // end namespace llvm -- GitLab From 36b86438d7cd652bcac3fce51c1bdfad99536ec8 Mon Sep 17 00:00:00 2001 From: Farzon Lotfi <1802579+farzonl@users.noreply.github.com> Date: Thu, 28 Mar 2024 12:32:28 -0400 Subject: [PATCH 074/788] [DXIL] Implement pow lowering (#86733) closes #86179 - `DXILIntrinsicExpansion.cpp` - add the pow expansion to exp2(y*log2(x)) --- .../Target/DirectX/DXILIntrinsicExpansion.cpp | 23 +++++++++++++++ llvm/test/CodeGen/DirectX/pow-vec.ll | 15 ++++++++++ llvm/test/CodeGen/DirectX/pow.ll | 29 +++++++++++++++++++ 3 files changed, 67 insertions(+) create mode 100644 llvm/test/CodeGen/DirectX/pow-vec.ll create mode 100644 llvm/test/CodeGen/DirectX/pow.ll diff --git a/llvm/lib/Target/DirectX/DXILIntrinsicExpansion.cpp b/llvm/lib/Target/DirectX/DXILIntrinsicExpansion.cpp index 3cc375edabde..3e2d10f5ee7a 100644 --- a/llvm/lib/Target/DirectX/DXILIntrinsicExpansion.cpp +++ b/llvm/lib/Target/DirectX/DXILIntrinsicExpansion.cpp @@ -37,6 +37,7 @@ static bool isIntrinsicExpansion(Function &F) { case Intrinsic::exp: case Intrinsic::log: case Intrinsic::log10: + case Intrinsic::pow: case Intrinsic::dx_any: case Intrinsic::dx_clamp: case Intrinsic::dx_uclamp: @@ -197,6 +198,26 @@ static bool expandLog10Intrinsic(CallInst *Orig) { return expandLogIntrinsic(Orig, numbers::ln2f / numbers::ln10f); } +static bool expandPowIntrinsic(CallInst *Orig) { + + Value *X = Orig->getOperand(0); + Value *Y = Orig->getOperand(1); + Type *Ty = X->getType(); + IRBuilder<> Builder(Orig->getParent()); + Builder.SetInsertPoint(Orig); + + auto *Log2Call = + Builder.CreateIntrinsic(Ty, Intrinsic::log2, {X}, nullptr, "elt.log2"); + auto *Mul = Builder.CreateFMul(Log2Call, Y); + auto *Exp2Call = + Builder.CreateIntrinsic(Ty, Intrinsic::exp2, {Mul}, nullptr, "elt.exp2"); + Exp2Call->setTailCall(Orig->isTailCall()); + Exp2Call->setAttributes(Orig->getAttributes()); + Orig->replaceAllUsesWith(Exp2Call); + Orig->eraseFromParent(); + return true; +} + static bool expandRcpIntrinsic(CallInst *Orig) { Value *X = Orig->getOperand(0); IRBuilder<> Builder(Orig->getParent()); @@ -270,6 +291,8 @@ static bool expandIntrinsic(Function &F, CallInst *Orig) { return expandLogIntrinsic(Orig); case Intrinsic::log10: return expandLog10Intrinsic(Orig); + case Intrinsic::pow: + return expandPowIntrinsic(Orig); case Intrinsic::dx_any: return expandAnyIntrinsic(Orig); case Intrinsic::dx_uclamp: diff --git a/llvm/test/CodeGen/DirectX/pow-vec.ll b/llvm/test/CodeGen/DirectX/pow-vec.ll new file mode 100644 index 000000000000..781fa5b8cb24 --- /dev/null +++ b/llvm/test/CodeGen/DirectX/pow-vec.ll @@ -0,0 +1,15 @@ +; RUN: opt -S -dxil-intrinsic-expansion < %s | FileCheck %s + +; Make sure dxil operation function calls for pow are generated for float and half. + +; CHECK-LABEL: pow_float4 +; CHECK: call <4 x float> @llvm.log2.v4f32(<4 x float> %a) +; CHECK: fmul <4 x float> %{{.*}}, %b +; CHECK: call <4 x float> @llvm.exp2.v4f32(<4 x float> %{{.*}}) +define noundef <4 x float> @pow_float4(<4 x float> noundef %a, <4 x float> noundef %b) { +entry: + %elt.pow = call <4 x float> @llvm.pow.v4f32(<4 x float> %a, <4 x float> %b) + ret <4 x float> %elt.pow +} + +declare <4 x float> @llvm.pow.v4f32(<4 x float>,<4 x float>) diff --git a/llvm/test/CodeGen/DirectX/pow.ll b/llvm/test/CodeGen/DirectX/pow.ll new file mode 100644 index 000000000000..25ce0fe731d0 --- /dev/null +++ b/llvm/test/CodeGen/DirectX/pow.ll @@ -0,0 +1,29 @@ +; RUN: opt -S -dxil-intrinsic-expansion < %s | FileCheck %s --check-prefixes=CHECK,EXPCHECK +; RUN: opt -S -dxil-op-lower < %s | FileCheck %s --check-prefixes=CHECK,DOPCHECK + +; Make sure dxil operation function calls for pow are generated. + +define noundef float @pow_float(float noundef %a, float noundef %b) { +entry: +; DOPCHECK: call float @dx.op.unary.f32(i32 23, float %a) +; EXPCHECK: call float @llvm.log2.f32(float %a) +; CHECK: fmul float %{{.*}}, %b +; DOPCHECK: call float @dx.op.unary.f32(i32 21, float %{{.*}}) +; EXPCHECK: call float @llvm.exp2.f32(float %{{.*}}) + %elt.pow = call float @llvm.pow.f32(float %a, float %b) + ret float %elt.pow +} + +define noundef half @pow_half(half noundef %a, half noundef %b) { +entry: +; DOPCHECK: call half @dx.op.unary.f16(i32 23, half %a) +; EXPCHECK: call half @llvm.log2.f16(half %a) +; CHECK: fmul half %{{.*}}, %b +; DOPCHECK: call half @dx.op.unary.f16(i32 21, half %{{.*}}) +; EXPCHECK: call half @llvm.exp2.f16(half %{{.*}}) + %elt.pow = call half @llvm.pow.f16(half %a, half %b) + ret half %elt.pow +} + +declare half @llvm.pow.f16(half,half) +declare float @llvm.pow.f32(float,float) -- GitLab From 39fe729502006f1b108828b75af8d63a27364f80 Mon Sep 17 00:00:00 2001 From: Keith Smiley Date: Thu, 28 Mar 2024 09:41:08 -0700 Subject: [PATCH 075/788] [lld-macho] Ignore -no_warn_duplicate_libraries flag (#86303) This is a new ld64 flag (along with `-warn_duplicate_libraries`), where the warning is enabled by default, and it can be useful to ignore since it can be hard to dedup library flags across large builds. This doesn't ignore the enabling version since if someone manually passed that and lld didn't respect it, we probably want the user to know that. --- lld/MachO/Options.td | 6 ++++++ lld/test/MachO/silent-ignore.s | 2 +- 2 files changed, 7 insertions(+), 1 deletion(-) diff --git a/lld/MachO/Options.td b/lld/MachO/Options.td index 19f8509ba714..11458d92b3ab 100644 --- a/lld/MachO/Options.td +++ b/lld/MachO/Options.td @@ -1413,3 +1413,9 @@ def debug_variant : Flag<["-"], "debug_variant">, HelpText<"Do not warn about issues that are only problems for binaries shipping to customers.">, Flags<[HelpHidden]>, Group; + +// NOTE: This flag should be respected if -warn_duplicate_libraries is ever implemented. +def no_warn_duplicate_libraries : Flag<["-"], "no_warn_duplicate_libraries">, + HelpText<"Do not warn if the input contains duplicate library options.">, + Flags<[HelpHidden]>, + Group; diff --git a/lld/test/MachO/silent-ignore.s b/lld/test/MachO/silent-ignore.s index e57342c28a7a..58c3cc148f07 100644 --- a/lld/test/MachO/silent-ignore.s +++ b/lld/test/MachO/silent-ignore.s @@ -20,7 +20,7 @@ ## Check that we don't emit any warnings nor errors for these unimplemented flags. # RUN: llvm-mc -filetype=obj -triple=x86_64-apple-darwin %s -o %t.o -# RUN: %lld %t.o -o /dev/null -objc_abi_version 2 -debug_variant +# RUN: %lld %t.o -o /dev/null -objc_abi_version 2 -debug_variant -no_warn_duplicate_libraries .globl _main _main: -- GitLab From 706c1302f99d79af21ddf22e23c53d33329f225a Mon Sep 17 00:00:00 2001 From: Kazu Hirata Date: Thu, 28 Mar 2024 09:43:03 -0700 Subject: [PATCH 076/788] [Dialect] Fix a warning This patch fixes: mlir/lib/Dialect/Tensor/Transforms/MergeConsecutiveInsertExtractSlicePatterns.cpp:158:17: error: 'matchAndRewrite' overrides a member function but is not marked 'override' [-Werror,-Wsuggest-override] --- .../Transforms/MergeConsecutiveInsertExtractSlicePatterns.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/mlir/lib/Dialect/Tensor/Transforms/MergeConsecutiveInsertExtractSlicePatterns.cpp b/mlir/lib/Dialect/Tensor/Transforms/MergeConsecutiveInsertExtractSlicePatterns.cpp index 59aa43222175..ff003e486d21 100644 --- a/mlir/lib/Dialect/Tensor/Transforms/MergeConsecutiveInsertExtractSlicePatterns.cpp +++ b/mlir/lib/Dialect/Tensor/Transforms/MergeConsecutiveInsertExtractSlicePatterns.cpp @@ -156,7 +156,7 @@ struct DropRedundantRankExpansionOnInsertSliceOfExtractSlice final using OpRewritePattern::OpRewritePattern; LogicalResult matchAndRewrite(tensor::InsertSliceOp insertSliceOp, - PatternRewriter &rewriter) const { + PatternRewriter &rewriter) const override { auto extractSliceOp = insertSliceOp.getSource().getDefiningOp(); if (!extractSliceOp) { -- GitLab From 423832421b9b259612c3fe4169a6a6e1e2600f95 Mon Sep 17 00:00:00 2001 From: Charlie Barto Date: Thu, 28 Mar 2024 09:52:25 -0700 Subject: [PATCH 077/788] [asan][windows] Weak function interception support in instruction size decoder. (#86570) This makes it so we'll be able to decode the instructions used in the weak function stubs from https://github.com/llvm/llvm-project/pull/81677. This code doesn't technically require those changes. Co-authored-by: Amy Wishnousky --- compiler-rt/lib/interception/interception_win.cpp | 11 ++++++++++- 1 file changed, 10 insertions(+), 1 deletion(-) diff --git a/compiler-rt/lib/interception/interception_win.cpp b/compiler-rt/lib/interception/interception_win.cpp index a04175ba1e4b..a638e66eccee 100644 --- a/compiler-rt/lib/interception/interception_win.cpp +++ b/compiler-rt/lib/interception/interception_win.cpp @@ -479,6 +479,8 @@ static size_t GetInstructionSize(uptr address, size_t* rel_offset = nullptr) { switch (*(u8*)address) { case 0x90: // 90 : nop + case 0xC3: // C3 : ret (for small/empty function interception + case 0xCC: // CC : int 3 i.e. registering weak functions) return 1; case 0x50: // push eax / rax @@ -502,7 +504,6 @@ static size_t GetInstructionSize(uptr address, size_t* rel_offset = nullptr) { // Cannot overwrite control-instruction. Return 0 to indicate failure. case 0xE9: // E9 XX XX XX XX : jmp