Skip to content

Commit 2a1f1b5

Browse files
authored
[OpenMP][OpenMPIRBuilder] Move copyInput to a passed in lambda function and re-order kernel argument load/stores (#68124)
This patch moves the existing copyInput function into a lambda argument that can be defined by a caller to the function. This allows more flexibility in how the function is defined, allowing Clang and MLIR to utilise their own respective functions and types inside of the lamba without affecting the OMPIRBuilder itself. The idea is to eventually replace/build on the existing copyInput function that's used and moved into OpenMPToLLVMIRTranslation.cpp to a slightly more complex implementation that uses MLIRs map information (primarily ByRef and ByCapture information at the moment). The patch also moves kernel load stores to the top of the kernel, prior to the first openmp runtime invocation. Just makes the IR a little closer to Clang.
1 parent 21030b9 commit 2a1f1b5

File tree

5 files changed

+163
-64
lines changed

5 files changed

+163
-64
lines changed

llvm/include/llvm/Frontend/OpenMP/OMPIRBuilder.h

Lines changed: 8 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -2166,6 +2166,10 @@ class OpenMPIRBuilder {
21662166
using TargetBodyGenCallbackTy = function_ref<InsertPointTy(
21672167
InsertPointTy AllocaIP, InsertPointTy CodeGenIP)>;
21682168

2169+
using TargetGenArgAccessorsCallbackTy = function_ref<InsertPointTy(
2170+
Argument &Arg, Value *Input, Value *&RetVal, InsertPointTy AllocaIP,
2171+
InsertPointTy CodeGenIP)>;
2172+
21692173
/// Generator for '#omp target'
21702174
///
21712175
/// \param Loc where the target data construct was encountered.
@@ -2177,14 +2181,17 @@ class OpenMPIRBuilder {
21772181
/// \param Inputs The input values to the region that will be passed.
21782182
/// as arguments to the outlined function.
21792183
/// \param BodyGenCB Callback that will generate the region code.
2184+
/// \param ArgAccessorFuncCB Callback that will generate accessors
2185+
/// instructions for passed in target arguments where neccessary
21802186
InsertPointTy createTarget(const LocationDescription &Loc,
21812187
OpenMPIRBuilder::InsertPointTy AllocaIP,
21822188
OpenMPIRBuilder::InsertPointTy CodeGenIP,
21832189
TargetRegionEntryInfo &EntryInfo, int32_t NumTeams,
21842190
int32_t NumThreads,
21852191
SmallVectorImpl<Value *> &Inputs,
21862192
GenMapInfoCallbackTy GenMapInfoCB,
2187-
TargetBodyGenCallbackTy BodyGenCB);
2193+
TargetBodyGenCallbackTy BodyGenCB,
2194+
TargetGenArgAccessorsCallbackTy ArgAccessorFuncCB);
21882195

21892196
/// Returns __kmpc_for_static_init_* runtime function for the specified
21902197
/// size \a IVSize and sign \a IVSigned. Will create a distribute call

llvm/lib/Frontend/OpenMP/OMPIRBuilder.cpp

Lines changed: 29 additions & 37 deletions
Original file line numberDiff line numberDiff line change
@@ -4539,25 +4539,11 @@ FunctionCallee OpenMPIRBuilder::createDispatchFiniFunction(unsigned IVSize,
45394539
return getOrCreateRuntimeFunction(M, Name);
45404540
}
45414541

4542-
// Copy input from pointer or i64 to the expected argument type.
4543-
static Value *copyInput(IRBuilderBase &Builder, unsigned AddrSpace,
4544-
Value *Input, Argument &Arg) {
4545-
auto Addr = Builder.CreateAlloca(Arg.getType()->isPointerTy()
4546-
? Arg.getType()
4547-
: Type::getInt64Ty(Builder.getContext()),
4548-
AddrSpace);
4549-
auto AddrAscast =
4550-
Builder.CreatePointerBitCastOrAddrSpaceCast(Addr, Input->getType());
4551-
Builder.CreateStore(&Arg, AddrAscast);
4552-
auto Copy = Builder.CreateLoad(Arg.getType(), AddrAscast);
4553-
4554-
return Copy;
4555-
}
4556-
4557-
static Function *
4558-
createOutlinedFunction(OpenMPIRBuilder &OMPBuilder, IRBuilderBase &Builder,
4559-
StringRef FuncName, SmallVectorImpl<Value *> &Inputs,
4560-
OpenMPIRBuilder::TargetBodyGenCallbackTy &CBFunc) {
4542+
static Function *createOutlinedFunction(
4543+
OpenMPIRBuilder &OMPBuilder, IRBuilderBase &Builder, StringRef FuncName,
4544+
SmallVectorImpl<Value *> &Inputs,
4545+
OpenMPIRBuilder::TargetBodyGenCallbackTy &CBFunc,
4546+
OpenMPIRBuilder::TargetGenArgAccessorsCallbackTy &ArgAccessorFuncCB) {
45614547
SmallVector<Type *> ParameterTypes;
45624548
if (OMPBuilder.Config.isTargetDevice()) {
45634549
// All parameters to target devices are passed as pointers
@@ -4597,18 +4583,20 @@ createOutlinedFunction(OpenMPIRBuilder &OMPBuilder, IRBuilderBase &Builder,
45974583
// Insert return instruction.
45984584
Builder.CreateRetVoid();
45994585

4600-
// Rewrite uses of input valus to parameters.
4586+
// New Alloca IP at entry point of created device function.
4587+
Builder.SetInsertPoint(EntryBB->getFirstNonPHI());
4588+
auto AllocaIP = Builder.saveIP();
4589+
46014590
Builder.SetInsertPoint(UserCodeEntryBB->getFirstNonPHIOrDbg());
4591+
4592+
// Rewrite uses of input valus to parameters.
46024593
for (auto InArg : zip(Inputs, Func->args())) {
46034594
Value *Input = std::get<0>(InArg);
46044595
Argument &Arg = std::get<1>(InArg);
4596+
Value *InputCopy = nullptr;
46054597

4606-
Value *InputCopy =
4607-
OMPBuilder.Config.isTargetDevice()
4608-
? copyInput(Builder,
4609-
OMPBuilder.M.getDataLayout().getAllocaAddrSpace(),
4610-
Input, Arg)
4611-
: &Arg;
4598+
Builder.restoreIP(
4599+
ArgAccessorFuncCB(Arg, Input, InputCopy, AllocaIP, Builder.saveIP()));
46124600

46134601
// Collect all the instructions
46144602
for (User *User : make_early_inc_range(Input->users()))
@@ -4623,18 +4611,19 @@ createOutlinedFunction(OpenMPIRBuilder &OMPBuilder, IRBuilderBase &Builder,
46234611
return Func;
46244612
}
46254613

4626-
static void
4627-
emitTargetOutlinedFunction(OpenMPIRBuilder &OMPBuilder, IRBuilderBase &Builder,
4628-
TargetRegionEntryInfo &EntryInfo,
4629-
Function *&OutlinedFn, Constant *&OutlinedFnID,
4630-
int32_t NumTeams, int32_t NumThreads,
4631-
SmallVectorImpl<Value *> &Inputs,
4632-
OpenMPIRBuilder::TargetBodyGenCallbackTy &CBFunc) {
4614+
static void emitTargetOutlinedFunction(
4615+
OpenMPIRBuilder &OMPBuilder, IRBuilderBase &Builder,
4616+
TargetRegionEntryInfo &EntryInfo, Function *&OutlinedFn,
4617+
Constant *&OutlinedFnID, int32_t NumTeams, int32_t NumThreads,
4618+
SmallVectorImpl<Value *> &Inputs,
4619+
OpenMPIRBuilder::TargetBodyGenCallbackTy &CBFunc,
4620+
OpenMPIRBuilder::TargetGenArgAccessorsCallbackTy &ArgAccessorFuncCB) {
46334621

46344622
OpenMPIRBuilder::FunctionGenCallback &&GenerateOutlinedFunction =
4635-
[&OMPBuilder, &Builder, &Inputs, &CBFunc](StringRef EntryFnName) {
4623+
[&OMPBuilder, &Builder, &Inputs, &CBFunc,
4624+
&ArgAccessorFuncCB](StringRef EntryFnName) {
46364625
return createOutlinedFunction(OMPBuilder, Builder, EntryFnName, Inputs,
4637-
CBFunc);
4626+
CBFunc, ArgAccessorFuncCB);
46384627
};
46394628

46404629
OMPBuilder.emitTargetRegionFunction(EntryInfo, GenerateOutlinedFunction,
@@ -4698,7 +4687,9 @@ OpenMPIRBuilder::InsertPointTy OpenMPIRBuilder::createTarget(
46984687
const LocationDescription &Loc, InsertPointTy AllocaIP,
46994688
InsertPointTy CodeGenIP, TargetRegionEntryInfo &EntryInfo, int32_t NumTeams,
47004689
int32_t NumThreads, SmallVectorImpl<Value *> &Args,
4701-
GenMapInfoCallbackTy GenMapInfoCB, TargetBodyGenCallbackTy CBFunc) {
4690+
GenMapInfoCallbackTy GenMapInfoCB,
4691+
OpenMPIRBuilder::TargetBodyGenCallbackTy CBFunc,
4692+
OpenMPIRBuilder::TargetGenArgAccessorsCallbackTy ArgAccessorFuncCB) {
47024693
if (!updateToLocation(Loc))
47034694
return InsertPointTy();
47044695

@@ -4707,7 +4698,8 @@ OpenMPIRBuilder::InsertPointTy OpenMPIRBuilder::createTarget(
47074698
Function *OutlinedFn;
47084699
Constant *OutlinedFnID;
47094700
emitTargetOutlinedFunction(*this, Builder, EntryInfo, OutlinedFn,
4710-
OutlinedFnID, NumTeams, NumThreads, Args, CBFunc);
4701+
OutlinedFnID, NumTeams, NumThreads, Args, CBFunc,
4702+
ArgAccessorFuncCB);
47114703
if (!Config.isTargetDevice())
47124704
emitTargetCall(*this, Builder, AllocaIP, OutlinedFn, OutlinedFnID, NumTeams,
47134705
NumThreads, Args, GenMapInfoCB);

llvm/unittests/Frontend/OpenMPIRBuilderTest.cpp

Lines changed: 74 additions & 19 deletions
Original file line numberDiff line numberDiff line change
@@ -5236,6 +5236,33 @@ TEST_F(OpenMPIRBuilderTest, TargetRegion) {
52365236
Inputs.push_back(BPtr);
52375237
Inputs.push_back(CPtr);
52385238

5239+
auto SimpleArgAccessorCB =
5240+
[&](llvm::Argument &Arg, llvm::Value *Input, llvm::Value *&RetVal,
5241+
llvm::OpenMPIRBuilder::InsertPointTy AllocaIP,
5242+
llvm::OpenMPIRBuilder::InsertPointTy CodeGenIP) {
5243+
if (!OMPBuilder.Config.isTargetDevice()) {
5244+
RetVal = cast<llvm::Value>(&Arg);
5245+
return CodeGenIP;
5246+
}
5247+
5248+
Builder.restoreIP(AllocaIP);
5249+
5250+
llvm::Value *Addr = Builder.CreateAlloca(
5251+
Arg.getType()->isPointerTy()
5252+
? Arg.getType()
5253+
: Type::getInt64Ty(Builder.getContext()),
5254+
OMPBuilder.M.getDataLayout().getAllocaAddrSpace());
5255+
llvm::Value *AddrAscast =
5256+
Builder.CreatePointerBitCastOrAddrSpaceCast(Addr, Input->getType());
5257+
Builder.CreateStore(&Arg, AddrAscast);
5258+
5259+
Builder.restoreIP(CodeGenIP);
5260+
5261+
RetVal = Builder.CreateLoad(Arg.getType(), AddrAscast);
5262+
5263+
return Builder.saveIP();
5264+
};
5265+
52395266
llvm::OpenMPIRBuilder::MapInfosTy CombinedInfos;
52405267
auto GenMapInfoCB = [&](llvm::OpenMPIRBuilder::InsertPointTy codeGenIP)
52415268
-> llvm::OpenMPIRBuilder::MapInfosTy & {
@@ -5245,9 +5272,9 @@ TEST_F(OpenMPIRBuilderTest, TargetRegion) {
52455272

52465273
TargetRegionEntryInfo EntryInfo("func", 42, 4711, 17);
52475274
OpenMPIRBuilder::LocationDescription OmpLoc({Builder.saveIP(), DL});
5248-
Builder.restoreIP(OMPBuilder.createTarget(OmpLoc, Builder.saveIP(),
5249-
Builder.saveIP(), EntryInfo, -1, 0,
5250-
Inputs, GenMapInfoCB, BodyGenCB));
5275+
Builder.restoreIP(OMPBuilder.createTarget(
5276+
OmpLoc, Builder.saveIP(), Builder.saveIP(), EntryInfo, -1, 0, Inputs,
5277+
GenMapInfoCB, BodyGenCB, SimpleArgAccessorCB));
52515278
OMPBuilder.finalize();
52525279
Builder.CreateRetVoid();
52535280

@@ -5301,6 +5328,33 @@ TEST_F(OpenMPIRBuilderTest, TargetRegionDevice) {
53015328
Constant::getNullValue(PointerType::get(Ctx, 0)),
53025329
Constant::getNullValue(PointerType::get(Ctx, 0))};
53035330

5331+
auto SimpleArgAccessorCB =
5332+
[&](llvm::Argument &Arg, llvm::Value *Input, llvm::Value *&RetVal,
5333+
llvm::OpenMPIRBuilder::InsertPointTy AllocaIP,
5334+
llvm::OpenMPIRBuilder::InsertPointTy CodeGenIP) {
5335+
if (!OMPBuilder.Config.isTargetDevice()) {
5336+
RetVal = cast<llvm::Value>(&Arg);
5337+
return CodeGenIP;
5338+
}
5339+
5340+
Builder.restoreIP(AllocaIP);
5341+
5342+
llvm::Value *Addr = Builder.CreateAlloca(
5343+
Arg.getType()->isPointerTy()
5344+
? Arg.getType()
5345+
: Type::getInt64Ty(Builder.getContext()),
5346+
OMPBuilder.M.getDataLayout().getAllocaAddrSpace());
5347+
llvm::Value *AddrAscast =
5348+
Builder.CreatePointerBitCastOrAddrSpaceCast(Addr, Input->getType());
5349+
Builder.CreateStore(&Arg, AddrAscast);
5350+
5351+
Builder.restoreIP(CodeGenIP);
5352+
5353+
RetVal = Builder.CreateLoad(Arg.getType(), AddrAscast);
5354+
5355+
return Builder.saveIP();
5356+
};
5357+
53045358
llvm::OpenMPIRBuilder::MapInfosTy CombinedInfos;
53055359
auto GenMapInfoCB = [&](llvm::OpenMPIRBuilder::InsertPointTy codeGenIP)
53065360
-> llvm::OpenMPIRBuilder::MapInfosTy & {
@@ -5322,9 +5376,10 @@ TEST_F(OpenMPIRBuilderTest, TargetRegionDevice) {
53225376
TargetRegionEntryInfo EntryInfo("parent", /*DeviceID=*/1, /*FileID=*/2,
53235377
/*Line=*/3, /*Count=*/0);
53245378

5325-
Builder.restoreIP(OMPBuilder.createTarget(
5326-
Loc, EntryIP, EntryIP, EntryInfo, /*NumTeams=*/-1,
5327-
/*NumThreads=*/0, CapturedArgs, GenMapInfoCB, BodyGenCB));
5379+
Builder.restoreIP(
5380+
OMPBuilder.createTarget(Loc, EntryIP, EntryIP, EntryInfo, /*NumTeams=*/-1,
5381+
/*NumThreads=*/0, CapturedArgs, GenMapInfoCB,
5382+
BodyGenCB, SimpleArgAccessorCB));
53285383

53295384
Builder.CreateRetVoid();
53305385
OMPBuilder.finalize();
@@ -5343,10 +5398,18 @@ TEST_F(OpenMPIRBuilderTest, TargetRegionDevice) {
53435398

53445399
// Check entry block
53455400
auto &EntryBlock = OutlinedFn->getEntryBlock();
5346-
Instruction *Init = EntryBlock.getFirstNonPHI();
5347-
EXPECT_NE(Init, nullptr);
5401+
Instruction *Alloca1 = EntryBlock.getFirstNonPHI();
5402+
EXPECT_NE(Alloca1, nullptr);
5403+
5404+
EXPECT_TRUE(isa<AllocaInst>(Alloca1));
5405+
auto *Store1 = Alloca1->getNextNode();
5406+
EXPECT_TRUE(isa<StoreInst>(Store1));
5407+
auto *Alloca2 = Store1->getNextNode();
5408+
EXPECT_TRUE(isa<AllocaInst>(Alloca2));
5409+
auto *Store2 = Alloca2->getNextNode();
5410+
EXPECT_TRUE(isa<StoreInst>(Store2));
53485411

5349-
auto *InitCall = dyn_cast<CallInst>(Init);
5412+
auto *InitCall = dyn_cast<CallInst>(Store2->getNextNode());
53505413
EXPECT_NE(InitCall, nullptr);
53515414
EXPECT_EQ(InitCall->getCalledFunction()->getName(), "__kmpc_target_init");
53525415
EXPECT_EQ(InitCall->arg_size(), 1U);
@@ -5370,17 +5433,9 @@ TEST_F(OpenMPIRBuilderTest, TargetRegionDevice) {
53705433
// Check user code block
53715434
auto *UserCodeBlock = EntryBlockBranch->getSuccessor(0);
53725435
EXPECT_EQ(UserCodeBlock->getName(), "user_code.entry");
5373-
auto *Alloca1 = UserCodeBlock->getFirstNonPHI();
5374-
EXPECT_TRUE(isa<AllocaInst>(Alloca1));
5375-
auto *Store1 = Alloca1->getNextNode();
5376-
EXPECT_TRUE(isa<StoreInst>(Store1));
5377-
auto *Load1 = Store1->getNextNode();
5436+
auto *Load1 = UserCodeBlock->getFirstNonPHI();
53785437
EXPECT_TRUE(isa<LoadInst>(Load1));
5379-
auto *Alloca2 = Load1->getNextNode();
5380-
EXPECT_TRUE(isa<AllocaInst>(Alloca2));
5381-
auto *Store2 = Alloca2->getNextNode();
5382-
EXPECT_TRUE(isa<StoreInst>(Store2));
5383-
auto *Load2 = Store2->getNextNode();
5438+
auto *Load2 = Load1->getNextNode();
53845439
EXPECT_TRUE(isa<LoadInst>(Load2));
53855440

53865441
auto *Value1 = Load2->getNextNode();

mlir/lib/Target/LLVMIR/Dialect/OpenMP/OpenMPToLLVMIRTranslation.cpp

Lines changed: 46 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -2018,6 +2018,31 @@ handleDeclareTargetMapVar(llvm::ArrayRef<Value> mapOperands,
20182018
}
20192019
}
20202020

2021+
static llvm::IRBuilderBase::InsertPoint
2022+
createDeviceArgumentAccessor(llvm::Argument &arg, llvm::Value *input,
2023+
llvm::Value *&retVal, llvm::IRBuilderBase &builder,
2024+
llvm::OpenMPIRBuilder &ompBuilder,
2025+
LLVM::ModuleTranslation &moduleTranslation,
2026+
llvm::IRBuilderBase::InsertPoint allocaIP,
2027+
llvm::IRBuilderBase::InsertPoint codeGenIP) {
2028+
builder.restoreIP(allocaIP);
2029+
2030+
llvm::Value *addr =
2031+
builder.CreateAlloca(arg.getType()->isPointerTy()
2032+
? arg.getType()
2033+
: llvm::Type::getInt64Ty(builder.getContext()),
2034+
ompBuilder.M.getDataLayout().getAllocaAddrSpace());
2035+
llvm::Value *addrAscast =
2036+
builder.CreatePointerBitCastOrAddrSpaceCast(addr, input->getType());
2037+
builder.CreateStore(&arg, addrAscast);
2038+
2039+
builder.restoreIP(codeGenIP);
2040+
2041+
retVal = builder.CreateLoad(arg.getType(), addrAscast);
2042+
2043+
return builder.saveIP();
2044+
}
2045+
20212046
static LogicalResult
20222047
convertOmpTarget(Operation &opInst, llvm::IRBuilderBase &builder,
20232048
LLVM::ModuleTranslation &moduleTranslation) {
@@ -2109,9 +2134,29 @@ convertOmpTarget(Operation &opInst, llvm::IRBuilderBase &builder,
21092134
return combinedInfos;
21102135
};
21112136

2137+
auto argAccessorCB = [&](llvm::Argument &arg, llvm::Value *input,
2138+
llvm::Value *&retVal, InsertPointTy allocaIP,
2139+
InsertPointTy codeGenIP) {
2140+
llvm::OpenMPIRBuilder *ompBuilder = moduleTranslation.getOpenMPBuilder();
2141+
2142+
// We just return the unaltered argument for the host function
2143+
// for now, some alterations may be required in the future to
2144+
// keep host fallback functions working identically to the device
2145+
// version (e.g. pass ByCopy values should be treated as such on
2146+
// host and device, currently not always the case)
2147+
if (!ompBuilder->Config.isTargetDevice()) {
2148+
retVal = cast<llvm::Value>(&arg);
2149+
return codeGenIP;
2150+
}
2151+
2152+
return createDeviceArgumentAccessor(arg, input, retVal, builder,
2153+
*ompBuilder, moduleTranslation,
2154+
allocaIP, codeGenIP);
2155+
};
2156+
21122157
builder.restoreIP(moduleTranslation.getOpenMPBuilder()->createTarget(
21132158
ompLoc, allocaIP, builder.saveIP(), entryInfo, defaultValTeams,
2114-
defaultValThreads, inputs, genMapInfoCB, bodyCB));
2159+
defaultValThreads, inputs, genMapInfoCB, bodyCB, argAccessorCB));
21152160

21162161
// Remap access operations to declare target reference pointers for the
21172162
// device, essentially generating extra loadop's as necessary

mlir/test/Target/LLVMIR/omptarget-region-device-llvm.mlir

Lines changed: 6 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -31,18 +31,18 @@ module attributes {omp.is_target_device = true} {
3131
// CHECK: @[[DYNA_ENV:.*]] = weak_odr protected global %struct.DynamicEnvironmentTy zeroinitializer
3232
// CHECK: @[[KERNEL_ENV:.*]] = weak_odr protected constant %struct.KernelEnvironmentTy { %struct.ConfigurationEnvironmentTy { i8 1, i8 1, i8 1 }, ptr @[[IDENT]], ptr @[[DYNA_ENV]] }
3333
// CHECK: define weak_odr protected void @__omp_offloading_{{[^_]+}}_{{[^_]+}}_omp_target_region__l{{[0-9]+}}(ptr %[[ADDR_A:.*]], ptr %[[ADDR_B:.*]], ptr %[[ADDR_C:.*]])
34-
// CHECK: %[[INIT:.*]] = call i32 @__kmpc_target_init(ptr @[[KERNEL_ENV]])
35-
// CHECK-NEXT: %[[CMP:.*]] = icmp eq i32 %3, -1
36-
// CHECK-NEXT: br i1 %[[CMP]], label %[[LABEL_ENTRY:.*]], label %[[LABEL_EXIT:.*]]
37-
// CHECK: [[LABEL_ENTRY]]:
3834
// CHECK: %[[TMP_A:.*]] = alloca ptr, align 8
3935
// CHECK: store ptr %[[ADDR_A]], ptr %[[TMP_A]], align 8
40-
// CHECK: %[[PTR_A:.*]] = load ptr, ptr %[[TMP_A]], align 8
4136
// CHECK: %[[TMP_B:.*]] = alloca ptr, align 8
4237
// CHECK: store ptr %[[ADDR_B]], ptr %[[TMP_B]], align 8
43-
// CHECK: %[[PTR_B:.*]] = load ptr, ptr %[[TMP_B]], align 8
4438
// CHECK: %[[TMP_C:.*]] = alloca ptr, align 8
4539
// CHECK: store ptr %[[ADDR_C]], ptr %[[TMP_C]], align 8
40+
// CHECK: %[[INIT:.*]] = call i32 @__kmpc_target_init(ptr @[[KERNEL_ENV]])
41+
// CHECK-NEXT: %[[CMP:.*]] = icmp eq i32 %[[INIT]], -1
42+
// CHECK-NEXT: br i1 %[[CMP]], label %[[LABEL_ENTRY:.*]], label %[[LABEL_EXIT:.*]]
43+
// CHECK: [[LABEL_ENTRY]]:
44+
// CHECK: %[[PTR_A:.*]] = load ptr, ptr %[[TMP_A]], align 8
45+
// CHECK: %[[PTR_B:.*]] = load ptr, ptr %[[TMP_B]], align 8
4646
// CHECK: %[[PTR_C:.*]] = load ptr, ptr %[[TMP_C]], align 8
4747
// CHECK-NEXT: br label %[[LABEL_TARGET:.*]]
4848
// CHECK: [[LABEL_TARGET]]:

0 commit comments

Comments
 (0)