<div dir="ltr"><div>I created the following pass that fixes the issue:<br><br>class bitcastCombinePass: public llvm::BasicBlockPass {<br>private:<br>    JITEngine *engine;<br>    static char ID;<br><br>public:<br>    bitcastCombinePass(JITEngine *engine): BasicBlockPass(ID), engine(engine) {}<br>
<br>    virtual bool runOnBasicBlock(llvm::BasicBlock &BB) {<br>        bool changed = false;<br>        for(auto i = BB.begin(); i != BB.end(); i++) {<br>            llvm::BitCastInst *bitcast = dynamic_cast<llvm::BitCastInst*>(&*i);<br>
            if(bitcast) {<br>                // find Twin-Bitcast<br>                for(auto i2 = BB.begin(); i2 != i; i2++) {<br>                    llvm::BitCastInst *bitcast2 = dynamic_cast<llvm::BitCastInst*>(&*i2);<br>
                    if(bitcast2) {<br>                        // two bitcasts ... same type?<br>                        if(bitcast->getType() == bitcast2->getType()) {<br>                            llvm::GetElementPtrInst *gep1 = dynamic_cast<llvm::GetElementPtrInst*>(bitcast->getOperand(0));<br>
                            llvm::GetElementPtrInst *gep2 = dynamic_cast<llvm::GetElementPtrInst*>(bitcast2->getOperand(0));<br>                            // both get GEP from same operand<br>                            if(gep1 && gep2 && gep1->getPointerOperand() == gep2->getPointerOperand()) {<br>
                                llvm::APInt offset1(sizeof(int *) * 8, 0);<br>                                llvm::APInt offset2(sizeof(int *) * 8, 0);<br>                                if(gep1->accumulateConstantOffset(*engine->executionEngine->getDataLayout(), offset1)<br>
                                        && gep2->accumulateConstantOffset(*engine->executionEngine->getDataLayout(), offset2)<br>                                        && offset1 == offset2) {<br>
                                    // bitcasts point to same value => replace them<br>                                    bitcast->replaceAllUsesWith(bitcast2);<br>                                }<br>                            }<br>
                        }<br>                    }<br>                }<br>            }<br>        }<br>        return changed;<br>    }<br>};<br>char bitcastCombinePass::ID;<br><br></div>This should become part of either InstCombine or GVN I think.<br>
</div><div class="gmail_extra"><br><br><div class="gmail_quote">2013/11/23 Carl-Philip Hänsch <span dir="ltr"><<a href="mailto:cphaensch@gmail.com" target="_blank">cphaensch@gmail.com</a>></span><br><blockquote class="gmail_quote" style="margin:0 0 0 .8ex;border-left:1px #ccc solid;padding-left:1ex">
<div dir="ltr"><div><div>Hi,<br><br></div>i have the following code:<br>define internal %"struct.dexter::ConditionConstant"* @_ZN6dexter18BinaryConditionAdd8evaluateEv5(%"class.dexter::BinaryConditionAdd"*) {<br>

entry:<br>  %1 = getelementptr inbounds %"class.dexter::BinaryConditionAdd"* %0, i32 0, i32 0, i32 1<br>  %2 = load %"class.dexter::BaseCondition"** %1, align 8<br>  %3 = bitcast %"class.dexter::BaseCondition"* %2 to %"class.dexter::BinaryConditionAdd"*<br>

  %4 = getelementptr inbounds %"class.dexter::BinaryConditionAdd"* %3, i32 0, i32 0, i32 0, i32 1, i32 0<br>  %5 = bitcast %union.anon* %4 to i64*<br>  store i64 4, i64* %5, align 8<br>  %6 = getelementptr inbounds %"class.dexter::BinaryConditionAdd"* %3, i32 0, i32 0, i32 0, i32 1<br>

  %7 = bitcast %"struct.dexter::ConditionConstant"* %6 to i64*<br>  %8 = load i64* %7, align 8<br>  %9 = add nsw i64 %8, 2<br>  %10 = getelementptr inbounds %"class.dexter::BinaryConditionAdd"* %0, i32 0, i32 0, i32 0, i32 1, i32 0<br>

  %11 = bitcast %union.anon* %10 to i64*<br>  store i64 %9, i64* %11, align 8<br>  %12 = getelementptr inbounds %"class.dexter::BinaryConditionAdd"* %0, i32 0, i32 0, i32 0, i32 1<br>  ret %"struct.dexter::ConditionConstant"* %12<br>

}<br><br></div>%5 and %7 point to the same memory location. This is not detected because %4 and %6 look different. But they have the same offset and the bitcast creates. Do you have an idea how to fix that?<br></div>
</blockquote></div><br></div>