> On Oct 13, 2017, at 6:05 PM, Peter Collingbourne <pe...@pcc.me.uk> wrote: > > > > On Fri, Oct 13, 2017 at 5:59 PM, Vedant Kumar <v...@apple.com > <mailto:v...@apple.com>> wrote: > >> On Oct 13, 2017, at 4:33 PM, Peter Collingbourne <pe...@pcc.me.uk >> <mailto:pe...@pcc.me.uk>> wrote: >> >> >> >> On Fri, Oct 13, 2017 at 4:19 PM, Vedant Kumar <v...@apple.com >> <mailto:v...@apple.com>> wrote: >> >>> On Oct 13, 2017, at 4:08 PM, Peter Collingbourne <pe...@pcc.me.uk >>> <mailto:pe...@pcc.me.uk>> wrote: >>> >>> On Fri, Oct 13, 2017 at 4:06 PM, Peter Collingbourne <pe...@pcc.me.uk >>> <mailto:pe...@pcc.me.uk>> wrote: >>> Here's a small reproducer. >>> >>> struct A { >>> virtual void f(...); >>> }; >>> >>> struct B : virtual A { >>> virtual void b(); >>> virtual void f(...); >>> }; >>> >>> void B::f(...) {} >>> >>> $ clang++ -fsanitize=function fsan.cpp -ffunction-sections -fdata-sections >>> -c -o /dev/null >>> fatal error: error in backend: Cannot represent a difference across sections >>> >>> Looking at the IR I see this function definition: >>> define void @_ZTv0_n24_N1B1fEz(%struct.B* %this, ...) unnamed_addr #0 align >>> 2 prologue <{ i32, i32 }> <{ i32 846595819, i32 trunc (i64 sub (i64 >>> ptrtoint (i8** @0 to i64), i64 ptrtoint (void (%struct.B*, ...)* @_ZN1B1fEz >>> to i64)) to i32) }> { >>> which appears to cause the error. >>> >>> I get basically the same IR if I use a Darwin target triple, so this isn't >>> a Linux-specific issue. (On Darwin we end up successfully creating an >>> object file, but the embedded offset in the text section will presumably be >>> incorrect.) >>> >>> Note that we're emitting prologue data on virtual functions, which is >>> unnecessary because -fsanitize=function only checks indirect calls via >>> function pointers. So I imagine that one way to solve the problem would be >>> to turn off prologue data emission on non-virtual functions. >>> >>> Sorry, I meant "limit prologue data emission to non-virtual functions". >> >> That's independently a great idea :). >> >> I don't see a problem in the IR you've showed above, however. Why do you >> expect the embedded offset to be incorrect? This program links and runs fine >> on Darwin: >> >> --- >> struct A { >> virtual void f(...) {} >> }; >> >> struct B : virtual A { >> virtual void b() {} >> virtual void f(...); >> }; >> >> void B::f(...) {} >> >> int main() { >> A a; >> a.f(); >> >> B b; >> b.f(); >> b.b(); >> return 0; >> } >> --- >> >> The "Cannot represent difference..." error appears limited to ELF and Wasm, >> afaik. >> >> In order to find the RTTI data for a function, the generated code will add >> the embedded offset to the function's address in order to find the global >> that contains the pointer to the RTTI data. So if we were to compute the >> address of _ZTv0_n24_N1B1fEz's global, we would compute the value: >> _ZTv0_n24_N1B1fEz + (@0 -_ZN1B1fEz) >> which, of course, will not yield the address of @0. >> >> I would certainly expect your program to run correctly because we do not try >> to interpret the prologue data when calling a virtual function, so the >> incorrectness of the offset has no effect on the program's execution. > > Thanks for explaining. I am still confused on one point. > > Calling a function pointer to a virtual member doesn't seem to trigger a > UBSan type check. I can see why "_ZTv0_n24_N1B1fEz + (@0 -_ZN1B1fEz)" doesn't > make sense, but I don't know how we'd ever get there. Consider: > > --- > class A { > public: > virtual int f() = 0; > }; > > class B : public A { > int f() { return 42; } > }; > > struct C { > void g() {} > static void h() {} > }; > > int main() { > auto h = &C::h; > h(); // type checked > > C c; > void (C::*g)() = &C::g; > (c.*g)(); // not checked > > int (A::*f)() = &A::f; > A *a = new B; > return (a->*f)(); // not checked > } > --- > > So, I'm not sure how we would get into a situation where we compute > "_ZTv0_n24_N1B1fEz + (@0 -_ZN1B1fEz)". > > Right, my point was that we wouldn't get into such a situation. I'm sorry if > I was unclear.
Oh, in that case were you suggesting that simply storing "(@0 -_ZN1B1fEz)" in the prologue for _ZTv0_n24_N1B1fEz would cause the backend error ("Cannot represent a difference...")? Sorry, I haven't fully worked out the root cause of that failure. > > In the last code example I posted, there are also no calls to the function > type check handler. > > At any rate, I implemented your idea to not emit signatures for virtual > methods: > https://reviews.llvm.org/D38913 <https://reviews.llvm.org/D38913> > > It's at least good for a code size savings, and it might fix the issue Eric > and Han are seeing. I'd appreciate any feedback. > > Thanks, I will take a look. Thanks for the review! vedant > > Peter > > > thanks, > vedant > > >> >> Peter >> >> >> vedant >> >>> >>> Peter >>> >>> On Fri, Oct 13, 2017 at 3:06 PM, Vedant Kumar <v...@apple.com >>> <mailto:v...@apple.com>> wrote: >>> >>>> On Oct 13, 2017, at 2:52 PM, Eric Christopher <echri...@gmail.com >>>> <mailto:echri...@gmail.com>> wrote: >>>> >>>> >>>> >>>> On Fri, Oct 13, 2017 at 2:50 PM Vedant Kumar <v...@apple.com >>>> <mailto:v...@apple.com>> wrote: >>>>> On Oct 13, 2017, at 1:44 PM, Eric Christopher <echri...@gmail.com >>>>> <mailto:echri...@gmail.com>> wrote: >>>>> >>>>> >>>>> >>>>> On Fri, Oct 13, 2017 at 1:42 PM Vedant Kumar <v...@apple.com >>>>> <mailto:v...@apple.com>> wrote: >>>>>> On Oct 13, 2017, at 1:39 PM, Vedant Kumar <v...@apple.com >>>>>> <mailto:v...@apple.com>> wrote: >>>>>> >>>>>> Hey Eric, >>>>>> >>>>>> I'm sorry for the breakage. I made sure to check the run-time tests in >>>>>> compiler-rt but we could have missing coverage there. >>>>>> >>>>>> The original version of this patch restricted the prologue data changes >>>>>> to Darwin only. We can switch back to that easily, just let me know. >>>>> >>>>> Actually I'll go ahead and work a patch up. >>>>> >>>>> >>>>> Appreciated :) >>>>> >>>>> Basically we were getting an error of: >>>>> >>>>> error: Cannot represent a difference across sections >>>>> >>>>> trying to compile things with the current code. >>>> >>>> Oh I see.. well, we started using a difference between the address of a >>>> function and the address of a global, so the error makes sense. >>>> >>>> I'd be interested in any factors that could narrow the problem down (e.g >>>> using a specific linker, using -ffunction-sections, using data-sections, >>>> etc). Basically I'm not sure why this would work on some Linux setups but >>>> not others. >>>> >>>> >>>> Definitely using the latter two options and gold as a linker. I'll see >>>> what Han can come up with. >>> >>> Gotcha. Well, -ffunction-sections appears to be untested in >>> compiler-rt/test/ubsan, at least. >>> >>> There's a test somewhere in there called function.cpp -- it would be great >>> if we could cover the *-sections options there. I'm not sure whether that's >>> what caused the failure, but the extra coverage couldn't hurt :). I would >>> do it myself but I don't have a Linux machine to test on. >>> >>> vedant >>> >>>> >>>> While we figure that out here's a patch to limit the impact on non-Darwin >>>> platforms: >>>> https://reviews.llvm.org/D38903 <https://reviews.llvm.org/D38903> >>>> >>>> *goes a looking* >>>> >>>> Thanks! >>>> >>>> -eric >>>> >>>> vedant >>>> >>>>> >>>>> Thanks! >>>>> >>>>> -eric >>>>> >>>>> vedant >>>>> >>>>>> >>>>>> vedant >>>>>> >>>>>> >>>>>>> On Oct 13, 2017, at 1:33 PM, Eric Christopher <echri...@gmail.com >>>>>>> <mailto:echri...@gmail.com>> wrote: >>>>>>> >>>>>>> Hi Vedant, >>>>>>> >>>>>>> So this actually broke -fsanitize=function on linux. Han is working up >>>>>>> a testcase for it, but letting you know for now that we'll probably >>>>>>> need some change here. >>>>>>> >>>>>>> -eric >>>>>>> >>>>>>> On Tue, Sep 12, 2017 at 5:05 PM Vedant Kumar via cfe-commits >>>>>>> <cfe-commits@lists.llvm.org <mailto:cfe-commits@lists.llvm.org>> wrote: >>>>>>> Author: vedantk >>>>>>> Date: Tue Sep 12 17:04:35 2017 >>>>>>> New Revision: 313096 >>>>>>> >>>>>>> URL: http://llvm.org/viewvc/llvm-project?rev=313096&view=rev >>>>>>> <http://llvm.org/viewvc/llvm-project?rev=313096&view=rev> >>>>>>> Log: >>>>>>> [ubsan] Function Sanitizer: Don't require writable text segments >>>>>>> >>>>>>> This change will make it possible to use -fsanitize=function on Darwin >>>>>>> and >>>>>>> possibly on other platforms. It fixes an issue with the way RTTI is >>>>>>> stored into >>>>>>> function prologue data. >>>>>>> >>>>>>> On Darwin, addresses stored in prologue data can't require run-time >>>>>>> fixups and >>>>>>> must be PC-relative. Run-time fixups are undesirable because they >>>>>>> necessitate >>>>>>> writable text segments, which can lead to security issues. And absolute >>>>>>> addresses are undesirable because they break PIE mode. >>>>>>> >>>>>>> The fix is to create a private global which points to the RTTI, and >>>>>>> then to >>>>>>> encode a PC-relative reference to the global into prologue data. >>>>>>> >>>>>>> Differential Revision: https://reviews.llvm.org/D37597 >>>>>>> <https://reviews.llvm.org/D37597> >>>>>>> >>>>>>> Modified: >>>>>>> cfe/trunk/lib/CodeGen/CGExpr.cpp >>>>>>> cfe/trunk/lib/CodeGen/CodeGenFunction.cpp >>>>>>> cfe/trunk/lib/CodeGen/CodeGenFunction.h >>>>>>> cfe/trunk/lib/CodeGen/TargetInfo.cpp >>>>>>> cfe/trunk/test/CodeGenCXX/catch-undef-behavior.cpp >>>>>>> >>>>>>> Modified: cfe/trunk/lib/CodeGen/CGExpr.cpp >>>>>>> URL: >>>>>>> http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/CodeGen/CGExpr.cpp?rev=313096&r1=313095&r2=313096&view=diff >>>>>>> >>>>>>> <http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/CodeGen/CGExpr.cpp?rev=313096&r1=313095&r2=313096&view=diff> >>>>>>> ============================================================================== >>>>>>> --- cfe/trunk/lib/CodeGen/CGExpr.cpp (original) >>>>>>> +++ cfe/trunk/lib/CodeGen/CGExpr.cpp Tue Sep 12 17:04:35 2017 >>>>>>> @@ -4409,10 +4409,7 @@ RValue CodeGenFunction::EmitCall(QualTyp >>>>>>> SanitizerScope SanScope(this); >>>>>>> llvm::Constant *FTRTTIConst = >>>>>>> CGM.GetAddrOfRTTIDescriptor(QualType(FnType, 0), >>>>>>> /*ForEH=*/true); >>>>>>> - llvm::Type *PrefixStructTyElems[] = { >>>>>>> - PrefixSig->getType(), >>>>>>> - FTRTTIConst->getType() >>>>>>> - }; >>>>>>> + llvm::Type *PrefixStructTyElems[] = {PrefixSig->getType(), >>>>>>> Int32Ty}; >>>>>>> llvm::StructType *PrefixStructTy = llvm::StructType::get( >>>>>>> CGM.getLLVMContext(), PrefixStructTyElems, >>>>>>> /*isPacked=*/true); >>>>>>> >>>>>>> @@ -4433,8 +4430,10 @@ RValue CodeGenFunction::EmitCall(QualTyp >>>>>>> EmitBlock(TypeCheck); >>>>>>> llvm::Value *CalleeRTTIPtr = >>>>>>> Builder.CreateConstGEP2_32(PrefixStructTy, >>>>>>> CalleePrefixStruct, 0, 1); >>>>>>> - llvm::Value *CalleeRTTI = >>>>>>> + llvm::Value *CalleeRTTIEncoded = >>>>>>> Builder.CreateAlignedLoad(CalleeRTTIPtr, getPointerAlign()); >>>>>>> + llvm::Value *CalleeRTTI = >>>>>>> + DecodeAddrUsedInPrologue(CalleePtr, CalleeRTTIEncoded); >>>>>>> llvm::Value *CalleeRTTIMatch = >>>>>>> Builder.CreateICmpEQ(CalleeRTTI, FTRTTIConst); >>>>>>> llvm::Constant *StaticData[] = { >>>>>>> >>>>>>> Modified: cfe/trunk/lib/CodeGen/CodeGenFunction.cpp >>>>>>> URL: >>>>>>> http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/CodeGen/CodeGenFunction.cpp?rev=313096&r1=313095&r2=313096&view=diff >>>>>>> >>>>>>> <http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/CodeGen/CodeGenFunction.cpp?rev=313096&r1=313095&r2=313096&view=diff> >>>>>>> ============================================================================== >>>>>>> --- cfe/trunk/lib/CodeGen/CodeGenFunction.cpp (original) >>>>>>> +++ cfe/trunk/lib/CodeGen/CodeGenFunction.cpp Tue Sep 12 17:04:35 2017 >>>>>>> @@ -429,6 +429,43 @@ bool CodeGenFunction::ShouldXRayInstrume >>>>>>> return CGM.getCodeGenOpts().XRayInstrumentFunctions; >>>>>>> } >>>>>>> >>>>>>> +llvm::Constant * >>>>>>> +CodeGenFunction::EncodeAddrForUseInPrologue(llvm::Function *F, >>>>>>> + llvm::Constant *Addr) { >>>>>>> + // Addresses stored in prologue data can't require run-time fixups >>>>>>> and must >>>>>>> + // be PC-relative. Run-time fixups are undesirable because they >>>>>>> necessitate >>>>>>> + // writable text segments, which are unsafe. And absolute addresses >>>>>>> are >>>>>>> + // undesirable because they break PIE mode. >>>>>>> + >>>>>>> + // Add a layer of indirection through a private global. Taking its >>>>>>> address >>>>>>> + // won't result in a run-time fixup, even if Addr has linkonce_odr >>>>>>> linkage. >>>>>>> + auto *GV = new llvm::GlobalVariable(CGM.getModule(), Addr->getType(), >>>>>>> + /*isConstant=*/true, >>>>>>> + >>>>>>> llvm::GlobalValue::PrivateLinkage, Addr); >>>>>>> + >>>>>>> + // Create a PC-relative address. >>>>>>> + auto *GOTAsInt = llvm::ConstantExpr::getPtrToInt(GV, IntPtrTy); >>>>>>> + auto *FuncAsInt = llvm::ConstantExpr::getPtrToInt(F, IntPtrTy); >>>>>>> + auto *PCRelAsInt = llvm::ConstantExpr::getSub(GOTAsInt, FuncAsInt); >>>>>>> + return (IntPtrTy == Int32Ty) >>>>>>> + ? PCRelAsInt >>>>>>> + : llvm::ConstantExpr::getTrunc(PCRelAsInt, Int32Ty); >>>>>>> +} >>>>>>> + >>>>>>> +llvm::Value * >>>>>>> +CodeGenFunction::DecodeAddrUsedInPrologue(llvm::Value *F, >>>>>>> + llvm::Value *EncodedAddr) { >>>>>>> + // Reconstruct the address of the global. >>>>>>> + auto *PCRelAsInt = Builder.CreateSExt(EncodedAddr, IntPtrTy); >>>>>>> + auto *FuncAsInt = Builder.CreatePtrToInt(F, IntPtrTy, "func_addr.int >>>>>>> <http://func_addr.int/>"); >>>>>>> + auto *GOTAsInt = Builder.CreateAdd(PCRelAsInt, FuncAsInt, >>>>>>> "global_addr.int <http://global_addr.int/>"); >>>>>>> + auto *GOTAddr = Builder.CreateIntToPtr(GOTAsInt, Int8PtrPtrTy, >>>>>>> "global_addr"); >>>>>>> + >>>>>>> + // Load the original pointer through the global. >>>>>>> + return Builder.CreateLoad(Address(GOTAddr, getPointerAlign()), >>>>>>> + "decoded_addr"); >>>>>>> +} >>>>>>> + >>>>>>> /// EmitFunctionInstrumentation - Emit LLVM code to call the specified >>>>>>> /// instrumentation function with the current function and the call >>>>>>> site, if >>>>>>> /// function instrumentation is enabled. >>>>>>> @@ -856,7 +893,10 @@ void CodeGenFunction::StartFunction(Glob >>>>>>> >>>>>>> CGM.getTargetCodeGenInfo().getUBSanFunctionSignature(CGM)) { >>>>>>> llvm::Constant *FTRTTIConst = >>>>>>> CGM.GetAddrOfRTTIDescriptor(FD->getType(), /*ForEH=*/true); >>>>>>> - llvm::Constant *PrologueStructElems[] = { PrologueSig, >>>>>>> FTRTTIConst }; >>>>>>> + llvm::Constant *FTRTTIConstEncoded = >>>>>>> + EncodeAddrForUseInPrologue(Fn, FTRTTIConst); >>>>>>> + llvm::Constant *PrologueStructElems[] = {PrologueSig, >>>>>>> + FTRTTIConstEncoded}; >>>>>>> llvm::Constant *PrologueStructConst = >>>>>>> llvm::ConstantStruct::getAnon(PrologueStructElems, >>>>>>> /*Packed=*/true); >>>>>>> Fn->setPrologueData(PrologueStructConst); >>>>>>> >>>>>>> Modified: cfe/trunk/lib/CodeGen/CodeGenFunction.h >>>>>>> URL: >>>>>>> http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/CodeGen/CodeGenFunction.h?rev=313096&r1=313095&r2=313096&view=diff >>>>>>> >>>>>>> <http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/CodeGen/CodeGenFunction.h?rev=313096&r1=313095&r2=313096&view=diff> >>>>>>> ============================================================================== >>>>>>> --- cfe/trunk/lib/CodeGen/CodeGenFunction.h (original) >>>>>>> +++ cfe/trunk/lib/CodeGen/CodeGenFunction.h Tue Sep 12 17:04:35 2017 >>>>>>> @@ -1776,6 +1776,15 @@ public: >>>>>>> /// EmitMCountInstrumentation - Emit call to .mcount. >>>>>>> void EmitMCountInstrumentation(); >>>>>>> >>>>>>> + /// Encode an address into a form suitable for use in a function >>>>>>> prologue. >>>>>>> + llvm::Constant *EncodeAddrForUseInPrologue(llvm::Function *F, >>>>>>> + llvm::Constant *Addr); >>>>>>> + >>>>>>> + /// Decode an address used in a function prologue, encoded by \c >>>>>>> + /// EncodeAddrForUseInPrologue. >>>>>>> + llvm::Value *DecodeAddrUsedInPrologue(llvm::Value *F, >>>>>>> + llvm::Value *EncodedAddr); >>>>>>> + >>>>>>> /// EmitFunctionProlog - Emit the target specific LLVM code to load >>>>>>> the >>>>>>> /// arguments for the given function. This is also responsible for >>>>>>> naming the >>>>>>> /// LLVM function arguments. >>>>>>> >>>>>>> Modified: cfe/trunk/lib/CodeGen/TargetInfo.cpp >>>>>>> URL: >>>>>>> http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/CodeGen/TargetInfo.cpp?rev=313096&r1=313095&r2=313096&view=diff >>>>>>> >>>>>>> <http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/CodeGen/TargetInfo.cpp?rev=313096&r1=313095&r2=313096&view=diff> >>>>>>> ============================================================================== >>>>>>> --- cfe/trunk/lib/CodeGen/TargetInfo.cpp (original) >>>>>>> +++ cfe/trunk/lib/CodeGen/TargetInfo.cpp Tue Sep 12 17:04:35 2017 >>>>>>> @@ -1086,8 +1086,8 @@ public: >>>>>>> getUBSanFunctionSignature(CodeGen::CodeGenModule &CGM) const >>>>>>> override { >>>>>>> unsigned Sig = (0xeb << 0) | // jmp rel8 >>>>>>> (0x06 << 8) | // .+0x08 >>>>>>> - ('F' << 16) | >>>>>>> - ('T' << 24); >>>>>>> + ('v' << 16) | >>>>>>> + ('2' << 24); >>>>>>> return llvm::ConstantInt::get(CGM.Int32Ty, Sig); >>>>>>> } >>>>>>> >>>>>>> @@ -2277,17 +2277,10 @@ public: >>>>>>> >>>>>>> llvm::Constant * >>>>>>> getUBSanFunctionSignature(CodeGen::CodeGenModule &CGM) const >>>>>>> override { >>>>>>> - unsigned Sig; >>>>>>> - if (getABIInfo().has64BitPointers()) >>>>>>> - Sig = (0xeb << 0) | // jmp rel8 >>>>>>> - (0x0a << 8) | // .+0x0c >>>>>>> - ('F' << 16) | >>>>>>> - ('T' << 24); >>>>>>> - else >>>>>>> - Sig = (0xeb << 0) | // jmp rel8 >>>>>>> - (0x06 << 8) | // .+0x08 >>>>>>> - ('F' << 16) | >>>>>>> - ('T' << 24); >>>>>>> + unsigned Sig = (0xeb << 0) | // jmp rel8 >>>>>>> + (0x06 << 8) | // .+0x08 >>>>>>> + ('v' << 16) | >>>>>>> + ('2' << 24); >>>>>>> return llvm::ConstantInt::get(CGM.Int32Ty, Sig); >>>>>>> } >>>>>>> >>>>>>> >>>>>>> Modified: cfe/trunk/test/CodeGenCXX/catch-undef-behavior.cpp >>>>>>> URL: >>>>>>> http://llvm.org/viewvc/llvm-project/cfe/trunk/test/CodeGenCXX/catch-undef-behavior.cpp?rev=313096&r1=313095&r2=313096&view=diff >>>>>>> >>>>>>> <http://llvm.org/viewvc/llvm-project/cfe/trunk/test/CodeGenCXX/catch-undef-behavior.cpp?rev=313096&r1=313095&r2=313096&view=diff> >>>>>>> ============================================================================== >>>>>>> --- cfe/trunk/test/CodeGenCXX/catch-undef-behavior.cpp (original) >>>>>>> +++ cfe/trunk/test/CodeGenCXX/catch-undef-behavior.cpp Tue Sep 12 >>>>>>> 17:04:35 2017 >>>>>>> @@ -16,6 +16,10 @@ struct S { >>>>>>> // Check that type mismatch handler is not modified by ASan. >>>>>>> // CHECK-ASAN: private unnamed_addr global { { [{{.*}} x i8]*, i32, >>>>>>> i32 }, { i16, i16, [4 x i8] }*, i8*, i8 } { {{.*}}, { i16, i16, [4 x >>>>>>> i8] }* [[TYPE_DESCR]], {{.*}} } >>>>>>> >>>>>>> +// CHECK: [[IndirectRTTI_ZTIFvPFviEE:@.+]] = private constant i8* >>>>>>> bitcast ({ i8*, i8* }* @_ZTIFvPFviEE to i8*) >>>>>>> +// CHECK-X86: [[IndirectRTTI_ZTIFvPFviEE:@.+]] = private constant i8* >>>>>>> bitcast ({ i8*, i8* }* @_ZTIFvPFviEE to i8*) >>>>>>> +// CHECK-X32: [[IndirectRTTI_ZTIFvPFviEE:@.+]] = private constant i8* >>>>>>> bitcast ({ i8*, i8* }* @_ZTIFvPFviEE to i8*) >>>>>>> + >>>>>>> struct T : S {}; >>>>>>> >>>>>>> // CHECK-LABEL: @_Z17reference_binding >>>>>>> @@ -395,23 +399,30 @@ void downcast_reference(B &b) { >>>>>>> // CHECK-NEXT: br i1 [[AND]] >>>>>>> } >>>>>>> >>>>>>> -// CHECK-LABEL: @_Z22indirect_function_callPFviE({{.*}} prologue <{ >>>>>>> i32, i8* }> <{ i32 1413876459, i8* bitcast ({ i8*, i8* }* @_ZTIFvPFviEE >>>>>>> to i8*) }> >>>>>>> -// CHECK-X32: @_Z22indirect_function_callPFviE({{.*}} prologue <{ i32, >>>>>>> i8* }> <{ i32 1413875435, i8* bitcast ({ i8*, i8* }* @_ZTIFvPFviEE to >>>>>>> i8*) }> >>>>>>> -// CHECK-X86: @_Z22indirect_function_callPFviE({{.*}} prologue <{ i32, >>>>>>> i8* }> <{ i32 1413875435, i8* bitcast ({ i8*, i8* }* @_ZTIFvPFviEE to >>>>>>> i8*) }> >>>>>>> +// >>>>>>> +// CHECK-LABEL: @_Z22indirect_function_callPFviE({{.*}} prologue <{ >>>>>>> i32, i32 }> <{ i32 846595819, i32 trunc (i64 sub (i64 ptrtoint (i8** >>>>>>> {{.*}} to i64), i64 ptrtoint (void (void (i32)*)* >>>>>>> @_Z22indirect_function_callPFviE to i64)) to i32) }> >>>>>>> +// CHECK-X32: @_Z22indirect_function_callPFviE({{.*}} prologue <{ i32, >>>>>>> i32 }> <{ i32 846595819, i32 sub (i32 ptrtoint (i8** >>>>>>> [[IndirectRTTI_ZTIFvPFviEE]] to i32), i32 ptrtoint (void (void (i32)*)* >>>>>>> @_Z22indirect_function_callPFviE to i32)) }> >>>>>>> +// CHECK-X86: @_Z22indirect_function_callPFviE({{.*}} prologue <{ i32, >>>>>>> i32 }> <{ i32 846595819, i32 sub (i32 ptrtoint (i8** >>>>>>> [[IndirectRTTI_ZTIFvPFviEE]] to i32), i32 ptrtoint (void (void (i32)*)* >>>>>>> @_Z22indirect_function_callPFviE to i32)) }> >>>>>>> void indirect_function_call(void (*p)(int)) { >>>>>>> - // CHECK: [[PTR:%.+]] = bitcast void (i32)* {{.*}} to <{ i32, i8* }>* >>>>>>> + // CHECK: [[PTR:%.+]] = bitcast void (i32)* {{.*}} to <{ i32, i32 }>* >>>>>>> >>>>>>> // Signature check >>>>>>> - // CHECK-NEXT: [[SIGPTR:%.+]] = getelementptr <{ i32, i8* }>, <{ >>>>>>> i32, i8* }>* [[PTR]], i32 0, i32 0 >>>>>>> + // CHECK-NEXT: [[SIGPTR:%.+]] = getelementptr <{ i32, i32 }>, <{ >>>>>>> i32, i32 }>* [[PTR]], i32 0, i32 0 >>>>>>> // CHECK-NEXT: [[SIG:%.+]] = load i32, i32* [[SIGPTR]] >>>>>>> - // CHECK-NEXT: [[SIGCMP:%.+]] = icmp eq i32 [[SIG]], 1413876459 >>>>>>> + // CHECK-NEXT: [[SIGCMP:%.+]] = icmp eq i32 [[SIG]], 846595819 >>>>>>> // CHECK-NEXT: br i1 [[SIGCMP]] >>>>>>> >>>>>>> // RTTI pointer check >>>>>>> - // CHECK: [[RTTIPTR:%.+]] = getelementptr <{ i32, i8* }>, <{ i32, >>>>>>> i8* }>* [[PTR]], i32 0, i32 1 >>>>>>> - // CHECK-NEXT: [[RTTI:%.+]] = load i8*, i8** [[RTTIPTR]] >>>>>>> + // CHECK: [[RTTIPTR:%.+]] = getelementptr <{ i32, i32 }>, <{ i32, >>>>>>> i32 }>* [[PTR]], i32 0, i32 1 >>>>>>> + // CHECK-NEXT: [[RTTIEncIntTrunc:%.+]] = load i32, i32* [[RTTIPTR]] >>>>>>> + // CHECK-NEXT: [[RTTIEncInt:%.+]] = sext i32 [[RTTIEncIntTrunc]] to >>>>>>> i64 >>>>>>> + // CHECK-NEXT: [[FuncAddrInt:%.+]] = ptrtoint void (i32)* {{.*}} to >>>>>>> i64 >>>>>>> + // CHECK-NEXT: [[IndirectGVInt:%.+]] = add i64 [[RTTIEncInt]], >>>>>>> [[FuncAddrInt]] >>>>>>> + // CHECK-NEXT: [[IndirectGV:%.+]] = inttoptr i64 [[IndirectGVInt]] >>>>>>> to i8** >>>>>>> + // CHECK-NEXT: [[RTTI:%.+]] = load i8*, i8** [[IndirectGV]], align 8 >>>>>>> // CHECK-NEXT: [[RTTICMP:%.+]] = icmp eq i8* [[RTTI]], bitcast ({ >>>>>>> i8*, i8* }* @_ZTIFviE to i8*) >>>>>>> // CHECK-NEXT: br i1 [[RTTICMP]] >>>>>>> + >>>>>>> p(42); >>>>>>> } >>>>>>> >>>>>>> >>>>>>> >>>>>>> _______________________________________________ >>>>>>> cfe-commits mailing list >>>>>>> cfe-commits@lists.llvm.org <mailto:cfe-commits@lists.llvm.org> >>>>>>> http://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits >>>>>>> <http://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits> >>> >>> >>> >>> -- >>> -- >>> Peter >>> >>> >>> >>> -- >>> -- >>> Peter >> >> >> >> >> -- >> -- >> Peter > > > > > -- > -- > Peter
_______________________________________________ cfe-commits mailing list cfe-commits@lists.llvm.org http://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits