@@ -43,8 +43,8 @@ namespace mlir {
43
43
static LLVM::LLVMFuncOp lookupOrCreateSPIRVFn (Operation *symbolTable,
44
44
StringRef name,
45
45
ArrayRef<Type> paramTypes,
46
- Type resultType,
47
- bool isConvergent = false ) {
46
+ Type resultType, bool isMemNone,
47
+ bool isConvergent) {
48
48
auto func = dyn_cast_or_null<LLVM::LLVMFuncOp>(
49
49
SymbolTable::lookupSymbolIn (symbolTable, name));
50
50
if (!func) {
@@ -53,6 +53,18 @@ static LLVM::LLVMFuncOp lookupOrCreateSPIRVFn(Operation *symbolTable,
53
53
symbolTable->getLoc (), name,
54
54
LLVM::LLVMFunctionType::get (resultType, paramTypes));
55
55
func.setCConv (LLVM::cconv::CConv::SPIR_FUNC);
56
+ func.setNoUnwind (true );
57
+ func.setWillReturn (true );
58
+
59
+ if (isMemNone) {
60
+ // no externally observable effects
61
+ constexpr auto noModRef = mlir::LLVM::ModRefInfo::NoModRef;
62
+ auto memAttr = b.getAttr <LLVM::MemoryEffectsAttr>(
63
+ /* other=*/ noModRef,
64
+ /* argMem=*/ noModRef, /* inaccessibleMem=*/ noModRef);
65
+ func.setMemoryEffectsAttr (memAttr);
66
+ }
67
+
56
68
func.setConvergent (isConvergent);
57
69
}
58
70
return func;
@@ -64,6 +76,10 @@ static LLVM::CallOp createSPIRVBuiltinCall(Location loc,
64
76
ValueRange args) {
65
77
auto call = rewriter.create <LLVM::CallOp>(loc, func, args);
66
78
call.setCConv (func.getCConv ());
79
+ call.setConvergentAttr (func.getConvergentAttr ());
80
+ call.setNoUnwindAttr (func.getNoUnwindAttr ());
81
+ call.setWillReturnAttr (func.getWillReturnAttr ());
82
+ call.setMemoryEffectsAttr (func.getMemoryEffectsAttr ());
67
83
return call;
68
84
}
69
85
@@ -91,8 +107,9 @@ struct GPUBarrierConversion final : ConvertOpToLLVMPattern<gpu::BarrierOp> {
91
107
assert (moduleOp && " Expecting module" );
92
108
Type flagTy = rewriter.getI32Type ();
93
109
Type voidTy = rewriter.getType <LLVM::LLVMVoidType>();
94
- LLVM::LLVMFuncOp func = lookupOrCreateSPIRVFn (
95
- moduleOp, funcName, flagTy, voidTy, /* isConvergent=*/ true );
110
+ LLVM::LLVMFuncOp func =
111
+ lookupOrCreateSPIRVFn (moduleOp, funcName, flagTy, voidTy,
112
+ /* isMemNone=*/ false , /* isConvergent=*/ true );
96
113
97
114
// Value used by SPIR-V backend to represent `CLK_LOCAL_MEM_FENCE`.
98
115
// See `llvm/lib/Target/SPIRV/SPIRVBuiltins.td`.
@@ -134,8 +151,9 @@ struct LaunchConfigConversion : ConvertToLLVMPattern {
134
151
assert (moduleOp && " Expecting module" );
135
152
Type dimTy = rewriter.getI32Type ();
136
153
Type indexTy = getTypeConverter ()->getIndexType ();
137
- LLVM::LLVMFuncOp func =
138
- lookupOrCreateSPIRVFn (moduleOp, funcName, dimTy, indexTy);
154
+ LLVM::LLVMFuncOp func = lookupOrCreateSPIRVFn (moduleOp, funcName, dimTy,
155
+ indexTy, /* isMemNone=*/ true ,
156
+ /* isConvergent=*/ false );
139
157
140
158
Location loc = op->getLoc ();
141
159
gpu::Dimension dim = getDimension (op);
@@ -268,9 +286,9 @@ struct GPUShuffleConversion final : ConvertOpToLLVMPattern<gpu::ShuffleOp> {
268
286
Type valueType = adaptor.getValue ().getType ();
269
287
Type offsetType = adaptor.getOffset ().getType ();
270
288
Type resultType = valueType;
271
- LLVM::LLVMFuncOp func =
272
- lookupOrCreateSPIRVFn ( moduleOp, funcName, {valueType, offsetType},
273
- resultType , /* isConvergent=*/ true );
289
+ LLVM::LLVMFuncOp func = lookupOrCreateSPIRVFn (
290
+ moduleOp, funcName, {valueType, offsetType}, resultType ,
291
+ /* isMemNone= */ false , /* isConvergent=*/ true );
274
292
275
293
Location loc = op->getLoc ();
276
294
std::array<Value, 2 > args{adaptor.getValue (), adaptor.getOffset ()};
0 commit comments