forked from OSchip/llvm-project
[ObjC] Emit selector load right before msgSend call.
We currently emit the selector load early, but only because we need it to compute the signature (so that we know which msgSend variant to call). We can prepare the signature with a plain undef, and replace it with the materialized selector value if (and only if) needed, later. Concretely, this usually doesn't have an effect, but tests need updating because we reordered the receiver bitcast and the selector load, which is always fine. There is one notable change: with this, when a msgSend needs a receiver null check, the selector is now loaded in the non-null block, instead of before the null check. That should be a mild improvement.
This commit is contained in:
parent
7ea4fe7ede
commit
ecb502342c
clang
lib/CodeGen
test
CodeGenObjC
arc-foreach.marc-literals.marc-loadweakretained-release.marc-precise-lifetime.marc-property.marc-related-result-type.marc.mclass-stubs.mmatrix-type-operators.mns_consume_null_check.mnsvalue-objc-boxable-ios-arc.mnsvalue-objc-boxable-ios.mnsvalue-objc-boxable-mac-arc.mnsvalue-objc-boxable-mac.mobjc-container-subscripting-1.mproperty.mtentative-cfconstantstring.m
CodeGenObjCXX
|
@ -2138,16 +2138,7 @@ CGObjCCommonMac::EmitMessageSend(CodeGen::CodeGenFunction &CGF,
|
|||
const ObjCCommonTypesHelper &ObjCTypes) {
|
||||
CodeGenTypes &Types = CGM.getTypes();
|
||||
auto selTy = CGF.getContext().getObjCSelType();
|
||||
llvm::Value *SelValue;
|
||||
|
||||
if (Method && Method->isDirectMethod()) {
|
||||
// Direct methods will synthesize the proper `_cmd` internally,
|
||||
// so just don't bother with setting the `_cmd` argument.
|
||||
assert(!IsSuper);
|
||||
SelValue = llvm::UndefValue::get(Types.ConvertType(selTy));
|
||||
} else {
|
||||
SelValue = GetSelector(CGF, Sel);
|
||||
}
|
||||
llvm::Value *SelValue = llvm::UndefValue::get(Types.ConvertType(selTy));
|
||||
|
||||
CallArgList ActualArgs;
|
||||
if (!IsSuper)
|
||||
|
@ -2168,10 +2159,15 @@ CGObjCCommonMac::EmitMessageSend(CodeGen::CodeGenFunction &CGF,
|
|||
canMessageReceiverBeNull(CGF, Method, IsSuper, ClassReceiver, Arg0);
|
||||
|
||||
bool RequiresNullCheck = false;
|
||||
bool RequiresSelValue = true;
|
||||
|
||||
llvm::FunctionCallee Fn = nullptr;
|
||||
if (Method && Method->isDirectMethod()) {
|
||||
assert(!IsSuper);
|
||||
Fn = GenerateDirectMethod(Method, Method->getClassInterface());
|
||||
// Direct methods will synthesize the proper `_cmd` internally,
|
||||
// so just don't bother with setting the `_cmd` argument.
|
||||
RequiresSelValue = false;
|
||||
} else if (CGM.ReturnSlotInterferesWithArgs(MSI.CallInfo)) {
|
||||
if (ReceiverCanBeNull) RequiresNullCheck = true;
|
||||
Fn = (ObjCABI == 2) ? ObjCTypes.getSendStretFn2(IsSuper)
|
||||
|
@ -2209,6 +2205,12 @@ CGObjCCommonMac::EmitMessageSend(CodeGen::CodeGenFunction &CGF,
|
|||
nullReturn.init(CGF, Arg0);
|
||||
}
|
||||
|
||||
// If a selector value needs to be passed, emit the load before the call.
|
||||
if (RequiresSelValue) {
|
||||
SelValue = GetSelector(CGF, Sel);
|
||||
ActualArgs[1] = CallArg(RValue::get(SelValue), selTy);
|
||||
}
|
||||
|
||||
llvm::CallBase *CallSite;
|
||||
CGCallee Callee = CGCallee::forDirect(BitcastFn);
|
||||
RValue rvalue = CGF.EmitCall(MSI.CallInfo, Callee, Return, ActualArgs,
|
||||
|
|
|
@ -51,9 +51,9 @@ void test0(NSArray *array) {
|
|||
// CHECK-LP64-NEXT: [[SAVED_ARRAY:%.*]] = bitcast i8* [[T2]] to [[ARRAY_T]]*
|
||||
|
||||
// Call the enumeration method.
|
||||
// CHECK-LP64-NEXT: [[T0:%.*]] = load i8*, i8** @OBJC_SELECTOR_REFERENCES_
|
||||
// CHECK-LP64-NEXT: [[T1:%.*]] = bitcast [[ARRAY_T]]* [[SAVED_ARRAY]] to i8*
|
||||
// CHECK-LP64-NEXT: [[SIZE:%.*]] = call i64 bitcast (i8* (i8*, i8*, ...)* @objc_msgSend to i64 (i8*, i8*, [[STATE_T]]*, [16 x i8*]*, i64)*)(i8* [[T1]], i8* [[T0]], [[STATE_T]]* [[STATE]], [16 x i8*]* [[BUFFER]], i64 16)
|
||||
// CHECK-LP64-NEXT: [[T0:%.*]] = bitcast [[ARRAY_T]]* [[SAVED_ARRAY]] to i8*
|
||||
// CHECK-LP64-NEXT: [[T1:%.*]] = load i8*, i8** @OBJC_SELECTOR_REFERENCES_
|
||||
// CHECK-LP64-NEXT: [[SIZE:%.*]] = call i64 bitcast (i8* (i8*, i8*, ...)* @objc_msgSend to i64 (i8*, i8*, [[STATE_T]]*, [16 x i8*]*, i64)*)(i8* [[T0]], i8* [[T1]], [[STATE_T]]* [[STATE]], [16 x i8*]* [[BUFFER]], i64 16)
|
||||
|
||||
// Check for a nonzero result.
|
||||
// CHECK-LP64-NEXT: [[T0:%.*]] = icmp eq i64 [[SIZE]], 0
|
||||
|
@ -78,9 +78,9 @@ void test0(NSArray *array) {
|
|||
// CHECK-LP64-OPT: [[CAPTURE:%.*]] = load i8*, i8** [[D0]]
|
||||
// CHECK-LP64-OPT: call void (...) @llvm.objc.clang.arc.use(i8* [[CAPTURE]])
|
||||
|
||||
// CHECK-LP64: [[T0:%.*]] = load i8*, i8** @OBJC_SELECTOR_REFERENCES_
|
||||
// CHECK-LP64-NEXT: [[T1:%.*]] = bitcast [[ARRAY_T]]* [[SAVED_ARRAY]] to i8*
|
||||
// CHECK-LP64-NEXT: [[SIZE:%.*]] = call i64 bitcast (i8* (i8*, i8*, ...)* @objc_msgSend to i64 (i8*, i8*, [[STATE_T]]*, [16 x i8*]*, i64)*)(i8* [[T1]], i8* [[T0]], [[STATE_T]]* [[STATE]], [16 x i8*]* [[BUFFER]], i64 16)
|
||||
// CHECK-LP64: [[T0:%.*]] = bitcast [[ARRAY_T]]* [[SAVED_ARRAY]] to i8*
|
||||
// CHECK-LP64-NEXT: [[T1:%.*]] = load i8*, i8** @OBJC_SELECTOR_REFERENCES_
|
||||
// CHECK-LP64-NEXT: [[SIZE:%.*]] = call i64 bitcast (i8* (i8*, i8*, ...)* @objc_msgSend to i64 (i8*, i8*, [[STATE_T]]*, [16 x i8*]*, i64)*)(i8* [[T0]], i8* [[T1]], [[STATE_T]]* [[STATE]], [16 x i8*]* [[BUFFER]], i64 16)
|
||||
|
||||
// Release the array.
|
||||
// CHECK-LP64: [[T0:%.*]] = bitcast [[ARRAY_T]]* [[SAVED_ARRAY]] to i8*
|
||||
|
@ -141,8 +141,8 @@ void test2(Test2 *a) {
|
|||
// CHECK-LP64-NEXT: [[COLL:%.*]] = bitcast i8* [[T2]] to [[ARRAY_T]]*
|
||||
|
||||
// Make sure it's not immediately released before starting the iteration.
|
||||
// CHECK-LP64-NEXT: load i8*, i8** @OBJC_SELECTOR_REFERENCES_
|
||||
// CHECK-LP64-NEXT: [[T0:%.*]] = bitcast [[ARRAY_T]]* [[COLL]] to i8*
|
||||
// CHECK-LP64-NEXT: load i8*, i8** @OBJC_SELECTOR_REFERENCES_
|
||||
// CHECK-LP64-NEXT: @objc_msgSend
|
||||
|
||||
// This bitcast is for the mutation check.
|
||||
|
@ -151,6 +151,7 @@ void test2(Test2 *a) {
|
|||
|
||||
// This bitcast is for the 'next' message send.
|
||||
// CHECK-LP64: [[T0:%.*]] = bitcast [[ARRAY_T]]* [[COLL]] to i8*
|
||||
// CHECK-LP64-NEXT: load i8*, i8** @OBJC_SELECTOR_REFERENCES_
|
||||
// CHECK-LP64-NEXT: @objc_msgSend
|
||||
|
||||
// This bitcast is for the final release.
|
||||
|
|
|
@ -51,8 +51,8 @@ void test_array(id a, id b) {
|
|||
// CHECK-NEXT: store i8* [[V1]], i8** [[T0]]
|
||||
|
||||
// CHECK-NEXT: [[T0:%.*]] = load [[CLASS_T:%.*]]*, [[CLASS_T:%.*]]** @"OBJC_CLASSLIST
|
||||
// CHECK-NEXT: [[SEL:%.*]] = load i8*, i8** @OBJC_SELECTOR_REFERENCES
|
||||
// CHECK-NEXT: [[T1:%.*]] = bitcast [[CLASS_T]]* [[T0]] to i8*
|
||||
// CHECK-NEXT: [[SEL:%.*]] = load i8*, i8** @OBJC_SELECTOR_REFERENCES
|
||||
// CHECK-NEXT: [[T2:%.*]] = bitcast [2 x i8*]* [[OBJECTS]] to i8**
|
||||
// CHECK-NEXT: [[T3:%.*]] = call i8* bitcast ({{.*@objc_msgSend.*}})(i8* [[T1]], i8* [[SEL]], i8** [[T2]], i64 2) [ "clang.arc.attachedcall"(i8* (i8*)* @llvm.objc.retainAutoreleasedReturnValue) ]
|
||||
// CHECK: call void (...) @llvm.objc.clang.arc.use(i8* [[V0]], i8* [[V1]])
|
||||
|
@ -93,8 +93,8 @@ void test_dictionary(id k1, id o1, id k2, id o2) {
|
|||
|
||||
// Constructing the dictionary
|
||||
// CHECK-NEXT: [[T0:%.*]] = load [[CLASS_T:%.*]]*, [[CLASS_T:%.*]]** @"OBJC_CLASSLIST
|
||||
// CHECK-NEXT: [[SEL:%.*]] = load i8*, i8** @OBJC_SELECTOR_REFERENCES
|
||||
// CHECK-NEXT: [[T1:%.*]] = bitcast [[CLASS_T]]* [[T0]] to i8*
|
||||
// CHECK-NEXT: [[SEL:%.*]] = load i8*, i8** @OBJC_SELECTOR_REFERENCES
|
||||
// CHECK-NEXT: [[T2:%.*]] = bitcast [2 x i8*]* [[OBJECTS]] to i8**
|
||||
// CHECK-NEXT: [[T3:%.*]] = bitcast [2 x i8*]* [[KEYS]] to i8**
|
||||
// CHECK-NEXT: [[T4:%.*]] = call i8* bitcast ({{.*@objc_msgSend.*}})(i8* [[T1]], i8* [[SEL]], i8** [[T2]], i8** [[T3]], i64 2) [ "clang.arc.attachedcall"(i8* (i8*)* @llvm.objc.retainAutoreleasedReturnValue) ]
|
||||
|
@ -126,8 +126,8 @@ void test_property(B *b) {
|
|||
// CHECK: [[T0:%.*]] = getelementptr inbounds [1 x i8*], [1 x i8*]* [[OBJECTS:%.*]], i64 0, i64 0
|
||||
|
||||
// Invoke 'prop'
|
||||
// CHECK: [[SEL:%.*]] = load i8*, i8** @OBJC_SELECTOR_REFERENCES
|
||||
// CHECK-NEXT: [[T1:%.*]] = bitcast
|
||||
// CHECK: [[T1:%.*]] = bitcast
|
||||
// CHECK-NEXT: [[SEL:%.*]] = load i8*, i8** @OBJC_SELECTOR_REFERENCES
|
||||
// CHECK-NEXT: [[V0:%.*]] = call [[B:%.*]]* bitcast ({{.*}} @objc_msgSend to {{.*}})(i8* [[T1]], i8* [[SEL]]) [ "clang.arc.attachedcall"(i8* (i8*)* @llvm.objc.retainAutoreleasedReturnValue) ]
|
||||
// CHECK-NEXT: call void (...) @llvm.objc.clang.arc.noop.use([[B]]* [[V0]])
|
||||
// CHECK-NEXT: [[V1:%.*]] = bitcast [[B]]* [[V0]] to i8*
|
||||
|
@ -137,8 +137,8 @@ void test_property(B *b) {
|
|||
|
||||
// Invoke arrayWithObjects:count:
|
||||
// CHECK-NEXT: [[T0:%.*]] = load [[CLASS_T]]*, [[CLASS_T]]** @"OBJC_CLASSLIST
|
||||
// CHECK-NEXT: [[SEL:%.*]] = load i8*, i8** @OBJC_SELECTOR_REFERENCES
|
||||
// CHECK-NEXT: [[T1:%.*]] = bitcast [[CLASS_T]]* [[T0]] to i8*
|
||||
// CHECK-NEXT: [[SEL:%.*]] = load i8*, i8** @OBJC_SELECTOR_REFERENCES
|
||||
// CHECK-NEXT: [[T2:%.*]] = bitcast [1 x i8*]* [[OBJECTS]] to i8**
|
||||
// CHECK-NEXT: [[T3:%.*]] = call i8* bitcast ({{.*}} @objc_msgSend to {{.*}}(i8* [[T1]], i8* [[SEL]], i8** [[T2]], i64 1) [ "clang.arc.attachedcall"(i8* (i8*)* @llvm.objc.retainAutoreleasedReturnValue) ]
|
||||
// CHECK-NEXT: call void (...) @llvm.objc.clang.arc.noop.use(i8* [[T3]])
|
||||
|
@ -158,4 +158,4 @@ void test_property(B *b) {
|
|||
// Destroy b
|
||||
// CHECK: call void @llvm.objc.release
|
||||
// CHECK-NEXT: ret void
|
||||
}
|
||||
}
|
||||
|
|
|
@ -30,8 +30,8 @@ int main (int argc, const char * argv[]) {
|
|||
|
||||
// CHECK: [[SIXTEEN:%.*]] = call i8* @llvm.objc.loadWeakRetained(i8** {{%.*}})
|
||||
// CHECK-NEXT: [[SEVENTEEN:%.*]] = bitcast i8* [[SIXTEEN]] to {{%.*}}
|
||||
// CHECK-NEXT: [[EIGHTEEN:%.*]] = load i8*, i8** @OBJC_SELECTOR_REFERENCES_.6
|
||||
// CHECK-NEXT: [[NINETEEN:%.*]] = bitcast %0* [[SEVENTEEN]] to i8*
|
||||
// CHECK-NEXT: [[EIGHTEEN:%.*]] = load i8*, i8** @OBJC_SELECTOR_REFERENCES_.6
|
||||
// CHECK-NEXT: call void bitcast (i8* (i8*, i8*, ...)* @objc_msgSend
|
||||
// CHECK-NEXT: [[TWENTY:%.*]] = bitcast %0* [[SEVENTEEN]] to i8*
|
||||
// CHECK-NEXT: call void @llvm.objc.release(i8* [[TWENTY]])
|
||||
|
|
|
@ -50,8 +50,8 @@ void test1a_message(void) {
|
|||
// CHECK-NEXT: [[T1:%.*]] = bitcast [[TEST1]]* [[T0]] to i8*
|
||||
// CHECK-NEXT: [[T2:%.*]] = call i8* @llvm.objc.retainAutorelease(i8* [[T1]])
|
||||
// CHECK-NEXT: [[T3:%.*]] = bitcast i8* [[T2]] to [[TEST1]]*
|
||||
// CHECK-NEXT: [[T4:%.*]] = load i8*, i8** @OBJC_SELECTOR_REFERENCES_
|
||||
// CHECK-NEXT: [[T5:%.*]] = bitcast [[TEST1]]* [[T3]] to i8*
|
||||
// CHECK-NEXT: [[T4:%.*]] = load i8*, i8** @OBJC_SELECTOR_REFERENCES_
|
||||
// CHECK-NEXT: [[T6:%.*]] = call i8* bitcast
|
||||
// CHECK-NEXT: store i8* [[T6]], i8**
|
||||
// CHECK-NEXT: [[CPTR2:%.*]] = bitcast i8** [[C]] to i8*
|
||||
|
@ -82,8 +82,8 @@ void test1a_property(void) {
|
|||
// CHECK-NEXT: [[T1:%.*]] = bitcast [[TEST1]]* [[T0]] to i8*
|
||||
// CHECK-NEXT: [[T2:%.*]] = call i8* @llvm.objc.retainAutorelease(i8* [[T1]])
|
||||
// CHECK-NEXT: [[T3:%.*]] = bitcast i8* [[T2]] to [[TEST1]]*
|
||||
// CHECK-NEXT: [[T4:%.*]] = load i8*, i8** @OBJC_SELECTOR_REFERENCES_
|
||||
// CHECK-NEXT: [[T5:%.*]] = bitcast [[TEST1]]* [[T3]] to i8*
|
||||
// CHECK-NEXT: [[T4:%.*]] = load i8*, i8** @OBJC_SELECTOR_REFERENCES_
|
||||
// CHECK-NEXT: [[T6:%.*]] = call i8* bitcast
|
||||
// CHECK-NEXT: store i8* [[T6]], i8**
|
||||
// CHECK-NEXT: [[CPTR2:%.*]] = bitcast i8** [[C]] to i8*
|
||||
|
@ -111,8 +111,8 @@ void test1b_message(void) {
|
|||
// CHECK-NEXT: [[CPTR1:%.*]] = bitcast i8** [[C]] to i8*
|
||||
// CHECK-NEXT: call void @llvm.lifetime.start.p0i8(i64 8, i8* [[CPTR1]])
|
||||
// CHECK-NEXT: [[T0:%.*]] = load [[TEST1]]*, [[TEST1]]**
|
||||
// CHECK-NEXT: [[T1:%.*]] = load i8*, i8** @OBJC_SELECTOR_REFERENCES_
|
||||
// CHECK-NEXT: [[T2:%.*]] = bitcast [[TEST1]]* [[T0]] to i8*
|
||||
// CHECK-NEXT: [[T1:%.*]] = load i8*, i8** @OBJC_SELECTOR_REFERENCES_
|
||||
// CHECK-NEXT: [[T3:%.*]] = call i8* bitcast
|
||||
// CHECK-NEXT: store i8* [[T3]], i8**
|
||||
// CHECK-NEXT: [[CPTR2:%.*]] = bitcast i8** [[C]] to i8*
|
||||
|
@ -140,8 +140,8 @@ void test1b_property(void) {
|
|||
// CHECK-NEXT: [[CPTR1:%.*]] = bitcast i8** [[C]] to i8*
|
||||
// CHECK-NEXT: call void @llvm.lifetime.start.p0i8(i64 8, i8* [[CPTR1]])
|
||||
// CHECK-NEXT: [[T0:%.*]] = load [[TEST1]]*, [[TEST1]]**
|
||||
// CHECK-NEXT: [[T1:%.*]] = load i8*, i8** @OBJC_SELECTOR_REFERENCES_
|
||||
// CHECK-NEXT: [[T2:%.*]] = bitcast [[TEST1]]* [[T0]] to i8*
|
||||
// CHECK-NEXT: [[T1:%.*]] = load i8*, i8** @OBJC_SELECTOR_REFERENCES_
|
||||
// CHECK-NEXT: [[T3:%.*]] = call i8* bitcast
|
||||
// CHECK-NEXT: store i8* [[T3]], i8**
|
||||
// CHECK-NEXT: [[CPTR2:%.*]] = bitcast i8** [[C]] to i8*
|
||||
|
@ -172,8 +172,8 @@ void test1c_message(void) {
|
|||
// CHECK-NEXT: [[T1:%.*]] = bitcast [[TEST1]]* [[T0]] to i8*
|
||||
// CHECK-NEXT: [[T2:%.*]] = call i8* @llvm.objc.retainAutorelease(i8* [[T1]])
|
||||
// CHECK-NEXT: [[T3:%.*]] = bitcast i8* [[T2]] to [[TEST1]]*
|
||||
// CHECK-NEXT: [[T4:%.*]] = load i8*, i8** @OBJC_SELECTOR_REFERENCES_
|
||||
// CHECK-NEXT: [[T5:%.*]] = bitcast [[TEST1]]* [[T3]] to i8*
|
||||
// CHECK-NEXT: [[T4:%.*]] = load i8*, i8** @OBJC_SELECTOR_REFERENCES_
|
||||
// CHECK-NEXT: [[T6:%.*]] = call i8* bitcast
|
||||
// CHECK-NEXT: store i8* [[T6]], i8**
|
||||
// CHECK-NEXT: [[PCPTR2:%.*]] = bitcast i8** [[PC]] to i8*
|
||||
|
@ -203,8 +203,8 @@ void test1c_property(void) {
|
|||
// CHECK-NEXT: [[T1:%.*]] = bitcast [[TEST1]]* [[T0]] to i8*
|
||||
// CHECK-NEXT: [[T2:%.*]] = call i8* @llvm.objc.retainAutorelease(i8* [[T1]])
|
||||
// CHECK-NEXT: [[T3:%.*]] = bitcast i8* [[T2]] to [[TEST1]]*
|
||||
// CHECK-NEXT: [[T4:%.*]] = load i8*, i8** @OBJC_SELECTOR_REFERENCES_
|
||||
// CHECK-NEXT: [[T5:%.*]] = bitcast [[TEST1]]* [[T3]] to i8*
|
||||
// CHECK-NEXT: [[T4:%.*]] = load i8*, i8** @OBJC_SELECTOR_REFERENCES_
|
||||
// CHECK-NEXT: [[T6:%.*]] = call i8* bitcast
|
||||
// CHECK-NEXT: store i8* [[T6]], i8**
|
||||
// CHECK-NEXT: [[PCPTR2:%.*]] = bitcast i8** [[PC]] to i8*
|
||||
|
@ -231,9 +231,9 @@ void test1d_message(void) {
|
|||
// CHECK-NEXT: [[PCPTR1:%.*]] = bitcast i8** [[PC]] to i8*
|
||||
// CHECK-NEXT: call void @llvm.lifetime.start.p0i8(i64 8, i8* [[PCPTR1]])
|
||||
// CHECK-NEXT: [[T0:%.*]] = load [[TEST1]]*, [[TEST1]]**
|
||||
// CHECK-NEXT: [[SEVEN:%.*]] = load i8*, i8** @OBJC_SELECTOR_REFERENCES_
|
||||
// CHECK-NEXT: [[EIGHT:%.*]] = bitcast [[TEST1]]* [[T0]] to i8*
|
||||
// CHECK-NEXT: [[CALL1:%.*]] = call i8* bitcast (i8* (i8*, i8*, ...)* @objc_msgSend to i8* (i8*, i8*)*)(i8* noundef [[EIGHT]], i8* noundef [[SEVEN]])
|
||||
// CHECK-NEXT: [[SEL:%.*]] = load i8*, i8** @OBJC_SELECTOR_REFERENCES_
|
||||
// CHECK-NEXT: [[CALL1:%.*]] = call i8* bitcast (i8* (i8*, i8*, ...)* @objc_msgSend to i8* (i8*, i8*)*)(i8* noundef [[EIGHT]], i8* noundef [[SEL]])
|
||||
// CHECK-NEXT: store i8* [[CALL1]], i8**
|
||||
// CHECK-NEXT: [[PCPTR2:%.*]] = bitcast i8** [[PC]] to i8*
|
||||
// CHECK-NEXT: call void @llvm.lifetime.end.p0i8(i64 8, i8* [[PCPTR2]])
|
||||
|
@ -259,9 +259,9 @@ void test1d_property(void) {
|
|||
// CHECK-NEXT: [[PCPTR1:%.*]] = bitcast i8** [[PC]] to i8*
|
||||
// CHECK-NEXT: call void @llvm.lifetime.start.p0i8(i64 8, i8* [[PCPTR1]])
|
||||
// CHECK-NEXT: [[T0:%.*]] = load [[TEST1]]*, [[TEST1]]**
|
||||
// CHECK-NEXT: [[SEVEN:%.*]] = load i8*, i8** @OBJC_SELECTOR_REFERENCES_
|
||||
// CHECK-NEXT: [[EIGHT:%.*]] = bitcast [[TEST1]]* [[T0]] to i8*
|
||||
// CHECK-NEXT: [[CALL1:%.*]] = call i8* bitcast (i8* (i8*, i8*, ...)* @objc_msgSend to i8* (i8*, i8*)*)(i8* noundef [[EIGHT]], i8* noundef [[SEVEN]])
|
||||
// CHECK-NEXT: [[SEL:%.*]] = load i8*, i8** @OBJC_SELECTOR_REFERENCES_
|
||||
// CHECK-NEXT: [[CALL1:%.*]] = call i8* bitcast (i8* (i8*, i8*, ...)* @objc_msgSend to i8* (i8*, i8*)*)(i8* noundef [[EIGHT]], i8* noundef [[SEL]])
|
||||
// CHECK-NEXT: store i8* [[CALL1]], i8**
|
||||
// CHECK-NEXT: [[PCPTR2:%.*]] = bitcast i8** [[PC]] to i8*
|
||||
// CHECK-NEXT: call void @llvm.lifetime.end.p0i8(i64 8, i8* [[PCPTR2]])
|
||||
|
|
|
@ -101,14 +101,14 @@ void test3(Test3 *t) {
|
|||
// CHECK-NEXT: [[X:%.*]] = alloca i8*,
|
||||
// Property access.
|
||||
// CHECK: [[T0:%.*]] = load [[TEST3]]*, [[TEST3]]** [[T]],
|
||||
// CHECK-NEXT: [[SEL:%.*]] = load i8*, i8** @OBJC_SELECTOR_REFERENCES
|
||||
// CHECK-NEXT: [[T1:%.*]] = bitcast [[TEST3]]* [[T0]] to i8*
|
||||
// CHECK-NEXT: [[SEL:%.*]] = load i8*, i8** @OBJC_SELECTOR_REFERENCES
|
||||
// CHECK-NEXT: [[T2:%.*]] = call i8* bitcast ({{.*}} @objc_msgSend to {{.*}})(i8* noundef [[T1]], i8* noundef [[SEL]])
|
||||
// CHECK-NEXT: store i8* [[T2]], i8** [[X]],
|
||||
// Message send.
|
||||
// CHECK-NEXT: [[T0:%.*]] = load [[TEST3]]*, [[TEST3]]** [[T]],
|
||||
// CHECK-NEXT: [[SEL:%.*]] = load i8*, i8** @OBJC_SELECTOR_REFERENCES
|
||||
// CHECK-NEXT: [[T1:%.*]] = bitcast [[TEST3]]* [[T0]] to i8*
|
||||
// CHECK-NEXT: [[SEL:%.*]] = load i8*, i8** @OBJC_SELECTOR_REFERENCES
|
||||
// CHECK-NEXT: [[T2:%.*]] = call i8* bitcast ({{.*}} @objc_msgSend to {{.*}})(i8* noundef [[T1]], i8* noundef [[SEL]])
|
||||
// CHECK-NEXT: [[T3:%.*]] = load i8*, i8** [[X]],
|
||||
// CHECK-NEXT: store i8* [[T2]], i8** [[X]],
|
||||
|
|
|
@ -14,8 +14,8 @@ void test0(Test0 *val) {
|
|||
// CHECK-NEXT: bitcast
|
||||
// CHECK-NEXT: call void @llvm.objc.storeStrong(
|
||||
// CHECK-NEXT: load [[TEST0]]*, [[TEST0]]** [[VAL]],
|
||||
// CHECK-NEXT: load
|
||||
// CHECK-NEXT: bitcast
|
||||
// CHECK-NEXT: load
|
||||
// CHECK-NEXT: [[T0:%.*]] = call i8* bitcast (
|
||||
// CHECK-NEXT: [[T1:%.*]] = notail call i8* @llvm.objc.retainAutoreleasedReturnValue(i8* [[T0]])
|
||||
// CHECK-NEXT: [[T2:%.*]] = bitcast i8* [[T1]] to [[TEST0]]*
|
||||
|
|
|
@ -108,8 +108,8 @@ void test3_unelided() {
|
|||
|
||||
// Call to +alloc.
|
||||
// CHECK-NEXT: load {{.*}}, {{.*}}* @"OBJC_CLASSLIST_REFERENCES_
|
||||
// CHECK-NEXT: load i8*, i8** @OBJC_SELECTOR_REFERENCES_
|
||||
// CHECK-NEXT: bitcast
|
||||
// CHECK-NEXT: load i8*, i8** @OBJC_SELECTOR_REFERENCES_
|
||||
// CHECK-NEXT: [[ALLOC:%.*]] = call i8* bitcast (i8* (i8*, i8*, ...)* @objc_msgSend
|
||||
// CHECK-NEXT: bitcast
|
||||
// CHECK-NEXT: bitcast
|
||||
|
@ -117,8 +117,8 @@ void test3_unelided() {
|
|||
[Test3 alloc];
|
||||
|
||||
// CHECK-NEXT: [[T0:%.*]] = load [[TEST3]]*, [[TEST3]]** [[X]]
|
||||
// CHECK-NEXT: load i8*, i8** @OBJC_SELECTOR_REFERENCES_
|
||||
// CHECK-NEXT: [[T1:%.*]] = bitcast [[TEST3]]* [[T0]] to i8*
|
||||
// CHECK-NEXT: load i8*, i8** @OBJC_SELECTOR_REFERENCES_
|
||||
// CHECK-NEXT: [[COPY:%.*]] = call i8* bitcast (i8* (i8*, i8*, ...)* @objc_msgSend {{.*}})(i8* noundef [[T1]],
|
||||
// CHECK-NEXT: call void @llvm.objc.release(i8* [[COPY]]) [[NUW:#[0-9]+]]
|
||||
[x copy];
|
||||
|
@ -141,14 +141,14 @@ void test3() {
|
|||
|
||||
// Call to +alloc.
|
||||
// CHECK-NEXT: load {{.*}}, {{.*}}* @"OBJC_CLASSLIST_REFERENCES_
|
||||
// CHECK-NEXT: load i8*, i8** @OBJC_SELECTOR_REFERENCES_
|
||||
// CHECK-NEXT: bitcast
|
||||
// CHECK-NEXT: load i8*, i8** @OBJC_SELECTOR_REFERENCES_
|
||||
// CHECK-NEXT: [[ALLOC:%.*]] = call i8* bitcast (i8* (i8*, i8*, ...)* @objc_msgSend
|
||||
// CHECK-NEXT: bitcast
|
||||
|
||||
// Call to -initWith: with elided retain of consumed argument.
|
||||
// CHECK-NEXT: load i8*, i8** @OBJC_SELECTOR_REFERENCES_
|
||||
// CHECK-NEXT: bitcast
|
||||
// CHECK-NEXT: load i8*, i8** @OBJC_SELECTOR_REFERENCES_
|
||||
// CHECK-NEXT: [[INIT:%.*]] = call i8* bitcast (i8* (i8*, i8*, ...)* @objc_msgSend to i8* (i8*, i8*, i32)*)(i8*
|
||||
// CHECK-NEXT: bitcast
|
||||
// CHECK-NEXT: [[INIT:%.*]] = bitcast
|
||||
|
@ -179,14 +179,14 @@ void test3() {
|
|||
id test4() {
|
||||
// Call to +alloc.
|
||||
// CHECK: load {{.*}}, {{.*}}* @"OBJC_CLASSLIST_REFERENCES_
|
||||
// CHECK-NEXT: load i8*, i8** @OBJC_SELECTOR_REFERENCES_
|
||||
// CHECK-NEXT: bitcast
|
||||
// CHECK-NEXT: load i8*, i8** @OBJC_SELECTOR_REFERENCES_
|
||||
// CHECK-NEXT: [[ALLOC:%.*]] = call i8* bitcast (i8* (i8*, i8*, ...)* @objc_msgSend
|
||||
// CHECK-NEXT: [[ALLOC:%.*]] = bitcast
|
||||
|
||||
// Call to -initWith: with elided retain of consumed argument.
|
||||
// CHECK-NEXT: load i8*, i8** @OBJC_SELECTOR_REFERENCES_
|
||||
// CHECK-NEXT: [[ALLOC:%.*]] = bitcast
|
||||
// CHECK-NEXT: load i8*, i8** @OBJC_SELECTOR_REFERENCES_
|
||||
// CHECK-NEXT: [[INIT:%.*]] = call i8* bitcast (i8* (i8*, i8*, ...)* @objc_msgSend to i8* (i8*, i8*, i32)*)(i8* noundef [[ALLOC]],
|
||||
|
||||
// Initialization of return value, occurring within full-expression.
|
||||
|
@ -314,12 +314,12 @@ void test10() {
|
|||
// CHECK-NEXT: [[YPTR1:%.*]] = bitcast i8** [[Y]] to i8*
|
||||
// CHECK-NEXT: call void @llvm.lifetime.start.p0i8(i64 8, i8* [[YPTR1]])
|
||||
// CHECK-NEXT: load [[TEST10]]*, [[TEST10]]** [[X]], align
|
||||
// CHECK-NEXT: load i8*, i8** @OBJC_SELECTOR_REFERENCES_{{[0-9]*}}
|
||||
// CHECK-NEXT: bitcast
|
||||
// CHECK-NEXT: load i8*, i8** @OBJC_SELECTOR_REFERENCES_{{[0-9]*}}
|
||||
// CHECK-NEXT: [[V:%.*]] = call [[TEST10]]* bitcast (i8* (i8*, i8*, ...)* @objc_msgSend{{.*}} [ "clang.arc.attachedcall"(i8* (i8*)* @llvm.objc.retainAutoreleasedReturnValue) ]
|
||||
// CHECK-NEXT: call void (...) @llvm.objc.clang.arc.noop.use(%3* [[V]])
|
||||
// CHECK-NEXT: load i8*, i8** @OBJC_SELECTOR_REFERENCES_{{[0-9]*}}
|
||||
// CHECK-NEXT: bitcast
|
||||
// CHECK-NEXT: load i8*, i8** @OBJC_SELECTOR_REFERENCES_{{[0-9]*}}
|
||||
// CHECK-NEXT: [[T3:%.*]] = call [[TEST10]]* bitcast (i8* (i8*, i8*, ...)* @objc_msgSend{{.*}} [ "clang.arc.attachedcall"(i8* (i8*)* @llvm.objc.retainAutoreleasedReturnValue) ]
|
||||
// CHECK-NEXT: call void (...) @llvm.objc.clang.arc.noop.use(%3* [[T3]])
|
||||
// CHECK-NEXT: [[T4:%.*]] = bitcast [[TEST10]]* [[T3]] to i8*
|
||||
|
@ -721,9 +721,9 @@ static id _test29_allocator = 0;
|
|||
// CHECK-NEXT: store [[TEST29]]* null, [[TEST29]]** [[SELF]]
|
||||
|
||||
// Actual message send.
|
||||
// CHECK-NEXT: [[T2:%.*]] = load i8*, i8** @OBJC_SELECTOR_REFERENCES_
|
||||
// CHECK-NEXT: [[T3:%.*]] = bitcast [[TEST29]]* [[T0]] to i8*
|
||||
// CHECK-NEXT: [[CALL:%.*]] = call i8* bitcast (i8* (i8*, i8*, ...)* @objc_msgSend to i8* (i8*, i8*, i8*)*)(i8* noundef [[T3]], i8* noundef [[T2]], i8* noundef [[T1]])
|
||||
// CHECK-NEXT: [[T2:%.*]] = bitcast [[TEST29]]* [[T0]] to i8*
|
||||
// CHECK-NEXT: [[SEL:%.*]] = load i8*, i8** @OBJC_SELECTOR_REFERENCES_
|
||||
// CHECK-NEXT: [[CALL:%.*]] = call i8* bitcast (i8* (i8*, i8*, ...)* @objc_msgSend to i8* (i8*, i8*, i8*)*)(i8* noundef [[T2]], i8* noundef [[SEL]], i8* noundef [[T1]])
|
||||
|
||||
// Implicit write of result back into 'self'. This is not supposed to
|
||||
// be detectable because we're supposed to ban accesses to the old
|
||||
|
@ -824,9 +824,9 @@ char *helper;
|
|||
|
||||
// Call.
|
||||
// CHECK-NEXT: [[T0:%.*]] = load [[TEST30]]*, [[TEST30]]** [[SELF]]
|
||||
// CHECK-NEXT: [[T1:%.*]] = load i8*, i8** @OBJC_SELECTOR_REFERENCES_
|
||||
// CHECK-NEXT: [[T2:%.*]] = bitcast [[TEST30]]* [[T0]] to i8*
|
||||
// CHECK-NEXT: [[CALL:%.*]] = call [[TEST30_HELPER:%.*]]* bitcast {{.*}} @objc_msgSend {{.*}}(i8* noundef [[T2]], i8* noundef [[T1]])
|
||||
// CHECK-NEXT: [[T1:%.*]] = bitcast [[TEST30]]* [[T0]] to i8*
|
||||
// CHECK-NEXT: [[SEL:%.*]] = load i8*, i8** @OBJC_SELECTOR_REFERENCES_
|
||||
// CHECK-NEXT: [[CALL:%.*]] = call [[TEST30_HELPER:%.*]]* bitcast {{.*}} @objc_msgSend {{.*}}(i8* noundef [[T1]], i8* noundef [[SEL]])
|
||||
|
||||
// Assignment.
|
||||
// CHECK-NEXT: [[T0:%.*]] = bitcast [[TEST30_HELPER]]* [[CALL]] to i8*
|
||||
|
@ -911,8 +911,8 @@ void test33(Test33 *ptr) {
|
|||
// CHECK-NEXT: load [[TEST33]]*, [[TEST33]]** [[PTR]]
|
||||
// CHECK-NEXT: [[W0:%.*]] = load [[A_T]]*, [[A_T]]** [[A]]
|
||||
// CHECK-NEXT: store [[A_T]]* [[W0]], [[A_T]]** [[TEMP0]]
|
||||
// CHECK-NEXT: load i8*, i8** @OBJC_SELECTOR_REFERENCES_
|
||||
// CHECK-NEXT: bitcast
|
||||
// CHECK-NEXT: load i8*, i8** @OBJC_SELECTOR_REFERENCES_
|
||||
// CHECK-NEXT: objc_msgSend{{.*}}, [[A_T]]** noundef [[TEMP0]])
|
||||
// CHECK-NEXT: [[T0:%.*]] = load [[A_T]]*, [[A_T]]** [[TEMP0]]
|
||||
// CHECK-NEXT: [[T1:%.*]] = bitcast [[A_T]]* [[T0]] to i8*
|
||||
|
@ -927,8 +927,8 @@ void test33(Test33 *ptr) {
|
|||
// CHECK-NEXT: load [[TEST33]]*, [[TEST33]]** [[PTR]]
|
||||
// CHECK-NEXT: [[W0:%.*]] = load [[A_T]]*, [[A_T]]** [[A]]
|
||||
// CHECK-NEXT: store [[A_T]]* [[W0]], [[A_T]]** [[TEMP1]]
|
||||
// CHECK-NEXT: load i8*, i8** @OBJC_SELECTOR_REFERENCES_
|
||||
// CHECK-NEXT: bitcast
|
||||
// CHECK-NEXT: load i8*, i8** @OBJC_SELECTOR_REFERENCES_
|
||||
// CHECK-NEXT: objc_msgSend{{.*}}, [[A_T]]** noundef [[TEMP1]])
|
||||
// CHECK-NEXT: [[T0:%.*]] = load [[A_T]]*, [[A_T]]** [[TEMP1]]
|
||||
// CHECK-NEXT: [[T1:%.*]] = bitcast [[A_T]]* [[T0]] to i8*
|
||||
|
@ -941,20 +941,20 @@ void test33(Test33 *ptr) {
|
|||
// CHECK-NEXT: call void @llvm.objc.release(i8* [[T5]])
|
||||
|
||||
// CHECK-NEXT: load [[TEST33]]*, [[TEST33]]** [[PTR]]
|
||||
// CHECK-NEXT: load i8*, i8** @OBJC_SELECTOR_REFERENCES_
|
||||
// CHECK-NEXT: bitcast
|
||||
// CHECK-NEXT: load i8*, i8** @OBJC_SELECTOR_REFERENCES_
|
||||
// CHECK-NEXT: objc_msgSend{{.*}}, [[A_T]]** noundef [[A]])
|
||||
|
||||
// CHECK-NEXT: load [[TEST33]]*, [[TEST33]]** [[PTR]]
|
||||
// CHECK-NEXT: load i8*, i8** @OBJC_SELECTOR_REFERENCES_
|
||||
// CHECK-NEXT: bitcast
|
||||
// CHECK-NEXT: load i8*, i8** @OBJC_SELECTOR_REFERENCES_
|
||||
// CHECK-NEXT: objc_msgSend{{.*}}, [[A_T]]** noundef [[A]])
|
||||
|
||||
// 'out'
|
||||
// CHECK-NEXT: load [[TEST33]]*, [[TEST33]]** [[PTR]]
|
||||
// CHECK-NEXT: store [[A_T]]* null, [[A_T]]** [[TEMP2]]
|
||||
// CHECK-NEXT: load i8*, i8** @OBJC_SELECTOR_REFERENCES_
|
||||
// CHECK-NEXT: bitcast
|
||||
// CHECK-NEXT: load i8*, i8** @OBJC_SELECTOR_REFERENCES_
|
||||
// CHECK-NEXT: objc_msgSend{{.*}}, [[A_T]]** noundef [[TEMP2]])
|
||||
// CHECK-NEXT: [[T0:%.*]] = load [[A_T]]*, [[A_T]]** [[TEMP2]]
|
||||
// CHECK-NEXT: [[T1:%.*]] = bitcast [[A_T]]* [[T0]] to i8*
|
||||
|
@ -1453,11 +1453,12 @@ void test66(void) {
|
|||
// CHECK-NEXT: call void (...) @llvm.objc.clang.arc.noop.use([[TEST66]]* [[T3]])
|
||||
// CHECK-NEXT: [[T4:%.*]] = call i8* @test66_arg(){{.*}} [ "clang.arc.attachedcall"(i8* (i8*)* @llvm.objc.retainAutoreleasedReturnValue) ]
|
||||
// CHECK-NEXT: call void (...) @llvm.objc.clang.arc.noop.use(i8* [[T4]])
|
||||
// CHECK-NEXT: [[T6:%.*]] = load i8*, i8** @OBJC_SELECTOR_REFERENCES
|
||||
// CHECK-NEXT: [[T7:%.*]] = bitcast [[TEST66]]* [[T3]] to i8*
|
||||
// CHECK-NEXT: [[SIX:%.*]] = icmp eq i8* [[T7]], null
|
||||
// CHECK-NEXT: br i1 [[SIX]], label [[NULINIT:%.*]], label [[CALL:%.*]]
|
||||
// CHECK: call void bitcast (i8* (i8*, i8*, ...)* @objc_msgSend to void (i8*, i8*, i8*)*)(i8* noundef [[T7]], i8* noundef [[T6]], i8* noundef [[T4]])
|
||||
// CHECK-NEXT: br i1 [[SIX]], label [[NULINIT:%.*]], label %[[CALL:.*]]
|
||||
// CHECK: [[CALL]]:
|
||||
// CHECK-NEXT: [[SEL:%.*]] = load i8*, i8** @OBJC_SELECTOR_REFERENCES
|
||||
// CHECK-NEXT: call void bitcast (i8* (i8*, i8*, ...)* @objc_msgSend to void (i8*, i8*, i8*)*)(i8* noundef [[T7]], i8* noundef [[SEL]], i8* noundef [[T4]])
|
||||
// CHECK-NEXT: br label [[CONT:%.*]]
|
||||
// CHECK: call void @llvm.objc.release(i8* [[T4]]) [[NUW]]
|
||||
// CHECK-NEXT: br label [[CONT:%.*]]
|
||||
|
|
|
@ -42,8 +42,8 @@ int main() {
|
|||
// CHECK-LABEL: define{{.*}} i32 @main()
|
||||
// CHECK-NEXT: entry:
|
||||
// CHECK-NEXT: [[CLASS:%.*]] = call %struct._class_t* @objc_loadClassref(i8** @"OBJC_CLASSLIST_REFERENCES_$_")
|
||||
// CHECK-NEXT: [[SELECTOR:%.*]] = load i8*, i8** @OBJC_SELECTOR_REFERENCES_
|
||||
// CHECK-NEXT: [[RECEIVER:%.*]] = bitcast %struct._class_t* [[CLASS]] to i8*
|
||||
// CHECK-NEXT: [[SELECTOR:%.*]] = load i8*, i8** @OBJC_SELECTOR_REFERENCES_
|
||||
// CHECK-NEXT: call void bitcast (i8* (i8*, i8*, ...)* @objc_msgSend to void (i8*, i8*)*)(i8* noundef [[RECEIVER]], i8* noundef [[SELECTOR]])
|
||||
// CHECK-NEXT: ret i32 0
|
||||
|
||||
|
|
|
@ -13,13 +13,13 @@ typedef double double4x4 __attribute__((matrix_type(4, 4)));
|
|||
// CHECK-LABEL: @test_index_placeholders(
|
||||
// CHECK-NEXT: entry:
|
||||
// CHECK: [[IV:%.*]] = load %0*, %0** [[IV_ADDR:%.*]], align 8
|
||||
// CHECK-NEXT: [[SEL:%.*]] = load i8*, i8** @OBJC_SELECTOR_REFERENCES_, align 8, !invariant.load !7
|
||||
// CHECK-NEXT: [[IV_PTR:%.*]] = bitcast %0* [[IV]] to i8*
|
||||
// CHECK-NEXT: [[SEL:%.*]] = load i8*, i8** @OBJC_SELECTOR_REFERENCES_, align 8, !invariant.load !7
|
||||
// CHECK-NEXT: [[CALL:%.*]] = call i32 bitcast (i8* (i8*, i8*, ...)* @objc_msgSend to i32 (i8*, i8*)*)(i8* noundef [[IV_PTR]], i8* noundef [[SEL]])
|
||||
// CHECK-NEXT: [[CONV:%.*]] = sext i32 [[CALL]] to i64
|
||||
// CHECK-NEXT: [[IV2:%.*]] = load %0*, %0** [[IV_ADDR]], align 8
|
||||
// CHECK-NEXT: [[SEL2:%.*]] = load i8*, i8** @OBJC_SELECTOR_REFERENCES_, align 8, !invariant.load !7
|
||||
// CHECK-NEXT: [[IV2_PTR:%.*]] = bitcast %0* [[IV2]] to i8*
|
||||
// CHECK-NEXT: [[SEL2:%.*]] = load i8*, i8** @OBJC_SELECTOR_REFERENCES_, align 8, !invariant.load !7
|
||||
// CHECK-NEXT: [[CALL1:%.*]] = call i32 bitcast (i8* (i8*, i8*, ...)* @objc_msgSend to i32 (i8*, i8*)*)(i8* noundef [[IV2_PTR]], i8* noundef [[SEL2]])
|
||||
// CHECK-NEXT: [[CONV2:%.*]] = sext i32 [[CALL1]] to i64
|
||||
// CHECK-NEXT: [[IDX1:%.*]] = mul i64 [[CONV2]], 4
|
||||
|
@ -40,20 +40,20 @@ __attribute__((objc_root_class))
|
|||
|
||||
// CHECK-LABEL: @test_base_and_index_placeholders(
|
||||
// CHECK: [[IV:%.*]] = load %0*, %0** [[IV_ADDR:%.*]], align 8
|
||||
// CHECK-NEXT: [[SEL:%.*]] = load i8*, i8** @OBJC_SELECTOR_REFERENCES_, align 8, !invariant.load !7
|
||||
// CHECK-NEXT: [[IV_PTR:%.*]] = bitcast %0* [[IV]] to i8*
|
||||
// CHECK-NEXT: [[SEL:%.*]] = load i8*, i8** @OBJC_SELECTOR_REFERENCES_, align 8, !invariant.load !7
|
||||
// CHECK-NEXT: [[CALL:%.*]] = call i32 bitcast (i8* (i8*, i8*, ...)* @objc_msgSend to i32 (i8*, i8*)*)(i8* noundef [[IV_PTR]], i8* noundef [[SEL]])
|
||||
// CHECK-NEXT: [[CONV:%.*]] = sext i32 [[CALL]] to i64
|
||||
// CHECK-NEXT: [[IV2:%.*]] = load %0*, %0** [[IV_ADDR]], align 8
|
||||
// CHECK-NEXT: [[SEL2:%.*]] = load i8*, i8** @OBJC_SELECTOR_REFERENCES_, align 8, !invariant.load !7
|
||||
// CHECK-NEXT: [[IV2_PTR:%.*]] = bitcast %0* [[IV2]] to i8*
|
||||
// CHECK-NEXT: [[SEL2:%.*]] = load i8*, i8** @OBJC_SELECTOR_REFERENCES_, align 8, !invariant.load !7
|
||||
// CHECK-NEXT: [[CALL1:%.*]] = call i32 bitcast (i8* (i8*, i8*, ...)* @objc_msgSend to i32 (i8*, i8*)*)(i8* noundef [[IV2_PTR]], i8* noundef [[SEL2]])
|
||||
// CHECK-NEXT: [[CONV2:%.*]] = sext i32 [[CALL1]] to i64
|
||||
// CHECK-NEXT: [[IDX1:%.*]] = mul i64 [[CONV2]], 4
|
||||
// CHECK-NEXT: [[IDX2:%.*]] = add i64 [[IDX1]], [[CONV]]
|
||||
// CHECK-NEXT: [[M:%.*]] = load %1*, %1** %m.addr, align 8
|
||||
// CHECK-NEXT: [[SEL3:%.*]] = load i8*, i8** @OBJC_SELECTOR_REFERENCES_, align 8, !invariant.load !7
|
||||
// CHECK-NEXT: [[M_PTR:%.*]] = bitcast %1* [[M]] to i8*
|
||||
// CHECK-NEXT: [[SEL3:%.*]] = load i8*, i8** @OBJC_SELECTOR_REFERENCES_, align 8, !invariant.load !7
|
||||
// CHECK-NEXT: [[MAT:%.*]] = call <16 x double> bitcast (i8* (i8*, i8*, ...)* @objc_msgSend to <16 x double> (i8*, i8*)*)(i8* noundef [[M_PTR]], i8* noundef [[SEL3]])
|
||||
// CHECK-NEXT: [[MATEXT:%.*]] = extractelement <16 x double> [[MAT]], i64 [[IDX2]]
|
||||
// CHECK-NEXT: ret double [[MATEXT]]
|
||||
|
|
|
@ -50,13 +50,14 @@ void test1(void) {
|
|||
// CHECK-NEXT: [[T0:%.*]] = load [[MYOBJECT:%.*]]*, [[MYOBJECT:%.*]]** @x
|
||||
// CHECK-NEXT: [[ARG:%.*]] = load i8*, i8** [[OBJ]]
|
||||
// CHECK-NEXT: [[ARG_RETAINED:%.*]] = call i8* @llvm.objc.retain(i8* [[ARG]])
|
||||
// CHECK-NEXT: load i8*, i8** @
|
||||
// CHECK-NEXT: [[SELF:%.*]] = bitcast [[MYOBJECT]]* [[T0]] to i8*
|
||||
// Null check.
|
||||
// CHECK-NEXT: [[T0:%.*]] = icmp eq i8* [[SELF]], null
|
||||
// CHECK-NEXT: br i1 [[T0]], label [[FORNULL:%.*]], label [[FORCALL:%.*]]
|
||||
// CHECK-NEXT: br i1 [[T0]], label [[FORNULL:%.*]], label %[[FORCALL:.*]]
|
||||
// Invoke and produce the return values.
|
||||
// CHECK: [[CALL:%.*]] = invoke <2 x float> bitcast
|
||||
// CHECK: [[FORCALL]]:
|
||||
// CHECK-NEXT: load i8*, i8** @OBJC_SELECTOR_REFERENCES_
|
||||
// CHECK-NEXT: [[CALL:%.*]] = invoke <2 x float> bitcast
|
||||
// CHECK-NEXT: to label [[INVOKE_CONT:%.*]] unwind label {{%.*}}
|
||||
// CHECK: [[T0:%.*]] = bitcast { float, float }* [[COERCE:%.*]] to <2 x float>*
|
||||
// CHECK-NEXT: store <2 x float> [[CALL]], <2 x float>* [[T0]],
|
||||
|
|
|
@ -21,8 +21,8 @@ void doRange() {
|
|||
// CHECK: [[LOCAL_CAST:%.*]] = bitcast %struct._NSRange* [[LOCAL_VAR]]{{.*}}
|
||||
// CHECK: call void @llvm.memcpy{{.*}} [[TEMP_CAST]]{{.*}} [[LOCAL_CAST]]{{.*}}
|
||||
// CHECK: [[PARAM_CAST:%.*]] = bitcast %struct._NSRange* [[TEMP_VAR]]{{.*}}
|
||||
// CHECK: [[SEL:%.*]] = load i8*, i8** [[VALUE_SEL]]
|
||||
// CHECK: [[RECV:%.*]] = bitcast %struct._class_t* [[RECV_PTR]] to i8*
|
||||
// CHECK: [[SEL:%.*]] = load i8*, i8** [[VALUE_SEL]]
|
||||
NSRange ns_range = { .location = 0, .length = 42 };
|
||||
// CHECK: call {{.*objc_msgSend.*}}(i8* noundef [[RECV]], i8* noundef [[SEL]], i8* noundef [[PARAM_CAST]], i8* {{.*}}[[RANGE_STR]]{{.*}})
|
||||
// CHECK: call i8* @llvm.objc.retainAutoreleasedReturnValue
|
||||
|
@ -40,8 +40,8 @@ void doPoint() {
|
|||
// CHECK: [[LOCAL_CAST:%.*]] = bitcast %struct.CGPoint* [[LOCAL_VAR]]{{.*}}
|
||||
// CHECK: call void @llvm.memcpy{{.*}} [[TEMP_CAST]]{{.*}} [[LOCAL_CAST]]{{.*}}
|
||||
// CHECK: [[PARAM_CAST:%.*]] = bitcast %struct.CGPoint* [[TEMP_VAR]]{{.*}}
|
||||
// CHECK: [[SEL:%.*]] = load i8*, i8** [[VALUE_SEL]]
|
||||
// CHECK: [[RECV:%.*]] = bitcast %struct._class_t* [[RECV_PTR]] to i8*
|
||||
// CHECK: [[SEL:%.*]] = load i8*, i8** [[VALUE_SEL]]
|
||||
CGPoint cg_point = { .x = 42, .y = 24 };
|
||||
// CHECK: call {{.*objc_msgSend.*}}(i8* noundef [[RECV]], i8* noundef [[SEL]], i8* noundef [[PARAM_CAST]], i8* {{.*}}[[POINT_STR]]{{.*}})
|
||||
// CHECK: call i8* @llvm.objc.retainAutoreleasedReturnValue
|
||||
|
@ -59,8 +59,8 @@ void doSize() {
|
|||
// CHECK: [[LOCAL_CAST:%.*]] = bitcast %struct.CGSize* [[LOCAL_VAR]]{{.*}}
|
||||
// CHECK: call void @llvm.memcpy{{.*}} [[TEMP_CAST]]{{.*}} [[LOCAL_CAST]]{{.*}}
|
||||
// CHECK: [[PARAM_CAST:%.*]] = bitcast %struct.CGSize* [[TEMP_VAR]]{{.*}}
|
||||
// CHECK: [[SEL:%.*]] = load i8*, i8** [[VALUE_SEL]]
|
||||
// CHECK: [[RECV:%.*]] = bitcast %struct._class_t* [[RECV_PTR]] to i8*
|
||||
// CHECK: [[SEL:%.*]] = load i8*, i8** [[VALUE_SEL]]
|
||||
CGSize cg_size = { .width = 42, .height = 24 };
|
||||
// CHECK: call {{.*objc_msgSend.*}}(i8* noundef [[RECV]], i8* noundef [[SEL]], i8* noundef [[PARAM_CAST]], i8* {{.*}}[[SIZE_STR]]{{.*}})
|
||||
// CHECK: call i8* @llvm.objc.retainAutoreleasedReturnValue
|
||||
|
@ -78,8 +78,8 @@ void doRect() {
|
|||
// CHECK: [[LOCAL_CAST:%.*]] = bitcast %struct.CGRect* [[LOCAL_VAR]]{{.*}}
|
||||
// CHECK: call void @llvm.memcpy{{.*}} [[TEMP_CAST]]{{.*}} [[LOCAL_CAST]]{{.*}}
|
||||
// CHECK: [[PARAM_CAST:%.*]] = bitcast %struct.CGRect* [[TEMP_VAR]]{{.*}}
|
||||
// CHECK: [[SEL:%.*]] = load i8*, i8** [[VALUE_SEL]]
|
||||
// CHECK: [[RECV:%.*]] = bitcast %struct._class_t* [[RECV_PTR]] to i8*
|
||||
// CHECK: [[SEL:%.*]] = load i8*, i8** [[VALUE_SEL]]
|
||||
CGPoint cg_point = { .x = 42, .y = 24 };
|
||||
CGSize cg_size = { .width = 42, .height = 24 };
|
||||
CGRect cg_rect = { .origin = cg_point, .size = cg_size };
|
||||
|
@ -99,8 +99,8 @@ void doNSEdgeInsets() {
|
|||
// CHECK: [[LOCAL_CAST:%.*]] = bitcast %struct.NSEdgeInsets* [[LOCAL_VAR]]{{.*}}
|
||||
// CHECK: call void @llvm.memcpy{{.*}} [[TEMP_CAST]]{{.*}} [[LOCAL_CAST]]{{.*}}
|
||||
// CHECK: [[PARAM_CAST:%.*]] = bitcast %struct.NSEdgeInsets* [[TEMP_VAR]]{{.*}}
|
||||
// CHECK: [[SEL:%.*]] = load i8*, i8** [[VALUE_SEL]]
|
||||
// CHECK: [[RECV:%.*]] = bitcast %struct._class_t* [[RECV_PTR]] to i8*
|
||||
// CHECK: [[SEL:%.*]] = load i8*, i8** [[VALUE_SEL]]
|
||||
NSEdgeInsets ns_edge_insets;
|
||||
// CHECK: call {{.*objc_msgSend.*}}(i8* noundef [[RECV]], i8* noundef [[SEL]], i8* noundef [[PARAM_CAST]], i8*{{.*}}[[EDGE_STR]]{{.*}})
|
||||
// CHECK: call i8* @llvm.objc.retainAutoreleasedReturnValue
|
||||
|
@ -115,8 +115,8 @@ void doRangeRValue() {
|
|||
// CHECK: [[RECV_PTR:%.*]] = load {{.*}} [[NSVALUE]]
|
||||
// CHECK: call {{.*}} @getRange {{.*}} [[COERCE]]{{.*}}
|
||||
// CHECK: [[COERCE_CAST:%.*]] = bitcast %struct._NSRange* [[COERCE]]{{.*}}
|
||||
// CHECK: [[SEL:%.*]] = load i8*, i8** [[VALUE_SEL]]
|
||||
// CHECK: [[RECV:%.*]] = bitcast %struct._class_t* [[RECV_PTR]] to i8*
|
||||
// CHECK: [[SEL:%.*]] = load i8*, i8** [[VALUE_SEL]]
|
||||
// CHECK: call {{.*objc_msgSend.*}}(i8* noundef [[RECV]], i8* noundef [[SEL]], i8* noundef [[COERCE_CAST]], i8* {{.*}}[[RANGE_STR]]{{.*}})
|
||||
// CHECK: call i8* @llvm.objc.retainAutoreleasedReturnValue
|
||||
NSValue *range_rvalue = @(getRange());
|
||||
|
|
|
@ -21,8 +21,8 @@ void doRange() {
|
|||
// CHECK: [[LOCAL_CAST:%.*]] = bitcast %struct._NSRange* [[LOCAL_VAR]]{{.*}}
|
||||
// CHECK: call void @llvm.memcpy{{.*}} [[TEMP_CAST]]{{.*}} [[LOCAL_CAST]]{{.*}}
|
||||
// CHECK: [[PARAM_CAST:%.*]] = bitcast %struct._NSRange* [[TEMP_VAR]]{{.*}}
|
||||
// CHECK: [[SEL:%.*]] = load i8*, i8** [[VALUE_SEL]]
|
||||
// CHECK: [[RECV:%.*]] = bitcast %struct._class_t* [[RECV_PTR]] to i8*
|
||||
// CHECK: [[SEL:%.*]] = load i8*, i8** [[VALUE_SEL]]
|
||||
NSRange ns_range = { .location = 0, .length = 42 };
|
||||
// CHECK: call {{.*objc_msgSend.*}}(i8* noundef [[RECV]], i8* noundef [[SEL]], i8* noundef [[PARAM_CAST]], i8* noundef {{.*}}[[RANGE_STR]]{{.*}})
|
||||
NSValue *range = @(ns_range);
|
||||
|
@ -38,8 +38,8 @@ void doPoint() {
|
|||
// CHECK: [[LOCAL_CAST:%.*]] = bitcast %struct.CGPoint* [[LOCAL_VAR]]{{.*}}
|
||||
// CHECK: call void @llvm.memcpy{{.*}} [[TEMP_CAST]]{{.*}} [[LOCAL_CAST]]{{.*}}
|
||||
// CHECK: [[PARAM_CAST:%.*]] = bitcast %struct.CGPoint* [[TEMP_VAR]]{{.*}}
|
||||
// CHECK: [[SEL:%.*]] = load i8*, i8** [[VALUE_SEL]]
|
||||
// CHECK: [[RECV:%.*]] = bitcast %struct._class_t* [[RECV_PTR]] to i8*
|
||||
// CHECK: [[SEL:%.*]] = load i8*, i8** [[VALUE_SEL]]
|
||||
CGPoint cg_point = { .x = 42, .y = 24 };
|
||||
// CHECK: call {{.*objc_msgSend.*}}(i8* noundef [[RECV]], i8* noundef [[SEL]], i8* noundef [[PARAM_CAST]], i8* noundef {{.*}}[[POINT_STR]]{{.*}})
|
||||
NSValue *point = @(cg_point);
|
||||
|
@ -55,8 +55,8 @@ void doSize() {
|
|||
// CHECK: [[LOCAL_CAST:%.*]] = bitcast %struct.CGSize* [[LOCAL_VAR]]{{.*}}
|
||||
// CHECK: call void @llvm.memcpy{{.*}} [[TEMP_CAST]]{{.*}} [[LOCAL_CAST]]{{.*}}
|
||||
// CHECK: [[PARAM_CAST:%.*]] = bitcast %struct.CGSize* [[TEMP_VAR]]{{.*}}
|
||||
// CHECK: [[SEL:%.*]] = load i8*, i8** [[VALUE_SEL]]
|
||||
// CHECK: [[RECV:%.*]] = bitcast %struct._class_t* [[RECV_PTR]] to i8*
|
||||
// CHECK: [[SEL:%.*]] = load i8*, i8** [[VALUE_SEL]]
|
||||
CGSize cg_size = { .width = 42, .height = 24 };
|
||||
// CHECK: call {{.*objc_msgSend.*}}(i8* noundef [[RECV]], i8* noundef [[SEL]], i8* noundef [[PARAM_CAST]], i8* noundef {{.*}}[[SIZE_STR]]{{.*}})
|
||||
NSValue *size = @(cg_size);
|
||||
|
@ -72,8 +72,8 @@ void doRect() {
|
|||
// CHECK: [[LOCAL_CAST:%.*]] = bitcast %struct.CGRect* [[LOCAL_VAR]]{{.*}}
|
||||
// CHECK: call void @llvm.memcpy{{.*}} [[TEMP_CAST]]{{.*}} [[LOCAL_CAST]]{{.*}}
|
||||
// CHECK: [[PARAM_CAST:%.*]] = bitcast %struct.CGRect* [[TEMP_VAR]]{{.*}}
|
||||
// CHECK: [[SEL:%.*]] = load i8*, i8** [[VALUE_SEL]]
|
||||
// CHECK: [[RECV:%.*]] = bitcast %struct._class_t* [[RECV_PTR]] to i8*
|
||||
// CHECK: [[SEL:%.*]] = load i8*, i8** [[VALUE_SEL]]
|
||||
CGPoint cg_point = { .x = 42, .y = 24 };
|
||||
CGSize cg_size = { .width = 42, .height = 24 };
|
||||
CGRect cg_rect = { .origin = cg_point, .size = cg_size };
|
||||
|
@ -91,8 +91,8 @@ void doNSEdgeInsets() {
|
|||
// CHECK: [[LOCAL_CAST:%.*]] = bitcast %struct.NSEdgeInsets* [[LOCAL_VAR]]{{.*}}
|
||||
// CHECK: call void @llvm.memcpy{{.*}} [[TEMP_CAST]]{{.*}} [[LOCAL_CAST]]{{.*}}
|
||||
// CHECK: [[PARAM_CAST:%.*]] = bitcast %struct.NSEdgeInsets* [[TEMP_VAR]]{{.*}}
|
||||
// CHECK: [[SEL:%.*]] = load i8*, i8** [[VALUE_SEL]]
|
||||
// CHECK: [[RECV:%.*]] = bitcast %struct._class_t* [[RECV_PTR]] to i8*
|
||||
// CHECK: [[SEL:%.*]] = load i8*, i8** [[VALUE_SEL]]
|
||||
NSEdgeInsets ns_edge_insets;
|
||||
// CHECK: call {{.*objc_msgSend.*}}(i8* noundef [[RECV]], i8* noundef [[SEL]], i8* noundef [[PARAM_CAST]], i8*{{.*}}[[EDGE_STR]]{{.*}})
|
||||
NSValue *edge_insets = @(ns_edge_insets);
|
||||
|
@ -105,8 +105,8 @@ void doRangeRValue() {
|
|||
// CHECK: [[RECV_PTR:%.*]] = load {{.*}} [[NSVALUE]]
|
||||
// CHECK: call {{.*}} @getRange {{.*}} [[COERCE]]{{.*}}
|
||||
// CHECK: [[COERCE_CAST:%.*]] = bitcast %struct._NSRange* [[COERCE]]{{.*}}
|
||||
// CHECK: [[SEL:%.*]] = load i8*, i8** [[VALUE_SEL]]
|
||||
// CHECK: [[RECV:%.*]] = bitcast %struct._class_t* [[RECV_PTR]] to i8*
|
||||
// CHECK: [[SEL:%.*]] = load i8*, i8** [[VALUE_SEL]]
|
||||
// CHECK: call {{.*objc_msgSend.*}}(i8* noundef [[RECV]], i8* noundef [[SEL]], i8* noundef [[COERCE_CAST]], i8* noundef {{.*}}[[RANGE_STR]]{{.*}})
|
||||
NSValue *range_rvalue = @(getRange());
|
||||
// CHECK: ret void
|
||||
|
|
|
@ -21,8 +21,8 @@ void doRange() {
|
|||
// CHECK: [[LOCAL_CAST:%.*]] = bitcast %struct._NSRange* [[LOCAL_VAR]]{{.*}}
|
||||
// CHECK: call void @llvm.memcpy{{.*}} [[TEMP_CAST]]{{.*}} [[LOCAL_CAST]]{{.*}}
|
||||
// CHECK: [[PARAM_CAST:%.*]] = bitcast %struct._NSRange* [[TEMP_VAR]]{{.*}}
|
||||
// CHECK: [[SEL:%.*]] = load i8*, i8** [[VALUE_SEL]]
|
||||
// CHECK: [[RECV:%.*]] = bitcast %struct._class_t* [[RECV_PTR]] to i8*
|
||||
// CHECK: [[SEL:%.*]] = load i8*, i8** [[VALUE_SEL]]
|
||||
NSRange ns_range = { .location = 0, .length = 42 };
|
||||
// CHECK: call {{.*objc_msgSend.*}}(i8* noundef [[RECV]], i8* noundef [[SEL]], i8* noundef [[PARAM_CAST]], i8* {{.*}}[[RANGE_STR]]{{.*}}) [ "clang.arc.attachedcall"(i8* (i8*)* @llvm.objc.retainAutoreleasedReturnValue) ]
|
||||
NSValue *range = @(ns_range);
|
||||
|
@ -39,8 +39,8 @@ void doPoint() {
|
|||
// CHECK: [[LOCAL_CAST:%.*]] = bitcast %struct._NSPoint* [[LOCAL_VAR]]{{.*}}
|
||||
// CHECK: call void @llvm.memcpy{{.*}} [[TEMP_CAST]]{{.*}} [[LOCAL_CAST]]{{.*}}
|
||||
// CHECK: [[PARAM_CAST:%.*]] = bitcast %struct._NSPoint* [[TEMP_VAR]]{{.*}}
|
||||
// CHECK: [[SEL:%.*]] = load i8*, i8** [[VALUE_SEL]]
|
||||
// CHECK: [[RECV:%.*]] = bitcast %struct._class_t* [[RECV_PTR]] to i8*
|
||||
// CHECK: [[SEL:%.*]] = load i8*, i8** [[VALUE_SEL]]
|
||||
NSPoint ns_point = { .x = 42, .y = 24 };
|
||||
// CHECK: call {{.*objc_msgSend.*}}(i8* noundef [[RECV]], i8* noundef [[SEL]], i8* noundef [[PARAM_CAST]], i8* {{.*}}[[POINT_STR]]{{.*}}) [ "clang.arc.attachedcall"(i8* (i8*)* @llvm.objc.retainAutoreleasedReturnValue) ]
|
||||
NSValue *point = @(ns_point);
|
||||
|
@ -57,8 +57,8 @@ void doSize() {
|
|||
// CHECK: [[LOCAL_CAST:%.*]] = bitcast %struct._NSSize* [[LOCAL_VAR]]{{.*}}
|
||||
// CHECK: call void @llvm.memcpy{{.*}} [[TEMP_CAST]]{{.*}} [[LOCAL_CAST]]{{.*}}
|
||||
// CHECK: [[PARAM_CAST:%.*]] = bitcast %struct._NSSize* [[TEMP_VAR]]{{.*}}
|
||||
// CHECK: [[SEL:%.*]] = load i8*, i8** [[VALUE_SEL]]
|
||||
// CHECK: [[RECV:%.*]] = bitcast %struct._class_t* [[RECV_PTR]] to i8*
|
||||
// CHECK: [[SEL:%.*]] = load i8*, i8** [[VALUE_SEL]]
|
||||
NSSize ns_size = { .width = 42, .height = 24 };
|
||||
// CHECK: call {{.*objc_msgSend.*}}(i8* noundef [[RECV]], i8* noundef [[SEL]], i8* noundef [[PARAM_CAST]], i8* {{.*}}[[SIZE_STR]]{{.*}}) [ "clang.arc.attachedcall"(i8* (i8*)* @llvm.objc.retainAutoreleasedReturnValue) ]
|
||||
NSValue *size = @(ns_size);
|
||||
|
@ -75,8 +75,8 @@ void doRect() {
|
|||
// CHECK: [[LOCAL_CAST:%.*]] = bitcast %struct._NSRect* [[LOCAL_VAR]]{{.*}}
|
||||
// CHECK: call void @llvm.memcpy{{.*}} [[TEMP_CAST]]{{.*}} [[LOCAL_CAST]]{{.*}}
|
||||
// CHECK: [[PARAM_CAST:%.*]] = bitcast %struct._NSRect* [[TEMP_VAR]]{{.*}}
|
||||
// CHECK: [[SEL:%.*]] = load i8*, i8** [[VALUE_SEL]]
|
||||
// CHECK: [[RECV:%.*]] = bitcast %struct._class_t* [[RECV_PTR]] to i8*
|
||||
// CHECK: [[SEL:%.*]] = load i8*, i8** [[VALUE_SEL]]
|
||||
NSPoint ns_point = { .x = 42, .y = 24 };
|
||||
NSSize ns_size = { .width = 42, .height = 24 };
|
||||
NSRect ns_rect = { .origin = ns_point, .size = ns_size };
|
||||
|
@ -95,8 +95,8 @@ void doNSEdgeInsets() {
|
|||
// CHECK: [[LOCAL_CAST:%.*]] = bitcast %struct.NSEdgeInsets* [[LOCAL_VAR]]{{.*}}
|
||||
// CHECK: call void @llvm.memcpy{{.*}} [[TEMP_CAST]]{{.*}} [[LOCAL_CAST]]{{.*}}
|
||||
// CHECK: [[PARAM_CAST:%.*]] = bitcast %struct.NSEdgeInsets* [[TEMP_VAR]]{{.*}}
|
||||
// CHECK: [[SEL:%.*]] = load i8*, i8** [[VALUE_SEL]]
|
||||
// CHECK: [[RECV:%.*]] = bitcast %struct._class_t* [[RECV_PTR]] to i8*
|
||||
// CHECK: [[SEL:%.*]] = load i8*, i8** [[VALUE_SEL]]
|
||||
NSEdgeInsets ns_edge_insets;
|
||||
// CHECK: call {{.*objc_msgSend.*}}(i8* noundef [[RECV]], i8* noundef [[SEL]], i8* noundef [[PARAM_CAST]], i8*{{.*}}[[EDGE_STR]]{{.*}}) [ "clang.arc.attachedcall"(i8* (i8*)* @llvm.objc.retainAutoreleasedReturnValue) ]
|
||||
NSValue *edge_insets = @(ns_edge_insets);
|
||||
|
@ -114,8 +114,8 @@ void doRangeRValue() {
|
|||
// CHECK: [[EXTR_RVAL:%.*]] = extractvalue {{.*}} [[RVAL]]{{.*}}
|
||||
// CHECK: store {{.*}}[[EXTR_RVAL]]{{.*}}[[COERCE_CAST_PTR]]{{.*}}
|
||||
// CHECK: [[COERCE_CAST:%.*]] = bitcast %struct._NSRange* [[COERCE]]{{.*}}
|
||||
// CHECK: [[SEL:%.*]] = load i8*, i8** [[VALUE_SEL]]
|
||||
// CHECK: [[RECV:%.*]] = bitcast %struct._class_t* [[RECV_PTR]] to i8*
|
||||
// CHECK: [[SEL:%.*]] = load i8*, i8** [[VALUE_SEL]]
|
||||
// CHECK: call {{.*objc_msgSend.*}}(i8* noundef [[RECV]], i8* noundef [[SEL]], i8* noundef [[COERCE_CAST]], i8* {{.*}}[[RANGE_STR]]{{.*}}) [ "clang.arc.attachedcall"(i8* (i8*)* @llvm.objc.retainAutoreleasedReturnValue) ]
|
||||
NSValue *range_rvalue = @(getRange());
|
||||
// CHECK: call void @llvm.objc.release
|
||||
|
|
|
@ -21,8 +21,8 @@ void doRange() {
|
|||
// CHECK: [[LOCAL_CAST:%.*]] = bitcast %struct._NSRange* [[LOCAL_VAR]]{{.*}}
|
||||
// CHECK: call void @llvm.memcpy{{.*}} [[TEMP_CAST]]{{.*}} [[LOCAL_CAST]]{{.*}}
|
||||
// CHECK: [[PARAM_CAST:%.*]] = bitcast %struct._NSRange* [[TEMP_VAR]]{{.*}}
|
||||
// CHECK: [[SEL:%.*]] = load i8*, i8** [[VALUE_SEL]]
|
||||
// CHECK: [[RECV:%.*]] = bitcast %struct._class_t* [[RECV_PTR]] to i8*
|
||||
// CHECK: [[SEL:%.*]] = load i8*, i8** [[VALUE_SEL]]
|
||||
NSRange ns_range = { .location = 0, .length = 42 };
|
||||
// CHECK: call {{.*objc_msgSend.*}}(i8* noundef [[RECV]], i8* noundef [[SEL]], i8* noundef [[PARAM_CAST]], i8* noundef {{.*}}[[RANGE_STR]]{{.*}})
|
||||
NSValue *range = @(ns_range);
|
||||
|
@ -38,8 +38,8 @@ void doPoint() {
|
|||
// CHECK: [[LOCAL_CAST:%.*]] = bitcast %struct._NSPoint* [[LOCAL_VAR]]{{.*}}
|
||||
// CHECK: call void @llvm.memcpy{{.*}} [[TEMP_CAST]]{{.*}} [[LOCAL_CAST]]{{.*}}
|
||||
// CHECK: [[PARAM_CAST:%.*]] = bitcast %struct._NSPoint* [[TEMP_VAR]]{{.*}}
|
||||
// CHECK: [[SEL:%.*]] = load i8*, i8** [[VALUE_SEL]]
|
||||
// CHECK: [[RECV:%.*]] = bitcast %struct._class_t* [[RECV_PTR]] to i8*
|
||||
// CHECK: [[SEL:%.*]] = load i8*, i8** [[VALUE_SEL]]
|
||||
NSPoint ns_point = { .x = 42, .y = 24 };
|
||||
// CHECK: call {{.*objc_msgSend.*}}(i8* noundef [[RECV]], i8* noundef [[SEL]], i8* noundef [[PARAM_CAST]], i8* noundef {{.*}}[[POINT_STR]]{{.*}})
|
||||
NSValue *point = @(ns_point);
|
||||
|
@ -55,8 +55,8 @@ void doSize() {
|
|||
// CHECK: [[LOCAL_CAST:%.*]] = bitcast %struct._NSSize* [[LOCAL_VAR]]{{.*}}
|
||||
// CHECK: call void @llvm.memcpy{{.*}} [[TEMP_CAST]]{{.*}} [[LOCAL_CAST]]{{.*}}
|
||||
// CHECK: [[PARAM_CAST:%.*]] = bitcast %struct._NSSize* [[TEMP_VAR]]{{.*}}
|
||||
// CHECK: [[SEL:%.*]] = load i8*, i8** [[VALUE_SEL]]
|
||||
// CHECK: [[RECV:%.*]] = bitcast %struct._class_t* [[RECV_PTR]] to i8*
|
||||
// CHECK: [[SEL:%.*]] = load i8*, i8** [[VALUE_SEL]]
|
||||
NSSize ns_size = { .width = 42, .height = 24 };
|
||||
// CHECK: call {{.*objc_msgSend.*}}(i8* noundef [[RECV]], i8* noundef [[SEL]], i8* noundef [[PARAM_CAST]], i8* noundef {{.*}}[[SIZE_STR]]{{.*}})
|
||||
NSValue *size = @(ns_size);
|
||||
|
@ -72,8 +72,8 @@ void doRect() {
|
|||
// CHECK: [[LOCAL_CAST:%.*]] = bitcast %struct._NSRect* [[LOCAL_VAR]]{{.*}}
|
||||
// CHECK: call void @llvm.memcpy{{.*}} [[TEMP_CAST]]{{.*}} [[LOCAL_CAST]]{{.*}}
|
||||
// CHECK: [[PARAM_CAST:%.*]] = bitcast %struct._NSRect* [[TEMP_VAR]]{{.*}}
|
||||
// CHECK: [[SEL:%.*]] = load i8*, i8** [[VALUE_SEL]]
|
||||
// CHECK: [[RECV:%.*]] = bitcast %struct._class_t* [[RECV_PTR]] to i8*
|
||||
// CHECK: [[SEL:%.*]] = load i8*, i8** [[VALUE_SEL]]
|
||||
NSPoint ns_point = { .x = 42, .y = 24 };
|
||||
NSSize ns_size = { .width = 42, .height = 24 };
|
||||
NSRect ns_rect = { .origin = ns_point, .size = ns_size };
|
||||
|
@ -91,8 +91,8 @@ void doNSEdgeInsets() {
|
|||
// CHECK: [[LOCAL_CAST:%.*]] = bitcast %struct.NSEdgeInsets* [[LOCAL_VAR]]{{.*}}
|
||||
// CHECK: call void @llvm.memcpy{{.*}} [[TEMP_CAST]]{{.*}} [[LOCAL_CAST]]{{.*}}
|
||||
// CHECK: [[PARAM_CAST:%.*]] = bitcast %struct.NSEdgeInsets* [[TEMP_VAR]]{{.*}}
|
||||
// CHECK: [[SEL:%.*]] = load i8*, i8** [[VALUE_SEL]]
|
||||
// CHECK: [[RECV:%.*]] = bitcast %struct._class_t* [[RECV_PTR]] to i8*
|
||||
// CHECK: [[SEL:%.*]] = load i8*, i8** [[VALUE_SEL]]
|
||||
NSEdgeInsets ns_edge_insets;
|
||||
// CHECK: call {{.*objc_msgSend.*}}(i8* noundef [[RECV]], i8* noundef [[SEL]], i8* noundef [[PARAM_CAST]], i8*{{.*}}[[EDGE_STR]]{{.*}})
|
||||
NSValue *edge_insets = @(ns_edge_insets);
|
||||
|
@ -109,8 +109,8 @@ void doRangeRValue() {
|
|||
// CHECK: [[EXTR_RVAL:%.*]] = extractvalue {{.*}} [[RVAL]]{{.*}}
|
||||
// CHECK: store {{.*}}[[EXTR_RVAL]]{{.*}}[[COERCE_CAST_PTR]]{{.*}}
|
||||
// CHECK: [[COERCE_CAST:%.*]] = bitcast %struct._NSRange* [[COERCE]]{{.*}}
|
||||
// CHECK: [[SEL:%.*]] = load i8*, i8** [[VALUE_SEL]]
|
||||
// CHECK: [[RECV:%.*]] = bitcast %struct._class_t* [[RECV_PTR]] to i8*
|
||||
// CHECK: [[SEL:%.*]] = load i8*, i8** [[VALUE_SEL]]
|
||||
// CHECK: call {{.*objc_msgSend.*}}(i8* noundef [[RECV]], i8* noundef [[SEL]], i8* noundef [[COERCE_CAST]], i8* noundef {{.*}}[[RANGE_STR]]{{.*}})
|
||||
NSValue *range_rvalue = @(getRange());
|
||||
// CHECK: ret void
|
||||
|
|
|
@ -19,16 +19,16 @@ int main() {
|
|||
|
||||
id oldObject = array[10];
|
||||
// CHECK: [[ARR:%.*]] = load {{%.*}} [[array:%.*]], align 8
|
||||
// CHECK-NEXT: [[SEL:%.*]] = load i8*, i8** @OBJC_SELECTOR_REFERENCES_
|
||||
// CHECK-NEXT: [[ARRC:%.*]] = bitcast {{%.*}} [[ARR]] to i8*
|
||||
// CHECK-NEXT: [[SEL:%.*]] = load i8*, i8** @OBJC_SELECTOR_REFERENCES_
|
||||
// CHECK-NEXT: [[CALL:%.*]] = call i8* bitcast (i8* (i8*, i8*, ...)* @objc_msgSend to i8* (i8*, i8*, i32)*)(i8* noundef [[ARRC]], i8* noundef [[SEL]], i32 noundef 10)
|
||||
// CHECK-NEXT: store i8* [[CALL]], i8** [[OLDOBJ:%.*]], align 8
|
||||
|
||||
val = (array[10] = oldObject);
|
||||
// CHECK: [[FOUR:%.*]] = load i8*, i8** [[oldObject:%.*]], align 8
|
||||
// CHECK-NEXT: [[THREE:%.*]] = load {{%.*}} [[array:%.*]], align 8
|
||||
// CHECK-NEXT: [[FIVE:%.*]] = load i8*, i8** @OBJC_SELECTOR_REFERENCES_.2
|
||||
// CHECK-NEXT: [[SIX:%.*]] = bitcast {{%.*}} [[THREE]] to i8*
|
||||
// CHECK-NEXT: [[FIVE:%.*]] = load i8*, i8** @OBJC_SELECTOR_REFERENCES_.2
|
||||
// CHECK-NEXT: call void bitcast (i8* (i8*, i8*, ...)* @objc_msgSend to void (i8*, i8*, i8*, i32)*)(i8* noundef [[SIX]], i8* noundef [[FIVE]], i8* noundef [[FOUR]], i32 noundef 10)
|
||||
// CHECK-NEXT: store i8* [[FOUR]], i8** [[val:%.*]]
|
||||
|
||||
|
@ -38,8 +38,8 @@ int main() {
|
|||
oldObject = dictionary[key];
|
||||
// CHECK: [[SEVEN:%.*]] = load {{%.*}} [[DICTIONARY:%.*]], align 8
|
||||
// CHECK-NEXT: [[EIGHT:%.*]] = load i8*, i8** [[KEY:%.*]], align 8
|
||||
// CHECK-NEXT: [[TEN:%.*]] = load i8*, i8** @OBJC_SELECTOR_REFERENCES_.4
|
||||
// CHECK-NEXT: [[ELEVEN:%.*]] = bitcast {{%.*}} [[SEVEN]] to i8*
|
||||
// CHECK-NEXT: [[TEN:%.*]] = load i8*, i8** @OBJC_SELECTOR_REFERENCES_.4
|
||||
// CHECK-NEXT: [[CALL1:%.*]] = call i8* bitcast (i8* (i8*, i8*, ...)* @objc_msgSend to i8* (i8*, i8*, i8*)*)(i8* noundef [[ELEVEN]], i8* noundef [[TEN]], i8* noundef [[EIGHT]])
|
||||
// CHECK-NEXT: store i8* [[CALL1]], i8** [[oldObject:%.*]], align 8
|
||||
|
||||
|
@ -48,8 +48,8 @@ int main() {
|
|||
// CHECK: [[FOURTEEN:%.*]] = load i8*, i8** [[NEWOBJECT:%.*]], align 8
|
||||
// CHECK-NEXT: [[TWELVE:%.*]] = load {{%.*}} [[DICTIONARY]], align 8
|
||||
// CHECK-NEXT: [[THIRTEEN:%.*]] = load i8*, i8** [[KEY]], align 8
|
||||
// CHECK-NEXT: [[SIXTEEN:%.*]] = load i8*, i8** @OBJC_SELECTOR_REFERENCES_.6
|
||||
// CHECK-NEXT: [[SEVENTEEN:%.*]] = bitcast {{%.*}} [[TWELVE]] to i8*
|
||||
// CHECK-NEXT: [[SIXTEEN:%.*]] = load i8*, i8** @OBJC_SELECTOR_REFERENCES_.6
|
||||
// CHECK-NEXT: call void bitcast (i8* (i8*, i8*, ...)* @objc_msgSend to void (i8*, i8*, i8*, i8*)*)(i8* noundef [[SEVENTEEN]], i8* noundef [[SIXTEEN]], i8* noundef [[FOURTEEN]], i8* noundef [[THIRTEEN]])
|
||||
// CHECK-NEXT: store i8* [[FOURTEEN]], i8** [[val:%.*]]
|
||||
}
|
||||
|
|
|
@ -58,22 +58,22 @@ int printf(const char *, ...);
|
|||
A *test2_helper(void);
|
||||
void test2() {
|
||||
// CHECK: [[BASE:%.*]] = call [[A:%.*]]* @test2_helper()
|
||||
// CHECK-NEXT: [[SEL:%.*]] = load i8*, i8**
|
||||
// CHECK-NEXT: [[BASETMP:%.*]] = bitcast [[A]]* [[BASE]] to i8*
|
||||
// CHECK-NEXT: [[SEL:%.*]] = load i8*, i8**
|
||||
// CHECK-NEXT: [[LD:%.*]] = call i32 bitcast (i8* (i8*, i8*, ...)* @objc_msgSend to i32 (i8*, i8*)*)(i8* noundef [[BASETMP]], i8* noundef [[SEL]])
|
||||
// CHECK-NEXT: [[ADD:%.*]] = add nsw i32 [[LD]], 1
|
||||
// CHECK-NEXT: [[SEL:%.*]] = load i8*, i8**
|
||||
// CHECK-NEXT: [[BASETMP:%.*]] = bitcast [[A]]* [[BASE]] to i8*
|
||||
// CHECK-NEXT: [[SEL:%.*]] = load i8*, i8**
|
||||
// CHECK-NEXT: call void bitcast (i8* (i8*, i8*, ...)* @objc_msgSend to void (i8*, i8*, i32)*)(i8* noundef [[BASETMP]], i8* noundef [[SEL]], i32 noundef [[ADD]])
|
||||
test2_helper().dyn++;
|
||||
|
||||
// CHECK: [[BASE:%.*]] = call [[A]]* @test2_helper()
|
||||
// CHECK-NEXT: [[SEL:%.*]] = load i8*, i8**
|
||||
// CHECK-NEXT: [[BASETMP:%.*]] = bitcast [[A]]* [[BASE]] to i8*
|
||||
// CHECK-NEXT: [[SEL:%.*]] = load i8*, i8**
|
||||
// CHECK-NEXT: [[LD:%.*]] = call i32 bitcast (i8* (i8*, i8*, ...)* @objc_msgSend to i32 (i8*, i8*)*)(i8* noundef [[BASETMP]], i8* noundef [[SEL]])
|
||||
// CHECK-NEXT: [[ADD:%.*]] = mul nsw i32 [[LD]], 10
|
||||
// CHECK-NEXT: [[SEL:%.*]] = load i8*, i8**
|
||||
// CHECK-NEXT: [[BASETMP:%.*]] = bitcast [[A]]* [[BASE]] to i8*
|
||||
// CHECK-NEXT: [[SEL:%.*]] = load i8*, i8**
|
||||
// CHECK-NEXT: call void bitcast (i8* (i8*, i8*, ...)* @objc_msgSend to void (i8*, i8*, i32)*)(i8* noundef [[BASETMP]], i8* noundef [[SEL]], i32 noundef [[ADD]])
|
||||
test2_helper().dyn *= 10;
|
||||
}
|
||||
|
@ -136,33 +136,33 @@ void test7(Test7 *t) {
|
|||
// CHECK: [[T:%.*]] = alloca [[TEST7]]*,
|
||||
// CHECK-NEXT: store
|
||||
// CHECK-NEXT: [[T0:%.*]] = load [[TEST7]]*, [[TEST7]]** [[T]], align
|
||||
// CHECK-NEXT: load i8*, i8** @OBJC_SELECTOR_REFERENCES
|
||||
// CHECK-NEXT: [[T1:%.*]] = bitcast [[TEST7]]* [[T0]] to i8*
|
||||
// CHECK-NEXT: load i8*, i8** @OBJC_SELECTOR_REFERENCES
|
||||
// CHECK-NEXT: [[T2:%.*]] = call zeroext i8 bitcast
|
||||
// CHECK-NEXT: [[T3:%.*]] = zext i8 [[T2]] to i32
|
||||
// CHECK-NEXT: [[T4:%.*]] = and i32 [[T3]], 2
|
||||
// CHECK-NEXT: [[T5:%.*]] = trunc i32 [[T4]] to i8
|
||||
// CHECK-NEXT: load i8*, i8** @OBJC_SELECTOR_REFERENCES
|
||||
// CHECK-NEXT: [[T6:%.*]] = bitcast [[TEST7]]* [[T0]] to i8*
|
||||
// CHECK-NEXT: load i8*, i8** @OBJC_SELECTOR_REFERENCES
|
||||
// CHECK-NEXT: call void bitcast
|
||||
// CHECK-NEXT: [[T0:%.*]] = load [[TEST7]]*, [[TEST7]]** [[T]], align
|
||||
// CHECK-NEXT: load i8*, i8** @OBJC_SELECTOR_REFERENCES
|
||||
// CHECK-NEXT: [[T1:%.*]] = bitcast [[TEST7]]* [[T0]] to i8*
|
||||
// CHECK-NEXT: load i8*, i8** @OBJC_SELECTOR_REFERENCES
|
||||
// CHECK-NEXT: [[T2:%.*]] = call zeroext i8 bitcast
|
||||
// CHECK-NEXT: [[T3:%.*]] = zext i8 [[T2]] to i32
|
||||
// CHECK-NEXT: [[T4:%.*]] = or i32 [[T3]], 5
|
||||
// CHECK-NEXT: [[T5:%.*]] = trunc i32 [[T4]] to i8
|
||||
// CHECK-NEXT: load i8*, i8** @OBJC_SELECTOR_REFERENCES
|
||||
// CHECK-NEXT: [[T6:%.*]] = bitcast [[TEST7]]* [[T0]] to i8*
|
||||
// CHECK-NEXT: load i8*, i8** @OBJC_SELECTOR_REFERENCES
|
||||
// CHECK-NEXT: call void bitcast
|
||||
// CHECK-NEXT: [[T0:%.*]] = load [[TEST7]]*, [[TEST7]]** [[T]], align
|
||||
// CHECK-NEXT: load i8*, i8** @OBJC_SELECTOR_REFERENCES
|
||||
// CHECK-NEXT: [[T1:%.*]] = bitcast [[TEST7]]* [[T0]] to i8*
|
||||
// CHECK-NEXT: load i8*, i8** @OBJC_SELECTOR_REFERENCES
|
||||
// CHECK-NEXT: [[T2:%.*]] = call zeroext i8 bitcast
|
||||
// CHECK-NEXT: [[T3:%.*]] = zext i8 [[T2]] to i32
|
||||
// CHECK-NEXT: [[T4:%.*]] = xor i32 [[T3]], 8
|
||||
// CHECK-NEXT: [[T5:%.*]] = trunc i32 [[T4]] to i8
|
||||
// CHECK-NEXT: load i8*, i8** @OBJC_SELECTOR_REFERENCES
|
||||
// CHECK-NEXT: [[T6:%.*]] = bitcast [[TEST7]]* [[T0]] to i8*
|
||||
// CHECK-NEXT: load i8*, i8** @OBJC_SELECTOR_REFERENCES
|
||||
// CHECK-NEXT: call void bitcast
|
||||
// CHECK-NEXT: ret void
|
||||
|
|
|
@ -36,7 +36,7 @@ static inline void _inlineFunction() {
|
|||
|
||||
// CHECK-LABEL: define internal void @_inlineFunction()
|
||||
// CHECK: [[ZERO:%.*]] = load %struct._class_t*, %struct._class_t** @"OBJC_CLASSLIST_REFERENCES_
|
||||
// CHECK-NEXT: [[ONE:%.*]] = load i8*, i8** @OBJC_SELECTOR_REFERENCES_
|
||||
// CHECK-NEXT: [[TWO:%.*]] = bitcast %struct._class_t* [[ZERO]] to i8*
|
||||
// CHECK-NEXT: call void (i8*, i8*, [[T:%.*]]*, ...) bitcast (i8* (i8*, i8*, ...)* @objc_msgSend to void (i8*, i8*, [[T:%.*]]*, ...)*)(i8* noundef [[TWO]], i8* noundef [[ONE]], [[T:%.*]]* noundef bitcast (%struct.__NSConstantString_tag* @_unnamed_cfstring_{{.*}} to [[T:%.*]]*))
|
||||
// CHECK-NEXT: [[OBJ:%.*]] = bitcast %struct._class_t* [[ZERO]] to i8*
|
||||
// CHECK-NEXT: [[SEL:%.*]] = load i8*, i8** @OBJC_SELECTOR_REFERENCES_
|
||||
// CHECK-NEXT: call void (i8*, i8*, [[T:%.*]]*, ...) bitcast (i8* (i8*, i8*, ...)* @objc_msgSend to void (i8*, i8*, [[T:%.*]]*, ...)*)(i8* noundef [[OBJ]], i8* noundef [[SEL]], [[T:%.*]]* noundef bitcast (%struct.__NSConstantString_tag* @_unnamed_cfstring_{{.*}} to [[T:%.*]]*))
|
||||
// CHECK-NEXT: ret void
|
||||
|
|
|
@ -23,10 +23,10 @@ class XClipboardDataSet
|
|||
@end
|
||||
|
||||
// CHECK: [[mClipData:%.*]] = getelementptr inbounds %class.XClipboardDataSet, %class.XClipboardDataSet*
|
||||
// CHECK: [[ZERO:%.*]] = load %struct._class_t*, %struct._class_t** @"OBJC_CLASSLIST_REFERENCES_$_"
|
||||
// CHECK: [[ONE:%.*]] = load i8*, i8** @OBJC_SELECTOR_REFERENCES_
|
||||
// CHECK: [[TWO:%.*]] = bitcast %struct._class_t* [[ZERO]] to i8*
|
||||
// CHECK: [[CALL:%.*]] = call noundef i8* bitcast (i8* (i8*, i8*, ...)* @objc_msgSend to i8* (i8*, i8*)*)(i8* noundef [[TWO]], i8* noundef [[ONE]])
|
||||
// CHECK: [[CLS:%.*]] = load %struct._class_t*, %struct._class_t** @"OBJC_CLASSLIST_REFERENCES_$_"
|
||||
// CHECK: [[RECV:%.*]] = bitcast %struct._class_t* [[CLS]] to i8*
|
||||
// CHECK: [[SEL:%.*]] = load i8*, i8** @OBJC_SELECTOR_REFERENCES_
|
||||
// CHECK: [[CALL:%.*]] = call noundef i8* bitcast (i8* (i8*, i8*, ...)* @objc_msgSend to i8* (i8*, i8*)*)(i8* noundef [[RECV]], i8* noundef [[SEL]])
|
||||
// CHECK: [[THREE:%.*]] = bitcast i8* [[CALL]] to [[T:%.*]]*
|
||||
// CHECK: store [[T]]* [[THREE]], [[T]]** [[mClipData]], align 8
|
||||
|
||||
|
|
|
@ -221,8 +221,8 @@ template void test37<Test37>(Test37 *a);
|
|||
// CHECK-NEXT: call void (...) @llvm.objc.clang.arc.noop.use({{.*}} [[T2]])
|
||||
|
||||
// Make sure it's not immediately released before starting the iteration.
|
||||
// CHECK-NEXT: load i8*, i8** @OBJC_SELECTOR_REFERENCES_
|
||||
// CHECK-NEXT: [[T0:%.*]] = bitcast [[NSARRAY]]* [[T2]] to i8*
|
||||
// CHECK-NEXT: load i8*, i8** @OBJC_SELECTOR_REFERENCES_
|
||||
// CHECK-NEXT: @objc_msgSend
|
||||
|
||||
// This bitcast is for the mutation check.
|
||||
|
@ -231,6 +231,7 @@ template void test37<Test37>(Test37 *a);
|
|||
|
||||
// This bitcast is for the 'next' message send.
|
||||
// CHECK: [[T0:%.*]] = bitcast [[NSARRAY]]* [[T2]] to i8*
|
||||
// CHECK-NEXT: load i8*, i8** @OBJC_SELECTOR_REFERENCES_
|
||||
// CHECK-NEXT: @objc_msgSend
|
||||
|
||||
// This bitcast is for the final release.
|
||||
|
|
|
@ -17,8 +17,8 @@ namespace test0 {
|
|||
template void foo<int>();
|
||||
// CHECK-LABEL: define weak_odr void @_ZN5test03fooIiEEvv()
|
||||
// CHECK: [[T0:%.*]] = call noundef [[TEST0:%.*]]* @_ZN5test01AcvP5Test0Ev(
|
||||
// CHECK-NEXT: [[T1:%.*]] = load i8*, i8**
|
||||
// CHECK-NEXT: [[T2:%.*]] = bitcast [[TEST0]]* [[T0]] to i8*
|
||||
// CHECK-NEXT: [[T1:%.*]] = load i8*, i8**
|
||||
// CHECK-NEXT: call void bitcast (i8* (i8*, i8*, ...)* @objc_msgSend to void (i8*, i8*)*)(i8* noundef [[T2]], i8* noundef [[T1]])
|
||||
// CHECK-NEXT: ret void
|
||||
}
|
||||
|
|
|
@ -24,12 +24,12 @@ typedef Quad2<double> Quad2d;
|
|||
}
|
||||
@end
|
||||
|
||||
// CHECK: [[TWO:%.*]] = load i8*, i8** @OBJC_SELECTOR_REFERENCES_, align 8, !invariant.load ![[MD_NUM:[0-9]+]]
|
||||
// CHECK: [[THREE:%.*]] = bitcast [[ONET:%.*]]* [[ONE:%.*]] to i8*
|
||||
// CHECK: [[CALL:%.*]] = call noundef nonnull align 1 %struct.Quad2* bitcast (i8* (i8*, i8*, ...)* @objc_msgSend to %struct.Quad2* (i8*, i8*)*)(i8* noundef [[THREE]], i8* noundef [[TWO]])
|
||||
// CHECK: [[FOUR:%.*]] = load i8*, i8** @OBJC_SELECTOR_REFERENCES_.2, align 8, !invariant.load ![[MD_NUM]]
|
||||
// CHECK: [[FIVE:%.*]] = bitcast [[ONET]]* [[ZERO:%.*]] to i8*
|
||||
// CHECK: call void bitcast (i8* (i8*, i8*, ...)* @objc_msgSend to void (i8*, i8*, %struct.Quad2*)*)(i8* noundef [[FIVE]], i8* noundef [[FOUR]], %struct.Quad2* noundef nonnull align 1 [[CALL]])
|
||||
// CHECK: [[OBJ:%.*]] = bitcast [[ONET:%.*]]* [[ONE:%.*]] to i8*
|
||||
// CHECK: [[SEL:%.*]] = load i8*, i8** @OBJC_SELECTOR_REFERENCES_, align 8, !invariant.load ![[MD_NUM:[0-9]+]]
|
||||
// CHECK: [[CALL:%.*]] = call noundef nonnull align 1 %struct.Quad2* bitcast (i8* (i8*, i8*, ...)* @objc_msgSend to %struct.Quad2* (i8*, i8*)*)(i8* noundef [[OBJ]], i8* noundef [[SEL]])
|
||||
// CHECK: [[OBJ2:%.*]] = bitcast [[ONET]]* [[ZERO:%.*]] to i8*
|
||||
// CHECK: [[SEL2:%.*]] = load i8*, i8** @OBJC_SELECTOR_REFERENCES_.2, align 8, !invariant.load ![[MD_NUM]]
|
||||
// CHECK: call void bitcast (i8* (i8*, i8*, ...)* @objc_msgSend to void (i8*, i8*, %struct.Quad2*)*)(i8* noundef [[OBJ2]], i8* noundef [[SEL2]], %struct.Quad2* noundef nonnull align 1 [[CALL]])
|
||||
|
||||
|
||||
struct A {
|
||||
|
@ -47,7 +47,7 @@ void test(C *c, const A &a) {
|
|||
}
|
||||
|
||||
// CHECK: [[ONE1:%.*]] = load %struct.A*, %struct.A** [[AADDR:%.*]], align 8
|
||||
// CHECK: [[TWO1:%.*]] = load i8*, i8** @OBJC_SELECTOR_REFERENCES_.5, align 8, !invariant.load ![[MD_NUM]]
|
||||
// CHECK: [[THREE1:%.*]] = bitcast [[TWOT:%.*]]* [[ZERO1:%.*]] to i8*
|
||||
// CHECK: call void bitcast (i8* (i8*, i8*, ...)* @objc_msgSend to void (i8*, i8*, %struct.A*)*)(i8* noundef [[THREE1]], i8* noundef [[TWO1]], %struct.A* noundef nonnull align {{[0-9]+}} dereferenceable({{[0-9]+}}) [[ONE1]])
|
||||
// CHECK: [[OBJ3:%.*]] = bitcast [[TWOT:%.*]]* [[ZERO1:%.*]] to i8*
|
||||
// CHECK: [[SEL3:%.*]] = load i8*, i8** @OBJC_SELECTOR_REFERENCES_.5, align 8, !invariant.load ![[MD_NUM]]
|
||||
// CHECK: call void bitcast (i8* (i8*, i8*, ...)* @objc_msgSend to void (i8*, i8*, %struct.A*)*)(i8* noundef [[OBJ3]], i8* noundef [[SEL3]], %struct.A* noundef nonnull align {{[0-9]+}} dereferenceable({{[0-9]+}}) [[ONE1]])
|
||||
// CHECK: store %struct.A* [[ONE1]], %struct.A** [[RESULT:%.*]], align 8
|
||||
|
|
|
@ -25,11 +25,11 @@ static Foo gFoo;
|
|||
@end
|
||||
|
||||
// CHECK: [[T0:%.*]] = load {{%.*}} [[S0:%.*]]
|
||||
// CHECK: load i8*, i8** @OBJC_SELECTOR_REFERENCES_
|
||||
// CHECK: [[T2:%.*]] = bitcast {{%.*}} [[T0]] to i8*
|
||||
// CHECK: load i8*, i8** @OBJC_SELECTOR_REFERENCES_
|
||||
// CHECK: @objc_msgSend
|
||||
// CHECK: [[R0:%.*]] = load {{%.*}} [[U0:%.*]]
|
||||
// CHECK: load i8*, i8** @OBJC_SELECTOR_REFERENCES_
|
||||
// CHECK: [[R2:%.*]] = bitcast {{%.*}} [[R0]] to i8*
|
||||
// CHECK: load i8*, i8** @OBJC_SELECTOR_REFERENCES_
|
||||
// CHECK: @objc_msgSend
|
||||
|
||||
|
|
Loading…
Reference in New Issue