From 241df8bc9a915df7bdccf5f5064c3cb213020ae1 Mon Sep 17 00:00:00 2001 From: TB Schardl Date: Sun, 18 Dec 2022 22:03:43 -0500 Subject: [PATCH 1/6] [Basic,CodeGen,Sema,IR,Tapir] Modify hyper_lookup intrinsic to pass additional information about the reducer being looked up, namely, its view size, identity function, and reduce function. --- clang/include/clang/Basic/Builtins.def | 2 +- clang/lib/CodeGen/CGBuiltin.cpp | 7 +++++-- clang/lib/Sema/SemaExpr.cpp | 10 ++++++++-- llvm/include/llvm/IR/Intrinsics.td | 8 +++++--- llvm/lib/Transforms/Tapir/OpenCilkABI.cpp | 5 +++-- 5 files changed, 22 insertions(+), 10 deletions(-) diff --git a/clang/include/clang/Basic/Builtins.def b/clang/include/clang/Basic/Builtins.def index ffc35f299ac9..b422ac35f64a 100644 --- a/clang/include/clang/Basic/Builtins.def +++ b/clang/include/clang/Basic/Builtins.def @@ -1691,7 +1691,7 @@ LANGBUILTIN(__arithmetic_fence, "v.", "t", ALL_LANGUAGES) // Tapir. Rewriting of reducer references happens during sema // and needs a builtin to carry the information to codegen. -BUILTIN(__hyper_lookup, "v*vC*", "nU") +BUILTIN(__hyper_lookup, "v*vC*zvC*vC*", "nU") #undef BUILTIN #undef LIBBUILTIN diff --git a/clang/lib/CodeGen/CGBuiltin.cpp b/clang/lib/CodeGen/CGBuiltin.cpp index 64a9525b2103..ce044c3dafd2 100644 --- a/clang/lib/CodeGen/CGBuiltin.cpp +++ b/clang/lib/CodeGen/CGBuiltin.cpp @@ -5438,8 +5438,11 @@ RValue CodeGenFunction::EmitBuiltinExpr(const GlobalDecl GD, unsigned BuiltinID, return RValue::get(Ptr); } case Builtin::BI__hyper_lookup: { - Function *F = CGM.getIntrinsic(Intrinsic::hyper_lookup); - return RValue::get(Builder.CreateCall(F, {EmitScalarExpr(E->getArg(0))})); + llvm::Value *Size = EmitScalarExpr(E->getArg(1)); + Function *F = CGM.getIntrinsic(Intrinsic::hyper_lookup, Size->getType()); + return RValue::get(Builder.CreateCall( + F, {EmitScalarExpr(E->getArg(0)), Size, EmitScalarExpr(E->getArg(2)), + EmitScalarExpr(E->getArg(3))})); } } IsSpawnedScope SpawnedScp(this); diff --git a/clang/lib/Sema/SemaExpr.cpp b/clang/lib/Sema/SemaExpr.cpp index 2edad31e6e44..c5893fdd8083 100644 --- a/clang/lib/Sema/SemaExpr.cpp +++ b/clang/lib/Sema/SemaExpr.cpp @@ -2049,6 +2049,9 @@ Expr *Sema::BuildHyperobjectLookup(Expr *E, bool Pointer) { InputType.getLocalFastQualifiers()); QualType Ptr = Context.getPointerType(ResultType); + QualType SizeType = Context.getSizeType(); + llvm::APInt Size(Context.getTypeSize(SizeType), + Context.getTypeSizeInChars(ResultType).getQuantity()); Expr *VarAddr; if (Pointer) VarAddr = E; @@ -2075,8 +2078,11 @@ Expr *Sema::BuildHyperobjectLookup(Expr *E, bool Pointer) { SourceLocation(), false, CurFPFeatureOverrides()); } - ExprResult Call = BuildCallExpr(nullptr, Lookup, E->getExprLoc(), - { VarAddr }, E->getExprLoc(), nullptr); + Expr *CallArgs[] = { + VarAddr, IntegerLiteral::Create(Context, Size, SizeType, E->getExprLoc()), + HT->getIdentity(), HT->getReduce()}; + ExprResult Call = BuildCallExpr(nullptr, Lookup, E->getExprLoc(), CallArgs, + E->getExprLoc(), nullptr); // Template expansion normally strips out implicit casts, // so make this explicit in C++. diff --git a/llvm/include/llvm/IR/Intrinsics.td b/llvm/include/llvm/IR/Intrinsics.td index 8c8aaf3a36da..467d88b10f35 100644 --- a/llvm/include/llvm/IR/Intrinsics.td +++ b/llvm/include/llvm/IR/Intrinsics.td @@ -1386,9 +1386,11 @@ def int_task_frameaddress // Ideally the types would be [llvm_anyptr_ty], [LLVMMatchType<0>] // but that does not work, so rely on the front end to insert bitcasts. def int_hyper_lookup - : Intrinsic<[llvm_ptr_ty], [llvm_ptr_ty], - [IntrWillReturn, IntrReadMem, IntrInaccessibleMemOnly, - IntrStrandPure, IntrHyperView, IntrInjective]>; + : Intrinsic<[llvm_ptr_ty], + [llvm_ptr_ty, llvm_anyint_ty, llvm_ptr_ty, llvm_ptr_ty], [ + IntrWillReturn, IntrReadMem, IntrInaccessibleMemOnly, + IntrStrandPure, IntrHyperView, IntrInjective + ]>; // TODO: Change tablegen to allow function pointer types in intrinsics. def int_reducer_register diff --git a/llvm/lib/Transforms/Tapir/OpenCilkABI.cpp b/llvm/lib/Transforms/Tapir/OpenCilkABI.cpp index 551ef5206bed..6ef000b1d886 100644 --- a/llvm/lib/Transforms/Tapir/OpenCilkABI.cpp +++ b/llvm/lib/Transforms/Tapir/OpenCilkABI.cpp @@ -223,7 +223,8 @@ void OpenCilkABI::prepareModule() { FunctionType *Grainsize16FnTy = FunctionType::get(Int16Ty, {Int16Ty}, false); FunctionType *Grainsize32FnTy = FunctionType::get(Int32Ty, {Int32Ty}, false); FunctionType *Grainsize64FnTy = FunctionType::get(Int64Ty, {Int64Ty}, false); - FunctionType *PtrPtrTy = FunctionType::get(VoidPtrTy, {VoidPtrTy}, false); + FunctionType *LookupTy = FunctionType::get( + VoidPtrTy, {VoidPtrTy, Int64Ty, VoidPtrTy, VoidPtrTy}, false); FunctionType *UnregTy = FunctionType::get(VoidTy, {VoidPtrTy}, false); FunctionType *Reg32Ty = FunctionType::get(VoidTy, {VoidPtrTy, Int32Ty, VoidPtrTy, @@ -258,7 +259,7 @@ void OpenCilkABI::prepareModule() { CilkRTSCilkForGrainsize32}, {"__cilkrts_cilk_for_grainsize_64", Grainsize64FnTy, CilkRTSCilkForGrainsize64}, - {"__cilkrts_reducer_lookup", PtrPtrTy, CilkRTSReducerLookup}, + {"__cilkrts_reducer_lookup", LookupTy, CilkRTSReducerLookup}, {"__cilkrts_reducer_register_32", Reg32Ty, CilkRTSReducerRegister32}, {"__cilkrts_reducer_register_64", Reg64Ty, CilkRTSReducerRegister64}, {"__cilkrts_reducer_unregister", UnregTy, CilkRTSReducerUnregister}, From 4ea5465ad3aa7d1a4cfb1d74788e10555225413c Mon Sep 17 00:00:00 2001 From: TB Schardl Date: Wed, 4 Jan 2023 00:31:50 +0000 Subject: [PATCH 2/6] [CodeGen,Sema] Fix support for __hyper_lookup calls in dependent contexts. --- clang/include/clang/Basic/Builtins.def | 2 +- clang/lib/CodeGen/CGBuiltin.cpp | 7 ++- clang/lib/Sema/SemaExpr.cpp | 85 ++++++++++++-------------- 3 files changed, 46 insertions(+), 48 deletions(-) diff --git a/clang/include/clang/Basic/Builtins.def b/clang/include/clang/Basic/Builtins.def index b422ac35f64a..c06f8d514b6f 100644 --- a/clang/include/clang/Basic/Builtins.def +++ b/clang/include/clang/Basic/Builtins.def @@ -1691,7 +1691,7 @@ LANGBUILTIN(__arithmetic_fence, "v.", "t", ALL_LANGUAGES) // Tapir. Rewriting of reducer references happens during sema // and needs a builtin to carry the information to codegen. -BUILTIN(__hyper_lookup, "v*vC*zvC*vC*", "nU") +BUILTIN(__hyper_lookup, "v*vC*z.", "nU") #undef BUILTIN #undef LIBBUILTIN diff --git a/clang/lib/CodeGen/CGBuiltin.cpp b/clang/lib/CodeGen/CGBuiltin.cpp index ce044c3dafd2..04161c8decfd 100644 --- a/clang/lib/CodeGen/CGBuiltin.cpp +++ b/clang/lib/CodeGen/CGBuiltin.cpp @@ -5440,9 +5440,12 @@ RValue CodeGenFunction::EmitBuiltinExpr(const GlobalDecl GD, unsigned BuiltinID, case Builtin::BI__hyper_lookup: { llvm::Value *Size = EmitScalarExpr(E->getArg(1)); Function *F = CGM.getIntrinsic(Intrinsic::hyper_lookup, Size->getType()); + llvm::Value *Ptr = EmitScalarExpr(E->getArg(0)); + llvm::Value *Identity = EmitScalarExpr(E->getArg(2)); + llvm::Value *Reduce = EmitScalarExpr(E->getArg(3)); return RValue::get(Builder.CreateCall( - F, {EmitScalarExpr(E->getArg(0)), Size, EmitScalarExpr(E->getArg(2)), - EmitScalarExpr(E->getArg(3))})); + F, {Ptr, Size, Builder.CreateBitCast(Identity, VoidPtrTy), + Builder.CreateBitCast(Reduce, VoidPtrTy)})); } } IsSpawnedScope SpawnedScp(this); diff --git a/clang/lib/Sema/SemaExpr.cpp b/clang/lib/Sema/SemaExpr.cpp index c5893fdd8083..4fb5508f18d6 100644 --- a/clang/lib/Sema/SemaExpr.cpp +++ b/clang/lib/Sema/SemaExpr.cpp @@ -2033,12 +2033,10 @@ Expr *Sema::BuildHyperobjectLookup(Expr *E, bool Pointer) { // For now all hyperobjects use the same lookup function. IdentifierInfo *ID = PP.getIdentifierInfo("__hyper_lookup"); - ValueDecl *Builtin = - dyn_cast - (LazilyCreateBuiltin(ID, ID->getBuiltinID(), - /* Scope = */ nullptr, - /* ForRedeclaration = */ false, - SourceLocation())); + ValueDecl *Builtin = dyn_cast( + LazilyCreateBuiltin(ID, ID->getBuiltinID(), + /* Scope = */ nullptr, + /* ForRedeclaration = */ false, SourceLocation())); // __hyper_lookup must be defined in Builtins.def. assert(Builtin && "no __hyper_lookup builtin"); @@ -2049,65 +2047,62 @@ Expr *Sema::BuildHyperobjectLookup(Expr *E, bool Pointer) { InputType.getLocalFastQualifiers()); QualType Ptr = Context.getPointerType(ResultType); - QualType SizeType = Context.getSizeType(); - llvm::APInt Size(Context.getTypeSize(SizeType), - Context.getTypeSizeInChars(ResultType).getQuantity()); + ExprResult SizeExpr; + if (ResultType.getTypePtr()->isDependentType()) { + SizeExpr = CreateUnaryExprOrTypeTraitExpr(E, E->getExprLoc(), UETT_SizeOf); + } else { + QualType SizeType = Context.getSizeType(); + llvm::APInt Size(Context.getTypeSize(SizeType), + Context.getTypeSizeInChars(ResultType).getQuantity()); + SizeExpr = IntegerLiteral::Create(Context, Size, SizeType, E->getExprLoc()); + } + Expr *VarAddr; - if (Pointer) + if (Pointer) { VarAddr = E; - else if (Difficult) { + } else if (Difficult) { IdentifierInfo *BAI = PP.getIdentifierInfo("__builtin_addressof"); - ValueDecl *BAV = - dyn_cast - (LazilyCreateBuiltin(BAI, BAI->getBuiltinID(), - /* Scope = */ nullptr, - /* ForRedeclaration = */ false, - SourceLocation())); + ValueDecl *BAV = dyn_cast( + LazilyCreateBuiltin(BAI, BAI->getBuiltinID(), + /* Scope = */ nullptr, + /* ForRedeclaration = */ false, SourceLocation())); assert(BAV && "no __builtin_addressof builtin"); - DeclRefExpr *BAD = BuildDeclRefExpr(BAV, Builtin->getType(), - VK_PRValue, SourceLocation(), - nullptr); + DeclRefExpr *BAD = BuildDeclRefExpr(BAV, Builtin->getType(), VK_PRValue, + SourceLocation(), nullptr); - ExprResult Address = BuildCallExpr(nullptr, BAD, E->getExprLoc(), - { E }, E->getExprLoc(), nullptr); + ExprResult Address = BuildCallExpr(nullptr, BAD, E->getExprLoc(), {E}, + E->getExprLoc(), nullptr); assert(Address.isUsable()); VarAddr = Address.get(); } else { - VarAddr = UnaryOperator::Create(Context, E, UO_AddrOf, Ptr, - VK_PRValue, OK_Ordinary, - SourceLocation(), false, + VarAddr = UnaryOperator::Create(Context, E, UO_AddrOf, Ptr, VK_PRValue, + OK_Ordinary, SourceLocation(), false, CurFPFeatureOverrides()); } - Expr *CallArgs[] = { - VarAddr, IntegerLiteral::Create(Context, Size, SizeType, E->getExprLoc()), - HT->getIdentity(), HT->getReduce()}; + Expr *CallArgs[] = {VarAddr, SizeExpr.get(), HT->getIdentity(), + HT->getReduce()}; ExprResult Call = BuildCallExpr(nullptr, Lookup, E->getExprLoc(), CallArgs, E->getExprLoc(), nullptr); - // Template expansion normally strips out implicit casts, - // so make this explicit in C++. + // Template expansion normally strips out implicit casts, so make this + // explicit in C++. CastExpr *Casted = nullptr; if (Difficult) - Casted = CXXStaticCastExpr::Create(Context, Ptr, VK_PRValue, - CK_BitCast, Call.get(), nullptr, - Context.CreateTypeSourceInfo(Ptr), - FPOptionsOverride(), - SourceLocation(), - SourceLocation(), - SourceRange()); + Casted = CXXStaticCastExpr::Create( + Context, Ptr, VK_PRValue, CK_BitCast, Call.get(), nullptr, + Context.CreateTypeSourceInfo(Ptr), FPOptionsOverride(), + SourceLocation(), SourceLocation(), SourceRange()); else - Casted = ImplicitCastExpr::Create(Context, Ptr, - CK_BitCast, - Call.get(), nullptr, VK_PRValue, - CurFPFeatureOverrides()); + Casted = + ImplicitCastExpr::Create(Context, Ptr, CK_BitCast, Call.get(), nullptr, + VK_PRValue, CurFPFeatureOverrides()); if (Pointer) return Casted; - auto *Deref = - UnaryOperator::Create(Context, Casted, UO_Deref, ResultType, - VK_LValue, OK_Ordinary, SourceLocation(), - false, CurFPFeatureOverrides()); + auto *Deref = UnaryOperator::Create(Context, Casted, UO_Deref, ResultType, + VK_LValue, OK_Ordinary, SourceLocation(), + false, CurFPFeatureOverrides()); return Deref; } From 573a186247423d83f4a310b1618be488e0882012 Mon Sep 17 00:00:00 2001 From: TB Schardl Date: Sat, 28 Jan 2023 03:22:47 +0000 Subject: [PATCH 3/6] [BasicAliasAnalysis,test/Cilk,test/Tapir] Fix test cases and alias analysis to accommodate new hyper.lookup signature. --- clang/test/Cilk/hyper-array-extern-1.cpp | 2 +- clang/test/Cilk/hyper-assign.c | 16 ++++++++-------- clang/test/Cilk/hyper-complex.c | 6 +++--- clang/test/Cilk/hyper-copy.c | 4 ++-- clang/test/Cilk/hyper-template.cpp | 2 +- clang/test/Cilk/hyper-unary.c | 18 +++++++++--------- llvm/lib/Analysis/BasicAliasAnalysis.cpp | 2 +- llvm/test/Transforms/Tapir/157.ll | 6 +++--- 8 files changed, 28 insertions(+), 28 deletions(-) diff --git a/clang/test/Cilk/hyper-array-extern-1.cpp b/clang/test/Cilk/hyper-array-extern-1.cpp index 6c649e70f70a..359e6a7f28f1 100644 --- a/clang/test/Cilk/hyper-array-extern-1.cpp +++ b/clang/test/Cilk/hyper-array-extern-1.cpp @@ -11,7 +11,7 @@ int read_array_hyper(unsigned i) return x[i]; // CHECK: %[[ARRAYIDX:.+]] = getelementptr inbounds // CHECK: %[[KEY:.+]] = bitcast i32* %[[ARRAYIDX]] to i8* - // CHECK: %[[VIEWRAW:.+]] = call i8* @llvm.hyper.lookup(i8* %[[KEY]]) + // CHECK: %[[VIEWRAW:.+]] = call i8* @llvm.hyper.lookup.i64(i8* %[[KEY]], i64 4, i8* null, i8* null) // CHECK-NOT: call i8* @llvm.hyper.lookup // CHECK: %[[VIEW:.+]] = bitcast i8* %[[VIEWRAW]] to i32* // CHECK: %[[VAL:.+]] = load i32, i32* %[[VIEW]] diff --git a/clang/test/Cilk/hyper-assign.c b/clang/test/Cilk/hyper-assign.c index 8cc91586d57d..7a656ec14bea 100644 --- a/clang/test/Cilk/hyper-assign.c +++ b/clang/test/Cilk/hyper-assign.c @@ -6,20 +6,20 @@ extern long _Hyperobject x, _Hyperobject y; long chain_assign() { - // CHECK: %[[Y1RAW:.+]] = call i8* @llvm.hyper.lookup(i8* bitcast (i64* @y to i8*)) + // CHECK: %[[Y1RAW:.+]] = call i8* @llvm.hyper.lookup.i64(i8* bitcast (i64* @y to i8*), i64 8, i8* null, i8* null) // CHECK: %[[Y1PTR:.+]] = bitcast i8* %[[Y1RAW]] to i64* // CHECK: %[[Y1VAL:.+]] = load i64, i64* %[[Y1PTR]] - // CHECK: call i8* @llvm.hyper.lookup(i8* bitcast (i64* @x to i8*)) + // CHECK: call i8* @llvm.hyper.lookup.i64(i8* bitcast (i64* @x to i8*), i64 8, i8* null, i8* null) // CHECK: store i64 %[[Y1VAL]] - // CHECK: call i8* @llvm.hyper.lookup(i8* bitcast (i64* @y to i8*)) - // CHECK: call i8* @llvm.hyper.lookup(i8* bitcast (i64* @x to i8*)) + // CHECK: call i8* @llvm.hyper.lookup.i64(i8* bitcast (i64* @y to i8*), i64 8, i8* null, i8* null) + // CHECK: call i8* @llvm.hyper.lookup.i64(i8* bitcast (i64* @x to i8*), i64 8, i8* null, i8* null) return x = y = x = y; } long simple_assign(long val) { - // CHECK: call i8* @llvm.hyper.lookup(i8* bitcast (i64* @x to i8*)) - // CHECK-NOT: call i8* @llvm.hyper.lookup(i8* bitcast (i64* @x to i8*)) + // CHECK: call i8* @llvm.hyper.lookup.i64(i8* bitcast (i64* @x to i8*), i64 8, i8* null, i8* null) + // CHECK-NOT: call i8* @llvm.hyper.lookup // CHECK: store i64 return x = val; } @@ -27,11 +27,11 @@ long simple_assign(long val) long subtract() { // The order is not fixed here. - // CHECK: call i8* @llvm.hyper.lookup(i8* bitcast (i64* @y to i8*)) + // CHECK: call i8* @llvm.hyper.lookup.i64(i8* bitcast (i64* @y to i8*), i64 8, i8* null, i8* null) // CHECK: load i64 // CHECK: add nsw i64 %[[Y:.+]], 1 // CHECK: store i64 - // CHECK: call i8* @llvm.hyper.lookup(i8* bitcast (i64* @x to i8*)) + // CHECK: call i8* @llvm.hyper.lookup.i64(i8* bitcast (i64* @x to i8*), i64 8, i8* null, i8* null) // CHECK: load i64 // CHECK: sub nsw // CHECK: store i64 diff --git a/clang/test/Cilk/hyper-complex.c b/clang/test/Cilk/hyper-complex.c index 894ab34afbf6..1567d0f2eaf1 100644 --- a/clang/test/Cilk/hyper-complex.c +++ b/clang/test/Cilk/hyper-complex.c @@ -7,7 +7,7 @@ extern __complex__ float _Hyperobject c; // CHECK-LABEL: get_real float get_real() { - // CHECK: %[[RAW1:.+]] = call i8* @llvm.hyper.lookup(i8* bitcast ({ float, float }* @c to i8*)) + // CHECK: %[[RAW1:.+]] = call i8* @llvm.hyper.lookup.i64(i8* bitcast ({ float, float }* @c to i8*), i64 8, i8* null, i8* null) // CHECK: %[[VIEW1:.+]] = bitcast i8* %[[RAW1]] to { float, float }* // CHECK: %[[FIELD1:.+]] = getelementptr inbounds { float, float }, { float, float }* %[[VIEW1]], i32 0, i32 0 // CHECK: %[[RET1:.+]] = load float, float* %[[FIELD1]] @@ -17,7 +17,7 @@ float get_real() // CHECK-LABEL: get_imag float get_imag() { - // CHECK: %[[RAW2:.+]] = call i8* @llvm.hyper.lookup(i8* bitcast ({ float, float }* @c to i8*)) + // CHECK: %[[RAW2:.+]] = call i8* @llvm.hyper.lookup.i64(i8* bitcast ({ float, float }* @c to i8*), i64 8, i8* null, i8* null) // CHECK: %[[VIEW2:.+]] = bitcast i8* %[[RAW2]] to { float, float }* // CHECK: %[[FIELD2:.+]] = getelementptr inbounds { float, float }, { float, float }* %[[VIEW2]], i32 0, i32 1 // CHECK: load float, float* %[[FIELD2]] @@ -29,7 +29,7 @@ float get_imag() float get_abs() { // Only one call to llvm.hyper.lookup. - // CHECK: @llvm.hyper.lookup(i8* bitcast ({ float, float }* @c to i8*)) + // CHECK: @llvm.hyper.lookup.i64(i8* bitcast ({ float, float }* @c to i8*), i64 8, i8* null, i8* null) // CHECK-NOT: @llvm.hyper.lookup // CHECK: call float @cabsf // CHECK: ret float diff --git a/clang/test/Cilk/hyper-copy.c b/clang/test/Cilk/hyper-copy.c index c960173c5f4e..a34482b7103b 100644 --- a/clang/test/Cilk/hyper-copy.c +++ b/clang/test/Cilk/hyper-copy.c @@ -9,9 +9,9 @@ extern struct S b __attribute__((aligned(8))); // CHECK-LABEL: scopy void scopy() { - // CHECK: call i8* @llvm.hyper.lookup(i8* bitcast (%struct.S* @a to i8*)) + // CHECK: call i8* @llvm.hyper.lookup.i64(i8* bitcast (%struct.S* @a to i8*), i64 8, i8* null, i8* null) // CHECK: call void @llvm.memcpy.p0i8.p0i8.i64(i8* align 8 bitcast (%struct.S* @b to i8*) - // CHECK: call i8* @llvm.hyper.lookup(i8* bitcast (%struct.S* @a to i8*)) + // CHECK: call i8* @llvm.hyper.lookup.i64(i8* bitcast (%struct.S* @a to i8*), i64 8, i8* null, i8* null) // CHECK: call void @llvm.memcpy.p0i8.p0i8.i64 // CHECK: ret void b = a; diff --git a/clang/test/Cilk/hyper-template.cpp b/clang/test/Cilk/hyper-template.cpp index 0a3ad8a428e6..f6f1d7998c2b 100644 --- a/clang/test/Cilk/hyper-template.cpp +++ b/clang/test/Cilk/hyper-template.cpp @@ -5,7 +5,7 @@ template struct S { T member; }; S _Hyperobject S_long; // CHECK-LABEL: @_Z1fv -// CHECK: %0 = call i8* @llvm.hyper.lookup(i8* bitcast (%struct.S* @S_long to i8*)) +// CHECK: %0 = call i8* @llvm.hyper.lookup.i64(i8* bitcast (%struct.S* @S_long to i8*), i64 8, i8* null, i8* null) // CHECK-NOT: call i8* @llvm.hyper.lookup // CHECK: getelementptr // CHECK: %[[RET:.+]] = load i64 diff --git a/clang/test/Cilk/hyper-unary.c b/clang/test/Cilk/hyper-unary.c index 6b68a2d77b94..5bc123a26d65 100644 --- a/clang/test/Cilk/hyper-unary.c +++ b/clang/test/Cilk/hyper-unary.c @@ -11,10 +11,10 @@ void function1() { // CHECK: store i32 1, i32* %[[Y:.+]], int _Hyperobject y = 1; - // CHECK: call i8* @llvm.hyper.lookup(i8* bitcast (i32* @x to i8*)) + // CHECK: call i8* @llvm.hyper.lookup.i64(i8* bitcast (i32* @x to i8*), i64 4, i8* null, i8* null) // CHECK: load i32 // CHECK: %[[Y1:.+]] = bitcast i32* %[[Y]] to i8* - // CHECK: call i8* @llvm.hyper.lookup(i8* %[[Y1]]) + // CHECK: call i8* @llvm.hyper.lookup.i64(i8* %[[Y1]], i64 4, i8* null, i8* null) // CHECK: load i32 (void)x; (void)y; } @@ -24,10 +24,10 @@ void function2() { // CHECK: store i32 1, i32* %[[Y:.+]], int _Hyperobject y = 1; - // CHECK: call i8* @llvm.hyper.lookup(i8* bitcast (i32* @x to i8*)) + // CHECK: call i8* @llvm.hyper.lookup.i64(i8* bitcast (i32* @x to i8*), i64 4, i8* null, i8* null) // CHECK: load i32 // CHECK: %[[Y2:.+]] = bitcast i32* %[[Y]] to i8* - // CHECK: call i8* @llvm.hyper.lookup(i8* %[[Y2]]) + // CHECK: call i8* @llvm.hyper.lookup.i64(i8* %[[Y2]], i64 4, i8* null, i8* null) // CHECK: load i32 (void)!x; (void)!y; } @@ -37,21 +37,21 @@ void function3() { // CHECK: store i32 1, i32* %[[Y:.+]], int _Hyperobject y = 1; - // CHECK: call i8* @llvm.hyper.lookup(i8* bitcast (i32* @x to i8*)) + // CHECK: call i8* @llvm.hyper.lookup.i64(i8* bitcast (i32* @x to i8*), i64 4, i8* null, i8* null) // CHECK: load i32 // CHECK: %[[Y3:.+]] = bitcast i32* %[[Y]] to i8* - // CHECK: call i8* @llvm.hyper.lookup(i8* %[[Y3]]) + // CHECK: call i8* @llvm.hyper.lookup.i64(i8* %[[Y3]], i64 4, i8* null, i8* null) // CHECK: load i32 (void)-x; (void)-y; - // CHECK: call i8* @llvm.hyper.lookup(i8* bitcast (i32* @x to i8*)) + // CHECK: call i8* @llvm.hyper.lookup.i64(i8* bitcast (i32* @x to i8*), i64 4, i8* null, i8* null) // CHECK: load i32 // CHECK: %[[Y4:.+]] = bitcast i32* %[[Y]] to i8* - // CHECK: call i8* @llvm.hyper.lookup(i8* %[[Y4]]) + // CHECK: call i8* @llvm.hyper.lookup.i64(i8* %[[Y4]], i64 4, i8* null, i8* null) // CHECK: load i32 (void)~x; (void)~y; // CHECK: %[[XP:.+]] = load i32*, i32** @xp // CHECK: %[[XP1:.+]] = bitcast i32* %[[XP]] to i8* - // CHECK: call i8* @llvm.hyper.lookup(i8* %[[XP1]]) + // CHECK: call i8* @llvm.hyper.lookup.i64(i8* %[[XP1]], i64 4, i8* null, i8* null) // CHECK: load i32 (void)*xp; } diff --git a/llvm/lib/Analysis/BasicAliasAnalysis.cpp b/llvm/lib/Analysis/BasicAliasAnalysis.cpp index 37fb3873f3ac..9c2e1874f71b 100644 --- a/llvm/lib/Analysis/BasicAliasAnalysis.cpp +++ b/llvm/lib/Analysis/BasicAliasAnalysis.cpp @@ -1662,7 +1662,7 @@ static const Value *getRecognizedArgument(const Value *V, bool InSameSpindle, if (!C) return nullptr; unsigned NumOperands = C->getNumOperands(); - if (NumOperands != 2) + if (NumOperands != 2 && NumOperands != 5) return nullptr; for (auto E : TapirFnAttrTable) { if (C->hasFnAttr(E.first)) diff --git a/llvm/test/Transforms/Tapir/157.ll b/llvm/test/Transforms/Tapir/157.ll index 46466842f8b5..150107efd3df 100644 --- a/llvm/test/Transforms/Tapir/157.ll +++ b/llvm/test/Transforms/Tapir/157.ll @@ -34,7 +34,7 @@ pfor.cond: ; preds = %pfor.inc, %pfor.ph pfor.body: ; preds = %pfor.cond %2 = load i64, i64* %add.ptr, align 8, !tbaa !4 %3 = bitcast i64* %sum to i8* - %4 = call i8* @llvm.hyper.lookup(i8* nonnull %3) + %4 = call i8* @llvm.hyper.lookup(i8* nonnull %3, i64 8, i8* bitcast (void (i8*)* @zero to i8*), i8* bitcast (void (i8*, i8*)* @plus to i8*)) %5 = bitcast i8* %4 to i64* %6 = load i64, i64* %5, align 8, !tbaa !4 %add = add nsw i64 %6, %2 @@ -51,7 +51,7 @@ pfor.cond.cleanup: ; preds = %pfor.inc pfor.end: ; preds = %entry, %pfor.cond.cleanup %7 = bitcast i64* %sum to i8* - %8 = call i8* @llvm.hyper.lookup(i8* nonnull %7) + %8 = call i8* @llvm.hyper.lookup(i8* nonnull %7, i64 8, i8* bitcast (void (i8*)* @zero to i8*), i8* bitcast (void (i8*, i8*)* @plus to i8*)) %9 = bitcast i8* %8 to i64* %10 = load i64, i64* %9, align 8, !tbaa !4 %11 = bitcast i64* %sum to i8* @@ -91,7 +91,7 @@ declare void @llvm.reducer.register.i64(i8*, i64, i8*, i8*) #2 declare token @llvm.syncregion.start() #3 ; Function Attrs: hyper_view inaccessiblememonly injective mustprogress nofree nounwind readonly strand_pure willreturn -declare i8* @llvm.hyper.lookup(i8*) #4 +declare i8* @llvm.hyper.lookup(i8*, i64, i8*, i8*) #4 ; Function Attrs: argmemonly mustprogress nofree nosync nounwind willreturn declare void @llvm.lifetime.end.p0i8(i64 immarg, i8* nocapture) #1 From a6a4706054574eca7139ddede44286f1dbcacb17 Mon Sep 17 00:00:00 2001 From: TB Schardl Date: Sun, 29 Jan 2023 20:21:12 +0000 Subject: [PATCH 4/6] [CilkSanitizer] Special-case the instrumentation of hyper.lookup, to allow Cilksan library to implement its own handling of reducers separately from runtime system. --- .../Instrumentation/CilkSanitizer.cpp | 18 ++++++++++++++++++ 1 file changed, 18 insertions(+) diff --git a/llvm/lib/Transforms/Instrumentation/CilkSanitizer.cpp b/llvm/lib/Transforms/Instrumentation/CilkSanitizer.cpp index c063859cea71..9d3b3838339b 100644 --- a/llvm/lib/Transforms/Instrumentation/CilkSanitizer.cpp +++ b/llvm/lib/Transforms/Instrumentation/CilkSanitizer.cpp @@ -3867,6 +3867,24 @@ bool CilkSanitizerImpl::instrumentIntrinsicCall( AfterHookParamTys.push_back(ArgSpill->getType()); AfterHookParamVals.push_back(ArgSpill); } + + // Special-case intrinsics. + IntrinsicInst *II = dyn_cast(I); + switch (II->getIntrinsicID()) { + case Intrinsic::hyper_lookup: { + FunctionType *AfterHookTy = + FunctionType::get(IRB.getInt8PtrTy(), AfterHookParamTys, Called->isVarArg()); + FunctionCallee AfterIntrinCallHook = + getOrInsertSynthesizedHook(("__csan_" + Buf).str(), AfterHookTy, FnAttrs); + CallInst *HookCall = + insertHookCall(&*Iter, AfterIntrinCallHook, AfterHookParamVals); + II->replaceUsesWithIf(HookCall, [HookCall](Use &U) { + return cast(U.getUser()) != HookCall; + }); + return true; + } + } + FunctionType *AfterHookTy = FunctionType::get(IRB.getVoidTy(), AfterHookParamTys, Called->isVarArg()); FunctionCallee AfterIntrinCallHook = From 7b6557d030a9dab0f4b7bca6dd0b77c95659ca1e Mon Sep 17 00:00:00 2001 From: TB Schardl Date: Thu, 30 Mar 2023 19:10:44 +0000 Subject: [PATCH 5/6] [test/Tapir] Mark test that requires the X86 target as such. --- llvm/test/Transforms/Tapir/157.ll | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/llvm/test/Transforms/Tapir/157.ll b/llvm/test/Transforms/Tapir/157.ll index 150107efd3df..09b1def9ff2a 100644 --- a/llvm/test/Transforms/Tapir/157.ll +++ b/llvm/test/Transforms/Tapir/157.ll @@ -1,5 +1,6 @@ ; Check that loops with reducers can be vectorized (OpenCilk issue 157). -; RUN: opt -S < %s -passes='loop-mssa(tapir-indvars),loop-stripmine,loop-mssa(loop-simplifycfg,licm),loop-vectorize' -o - | FileCheck %s +; RUN: opt -S < %s -passes='loop-mssa(tapir-indvars),loop-stripmine,loop-mssa(loop-simplifycfg,licm),loop-vectorize' | FileCheck %s +; REQUIRES: x86-registered-target target datalayout = "e-m:e-p270:32:32-p271:32:32-p272:64:64-i64:64-f80:128-n8:16:32:64-S128" target triple = "x86_64-unknown-freebsd13.1" From 5c01343bbb1fc9a7b958effc433f9fb80b22279d Mon Sep 17 00:00:00 2001 From: "Tao B. Schardl" Date: Thu, 6 Apr 2023 05:59:35 -0400 Subject: [PATCH 6/6] Fix workaround in llvm-project-tests.yml for new macOS runner image. --- .github/workflows/llvm-project-tests.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.github/workflows/llvm-project-tests.yml b/.github/workflows/llvm-project-tests.yml index 8ebca9d69bce..e33482f4b917 100644 --- a/.github/workflows/llvm-project-tests.yml +++ b/.github/workflows/llvm-project-tests.yml @@ -28,7 +28,7 @@ concurrency: env: # Workaround for https://github.com/actions/virtual-environments/issues/5900. # This should be a no-op for non-mac OSes - CPLUS_INCLUDE_PATH: /usr/local/Cellar/llvm/15.0.7_1/include/c++/v1:/Library/Developer/CommandLineTools/SDKs/MacOSX12.1.sdk/usr/include + CPLUS_INCLUDE_PATH: /usr/local/Cellar/llvm@15/15.0.7/include/c++/v1:/usr/local/Cellar/llvm/15.0.7_1/include/c++/v1:/Library/Developer/CommandLineTools/SDKs/MacOSX12.1.sdk/usr/include jobs: lit-tests: