|
24 | 24 | #include "llvm/CodeGen/IntrinsicLowering.h" |
25 | 25 | #include "llvm/IR/IRBuilder.h" |
26 | 26 | #include "llvm/IR/IntrinsicInst.h" |
| 27 | +#include "llvm/IR/Intrinsics.h" |
| 28 | +#include "llvm/IR/IntrinsicsSPIRV.h" |
27 | 29 | #include "llvm/Transforms/Utils/Cloning.h" |
28 | 30 | #include "llvm/Transforms/Utils/LowerMemIntrinsics.h" |
29 | 31 |
|
@@ -233,6 +235,32 @@ static void buildUMulWithOverflowFunc(Function *UMulFunc) { |
233 | 235 | IRB.CreateRet(Res); |
234 | 236 | } |
235 | 237 |
|
| 238 | +static void lowerExpectAssume(IntrinsicInst *II) { |
| 239 | + // If we cannot use the SPV_KHR_expect_assume extension, then we need to |
| 240 | + // ignore the intrinsic and move on. It should be removed later on by LLVM. |
| 241 | + // Otherwise we should lower the intrinsic to the corresponding SPIR-V |
| 242 | + // instruction. |
| 243 | + // For @llvm.assume we have OpAssumeTrueKHR. |
| 244 | + // For @llvm.expect we have OpExpectKHR. |
| 245 | + // |
| 246 | + // We need to lower this into a builtin and then the builtin into a SPIR-V |
| 247 | + // instruction. |
| 248 | + if (II->getIntrinsicID() == Intrinsic::assume) { |
| 249 | + Function *F = Intrinsic::getDeclaration( |
| 250 | + II->getModule(), Intrinsic::SPVIntrinsics::spv_assume); |
| 251 | + II->setCalledFunction(F); |
| 252 | + } else if (II->getIntrinsicID() == Intrinsic::expect) { |
| 253 | + Function *F = Intrinsic::getDeclaration( |
| 254 | + II->getModule(), Intrinsic::SPVIntrinsics::spv_expect, |
| 255 | + {II->getOperand(0)->getType()}); |
| 256 | + II->setCalledFunction(F); |
| 257 | + } else { |
| 258 | + llvm_unreachable("Unknown intrinsic"); |
| 259 | + } |
| 260 | + |
| 261 | + return; |
| 262 | +} |
| 263 | + |
236 | 264 | static void lowerUMulWithOverflow(IntrinsicInst *UMulIntrinsic) { |
237 | 265 | // Get a separate function - otherwise, we'd have to rework the CFG of the |
238 | 266 | // current one. Then simply replace the intrinsic uses with a call to the new |
@@ -270,6 +298,10 @@ bool SPIRVPrepareFunctions::substituteIntrinsicCalls(Function *F) { |
270 | 298 | } else if (II->getIntrinsicID() == Intrinsic::umul_with_overflow) { |
271 | 299 | lowerUMulWithOverflow(II); |
272 | 300 | Changed = true; |
| 301 | + } else if (II->getIntrinsicID() == Intrinsic::assume || |
| 302 | + II->getIntrinsicID() == Intrinsic::expect) { |
| 303 | + lowerExpectAssume(II); |
| 304 | + Changed = true; |
273 | 305 | } |
274 | 306 | } |
275 | 307 | } |
|
0 commit comments