diff --git a/clang/lib/CodeGen/BackendUtil.cpp b/clang/lib/CodeGen/BackendUtil.cpp index f7c975fc70423..cef177d76af7b 100644 --- a/clang/lib/CodeGen/BackendUtil.cpp +++ b/clang/lib/CodeGen/BackendUtil.cpp @@ -1109,6 +1109,9 @@ void EmitAssemblyHelper::RunOptimizationPipeline( MPM.addPass(SYCLPropagateJointMatrixUsagePass()); // Lowers static/dynamic local memory builtin calls. MPM.addPass(SYCLLowerWGLocalMemoryPass()); + // Compile-time properties pass must create standard metadata as early + // as possible to make them available for other passes. + MPM.addPass(CompileTimePropertiesPass()); }); else if (LangOpts.SYCLIsHost && !LangOpts.SYCLESIMDBuildHostCode) PB.registerPipelineStartEPCallback( @@ -1271,9 +1274,6 @@ void EmitAssemblyHelper::RunOptimizationPipeline( MPM.addPass(SPIRITTAnnotationsPass()); } - // Process properties and annotations - MPM.addPass(CompileTimePropertiesPass()); - // Record SYCL aspect names (this should come after propagating aspects // and before cleaning up metadata) MPM.addPass(RecordSYCLAspectNamesPass()); diff --git a/clang/test/CodeGenSYCL/kernel-early-optimization-pipeline.cpp b/clang/test/CodeGenSYCL/kernel-early-optimization-pipeline.cpp index d352f1bcca39a..1af3368350bed 100644 --- a/clang/test/CodeGenSYCL/kernel-early-optimization-pipeline.cpp +++ b/clang/test/CodeGenSYCL/kernel-early-optimization-pipeline.cpp @@ -9,6 +9,7 @@ // CHECK: SYCLPropagateAspectsUsagePass // CHECK: SYCLPropagateJointMatrixUsagePass // CHECK: SYCLLowerWGLocalMemoryPass +// CHECK: CompileTimePropertiesPass // CHECK: InferFunctionAttrsPass // CHECK: AlwaysInlinerPass // CHECK: ModuleInlinerWrapperPass @@ -17,7 +18,6 @@ // CHECK: SYCLMutatePrintfAddrspacePass // CHECK: SYCLPropagateAspectsUsagePass // CHECK: SYCLAddOptLevelAttributePass -// CHECK: CompileTimePropertiesPass // CHECK: RecordSYCLAspectNamesPass // CHECK: CleanupSYCLMetadataPass // diff --git a/llvm/lib/SYCLLowerIR/CompileTimePropertiesPass.cpp b/llvm/lib/SYCLLowerIR/CompileTimePropertiesPass.cpp index e1d0e46df0863..ca79ecc028915 100644 --- a/llvm/lib/SYCLLowerIR/CompileTimePropertiesPass.cpp +++ b/llvm/lib/SYCLLowerIR/CompileTimePropertiesPass.cpp @@ -943,16 +943,28 @@ bool CompileTimePropertiesPass::transformSYCLPropertiesAnnotation( LLVMContext &Ctx = M.getContext(); unsigned MDKindID = Ctx.getMDKindID(SpirvDecorMdKind); if (!FPGAProp && llvm::isa(IntrInst->getArgOperand(0))) { - // If there are no annotations other than cache controls we can apply the - // controls to the pointer and remove the intrinsic. + // Find all load/store instructions using the pointer being annotated and + // apply the cache control metadata to them. + SmallVector, 8> TargetedInstList; + getUserListIgnoringCast(IntrInst, TargetedInstList); + getUserListIgnoringCast(IntrInst, TargetedInstList); + getUserListIgnoringCast(IntrInst, TargetedInstList); + for (const auto &[Inst, MDVal] : TargetedInstList) { + // Merge with existing metadata if present. + SmallVector MDOps; + if (MDNode *CurrentMD = Inst->getMetadata(MDKindID)) + for (Metadata *Op : CurrentMD->operands()) + MDOps.push_back(Op); + for (Metadata *Op : MDOpsCacheProp) + MDOps.push_back(Op); + MDOps.push_back(ConstantAsMetadata::get(Constant::getIntegerValue( + Type::getInt32Ty(Ctx), APInt(32, MDVal)))); + Inst->setMetadata(MDKindID, MDTuple::get(Ctx, MDOps)); + } + // Replace all uses of ptr.annotations intrinsic with first operand and + // delete the original intrinsic. Instruction *PtrInstr = cast(IntrInst->getArgOperand(0)); - if (MDNode *CurrentMD = PtrInstr->getMetadata(MDKindID)) - for (Metadata *Op : CurrentMD->operands()) - MDOpsCacheProp.push_back(Op); - PtrInstr->setMetadata(MDKindID, MDTuple::get(Ctx, MDOpsCacheProp)); - // Replace all uses of IntrInst with first operand IntrInst->replaceAllUsesWith(PtrInstr); - // Delete the original IntrInst RemovableAnnotations.push_back(IntrInst); } else { // If there were FPGA annotations then we retain the original intrinsic diff --git a/sycl/test/check_device_code/extensions/properties/properties_cache_control.cpp b/sycl/test/check_device_code/extensions/properties/properties_cache_control.cpp index 6497dd0e70730..6d1b21b41fe37 100644 --- a/sycl/test/check_device_code/extensions/properties/properties_cache_control.cpp +++ b/sycl/test/check_device_code/extensions/properties/properties_cache_control.cpp @@ -171,57 +171,62 @@ SYCL_EXTERNAL void annotated_ptr_func_param_test(float *p) { } // CHECK: spir_func{{.*}}annotated_ptr_func_param_test -// CHECK: {{.*}}call ptr addrspace(4) @llvm.ptr.annotation.p4.p1{{.*}}!spirv.Decorations [[WHINT:.*]] +// CHECK: store float 4.200000e+01, ptr addrspace(4) %{{.*}}, !spirv.Decorations ![[WHINT:[0-9]+]] // CHECK: ret void // CHECK: spir_kernel{{.*}}cache_control_read_hint_func -// CHECK: {{.*}}addrspacecast ptr addrspace(1){{.*}}!spirv.Decorations [[RHINT:.*]] +// CHECK: store float 5.500000e+01, ptr addrspace(1) %{{.*}}, !spirv.Decorations ![[RHINT:[0-9]+]] // CHECK: ret void // CHECK: spir_kernel{{.*}}cache_control_read_assertion_func -// CHECK: {{.*}}addrspacecast ptr addrspace(1){{.*}}!spirv.Decorations [[RASSERT:.*]] +// CHECK: store i32 66, ptr addrspace(1) %{{.*}}, !spirv.Decorations ![[RASSERT:[0-9]+]] // CHECK: ret void // CHECK: spir_kernel{{.*}}cache_control_write_hint_func -// CHECK: {{.*}}addrspacecast ptr addrspace(1){{.*}}!spirv.Decorations [[WHINT]] +// CHECK: store float 7.700000e+01, ptr addrspace(1) %{{.*}}, !spirv.Decorations ![[WHINT]] // CHECK: ret void // CHECK: spir_kernel{{.*}}cache_control_read_write_func -// CHECK: {{.*}}addrspacecast ptr addrspace(1){{.*}}!spirv.Decorations [[RWHINT:.*]] +// CHECK: store float 7.700000e+01, ptr addrspace(1) %{{.*}}, !spirv.Decorations ![[RWHINT:[0-9]+]] // CHECK: ret void // CHECK: spir_kernel{{.*}}cache_control_load_store_func -// CHECK: {{.*}}getelementptr{{.*}}addrspace(4){{.*}}!spirv.Decorations [[LDSTHINT_A:.*]] -// CHECK: {{.*}}getelementptr{{.*}}addrspace(4){{.*}}!spirv.Decorations [[LDSTHINT_B:.*]] +// CHECK: store double 1.000000e+00, ptr addrspace(1) %[[PTR_A:.*]], align 8{{.*}}, !spirv.Decorations ![[STHINT_A:[0-9]+]] +// CHECK: store double 1.000000e+00, ptr addrspace(1) %[[PTR_B:.*]], align 8{{.*}}, !spirv.Decorations ![[STHINT_B:[0-9]+]] +// CHECK: load double, ptr addrspace(1) %[[PTR_A]], align 8{{.*}}, !spirv.Decorations ![[LDHINT_A:[0-9]+]] +// CHECK: load double, ptr addrspace(1) %[[PTR_B]], align 8{{.*}}, !spirv.Decorations ![[LDHINT_B:[0-9]+]] // CHECK: ret void -// CHECK: [[WHINT]] = !{[[WHINT1:.*]], [[WHINT2:.*]], [[WHINT3:.*]], [[WHINT4:.*]]} +// CHECK: [[WHINT]] = !{[[WHINT1:.*]], [[WHINT2:.*]], [[WHINT3:.*]], [[WHINT4:.*]], i32 1} // CHECK: [[WHINT1]] = !{i32 6443, i32 3, i32 3} // CHECK: [[WHINT2]] = !{i32 6443, i32 0, i32 1} // CHECK: [[WHINT3]] = !{i32 6443, i32 1, i32 2} // CHECK: [[WHINT4]] = !{i32 6443, i32 2, i32 2} -// CHECK: [[RHINT]] = !{[[RHINT1:.*]], [[RHINT2:.*]], [[RHINT3:.*]]} +// CHECK: [[RHINT]] = !{[[RHINT1:.*]], [[RHINT2:.*]], [[RHINT3:.*]], i32 1} // CHECK: [[RHINT1]] = !{i32 6442, i32 1, i32 0} // CHECK: [[RHINT2]] = !{i32 6442, i32 2, i32 0} // CHECK: [[RHINT3]] = !{i32 6442, i32 0, i32 1} -// CHECK: [[RASSERT]] = !{[[RASSERT1:.*]], [[RASSERT2:.*]], [[RASSERT3:.*]]} +// CHECK: [[RASSERT]] = !{[[RASSERT1:.*]], [[RASSERT2:.*]], [[RASSERT3:.*]], i32 1} // CHECK: [[RASSERT1]] = !{i32 6442, i32 1, i32 3} // CHECK: [[RASSERT2]] = !{i32 6442, i32 2, i32 3} // CHECK: [[RASSERT3]] = !{i32 6442, i32 0, i32 4} -// CHECK: [[RWHINT]] = !{[[RWHINT1:.*]], [[RWHINT2:.*]], [[RWHINT3:.*]]} +// CHECK: [[RWHINT]] = !{[[RWHINT1:.*]], [[RWHINT2:.*]], [[RWHINT3:.*]], i32 1} // CHECK: [[RWHINT1]] = !{i32 6442, i32 2, i32 1} // CHECK: [[RWHINT2]] = !{i32 6442, i32 3, i32 4} // CHECK: [[RWHINT3]] = !{i32 6443, i32 3, i32 1} -// CHECK: [[LDSTHINT_A]] = !{[[RHINT1]], [[RHINT2]], [[RHINT3]], [[LDSTHINT_A1:.*]], [[LDSTHINT_A2:.*]], [[LDSTHINT_A3:.*]]} -// CHECK: [[LDSTHINT_A1]] = !{i32 6443, i32 0, i32 0} -// CHECK: [[LDSTHINT_A2]] = !{i32 6443, i32 1, i32 0} -// CHECK: [[LDSTHINT_A3]] = !{i32 6443, i32 2, i32 0} +// CHECK: [[STHINT_A]] = !{[[STHINT_A1:.*]], [[STHINT_A2:.*]], [[STHINT_A3:.*]], i32 1} +// CHECK: [[STHINT_A1]] = !{i32 6443, i32 0, i32 0} +// CHECK: [[STHINT_A2]] = !{i32 6443, i32 1, i32 0} +// CHECK: [[STHINT_A3]] = !{i32 6443, i32 2, i32 0} -// CHECK: [[LDSTHINT_B]] = !{[[LDSTHINT_B1:.*]], [[RWHINT1]], [[LDSTHINT_B2:.*]], [[LDSTHINT_A2]], [[LDSTHINT_A3]], [[LDSTHINT_B3:.*]]} -// CHECK: [[LDSTHINT_B1]] = !{i32 6442, i32 1, i32 1} -// CHECK: [[LDSTHINT_B2]] = !{i32 6442, i32 0, i32 2} -// CHECK: [[LDSTHINT_B3]] = !{i32 6443, i32 0, i32 2} +// CHECK: [[STHINT_B]] = !{[[STHINT_A2]], [[STHINT_A3]], [[STHINT_B1:.*]], i32 1} +// CHECK: [[STHINT_B1]] = !{i32 6443, i32 0, i32 2} + +// CHECK: [[LDHINT_A]] = !{[[RHINT1]], [[RHINT2]], [[RHINT3]], i32 0} +// CHECK: [[LDHINT_B]] = !{[[LDHINT_B1:.*]], [[RWHINT1]], [[LDHINT_B2:.*]], i32 0} +// CHECK: [[LDHINT_B1]] = !{i32 6442, i32 1, i32 1} +// CHECK: [[LDHINT_B2]] = !{i32 6442, i32 0, i32 2}