<p dir="ltr">I see. So, compatibility of two values depends on address spaces as well? I didn't know that, thank you.</p>
<p dir="ltr">In that case, is there some uniform way to say "give me a new instruction with this (possibly incompatible) value"? </p>
<p dir="ltr">For context, I'm taking some code that was generated in a different address space context, and I'm copying it to a different context (with a different address space).<br></p>
<p dir="ltr">Thanks,<br>
Siddharth.</p>
<br><div class="gmail_quote"><div dir="ltr">On Sat 14 Oct, 2017, 02:30 Quentin Colombet, <<a href="mailto:qcolombet@apple.com">qcolombet@apple.com</a>> wrote:<br></div><blockquote class="gmail_quote" style="margin:0 0 0 .8ex;border-left:1px #ccc solid;padding-left:1ex"><div style="word-wrap:break-word;line-break:after-white-space"><div>Hi <span style="font-family:sans-serif;white-space:pre-wrap">Siddharth,</span></div><div><span style="font-family:sans-serif;white-space:pre-wrap"><br></span></div><div><font face="sans-serif"><span style="white-space:pre-wrap">I haven’t read through your code or example, so my reply may be off but I would say this is expected.</span></font></div><div><font face="sans-serif"><span style="white-space:pre-wrap">When you call replaceUsesOfWith, you have to make sure the values are “compatible” before doing this.</span></font></div><div><font face="sans-serif"><span style="white-space:pre-wrap">If the address space of both values are different and that’s not okay, then you will create wrong code.</span></font></div><div><font face="sans-serif"><span style="white-space:pre-wrap"><br></span></font></div><div><font face="sans-serif"><span style="white-space:pre-wrap">Cheers,</span></font></div><div><font face="sans-serif"><span style="white-space:pre-wrap">-Quentin</span></font></div><br><div><blockquote type="cite"></blockquote></div></div><div style="word-wrap:break-word;line-break:after-white-space"><div><blockquote type="cite"><div>On Oct 13, 2017, at 5:17 PM, Siddharth Bhat via llvm-dev <<a href="mailto:llvm-dev@lists.llvm.org" target="_blank">llvm-dev@lists.llvm.org</a>> wrote:</div><br class="m_-3210939756874267889Apple-interchange-newline"></blockquote></div></div><div style="word-wrap:break-word;line-break:after-white-space"><div><blockquote type="cite"><div><div dir="ltr">Hello,<div><br></div><div>Calling `replaceUsesOfWith` with a value in a different addrspace does not keep the addrspace of a GEP consistent. <span style="white-space:pre-wrap">Is this known? Is this a bug or expected behaviour?</span></div><div><br></div><div><a href="https://gist.github.com/bollu/152ba5e1c20c03c7fc6d8c7b23ba828f" target="_blank">Minimal counterexample link</a></div><div><br></div><div>Reproduced here:</div><div><br></div><div><pre style="word-wrap:break-word;white-space:pre-wrap">#include <iostream>
#include "llvm/ADT/APFloat.h"
#include "llvm/ADT/STLExtras.h"
#include "llvm/ADT/SmallVector.h"
#include "llvm/Bitcode/BitcodeWriter.h"
#include "llvm/IR/BasicBlock.h"
#include "llvm/IR/Constants.h"
#include "llvm/IR/DerivedTypes.h"
#include "llvm/IR/Function.h"
#include "llvm/IR/IRBuilder.h"
#include "llvm/IR/Instructions.h"
#include "llvm/IR/LLVMContext.h"
#include "llvm/IR/Module.h"
#include "llvm/IR/Type.h"
#include "llvm/IR/Verifier.h"
#include "llvm/Support/FileSystem.h"
using namespace llvm;
using namespace std;

static const bool NON_VAR_ARG = false;

static AssertingVH<Function> getOrCreateFunction(Module &m, FunctionType *FTy,
                                                 std::string name) {
    Function *F = m.getFunction(name);
    if (F) return F;

    return Function::Create(FTy, GlobalValue::ExternalLinkage, name, &m);
};
static const bool SHOW_ERROR = false;

int main() {
    static LLVMContext ctx;
    static IRBuilder<> Builder(ctx);

    Module *m = new Module("Module", ctx);
    Function *F = getOrCreateFunction(
        *m,
        FunctionType::get(Builder.getInt64Ty(),
                          {PointerType::get(Builder.getInt32Ty(), 42),
                          PointerType::get(Builder.getInt32Ty(), 1)},
                          NON_VAR_ARG),
        "f");
    auto It = F->arg_begin();
    Value *Arg = &*It;
    It++;
    Value *Arg2 = &*It;

    BasicBlock *Entry = BasicBlock::Create(ctx, "entry", F);
    Builder.SetInsertPoint(Entry);

    Instruction *Slot = nullptr;
<b>    if (SHOW_ERROR) {
        Slot = cast<Instruction>(Builder.CreateGEP(Arg, {Builder.getInt64(1)}, "slot"));
        errs() << "Slot(original): " << *Slot << "\n";
        Slot->replaceUsesOfWith(Arg, Arg2);
        errs() << "Slot(replaced): " << *Slot << "\n";
    }
    else {
        Slot = cast<Instruction>(Builder.CreateGEP(Arg2, {Builder.getInt64(1)}, "slot"));
    }
</b>    Value *TypedSlot = Builder.CreateBitCast(Slot, PointerType::get(Builder.getInt64Ty(), 1), "slot_typed");
    Value *Load = Builder.CreateLoad(TypedSlot, "Val");
    Builder.CreateRet(Load);

    if (verifyModule(*m) == 1) {
        errs() << "module has an error: ";
        verifyModule(*m, &errs());
        report_fatal_error("buggy module.");
    }
    outs() << *m << "\n";
    // llvm::WriteBitcodeToFile(m, outs());

    return 1;
};</pre><pre style="word-wrap:break-word;white-space:pre-wrap"><br></pre><pre style="word-wrap:break-word;white-space:pre-wrap"><br></pre><pre style="word-wrap:break-word;white-space:pre-wrap">Output:</pre><pre style="word-wrap:break-word;white-space:pre-wrap">### `SHOW_ERROR = 0`
```ll
; ModuleID = 'Module'
source_filename = "Module"

define i64 @f(i32 addrspace(42)*, i32 addrspace(1)*) {
entry:
  %slot = getelementptr i32, i32 addrspace(1)* %1, i64 1
  %slot_typed = bitcast i32 addrspace(1)* %slot to i64 addrspace(1)*
  %Val = load i64, i64 addrspace(1)* %slot_typed
  ret i64 %Val
}
```

### `SHOW_ERROR = 1`
```
Slot(original):   %slot = getelementptr i32, i32 addrspace(42)* %0, i64 1
Slot(replaced):   %slot = getelementptr i32, i32 addrspace(1)* %1, i64 1
<b>Assertion failed: (castIsValid(op, S, Ty) && "Invalid cast!"), function Create, file /Users/bollu/work/LLVM-all/polly/llvm/lib/IR/Instructions.cpp, line 2592.
</b>[5]    56333 abort      ./prog
```</pre><pre style="word-wrap:break-word;white-space:pre-wrap"><br></pre><pre style="word-wrap:break-word;white-space:pre-wrap"><font face="sans-serif">Thanks,</font></pre><pre style="word-wrap:break-word;white-space:pre-wrap"><font face="sans-serif">~Siddharth.</font></pre></div></div><div dir="ltr">-- <br></div><div class="m_-3210939756874267889gmail_signature" data-smartmail="gmail_signature"><div dir="ltr">Sending this from my phone, please excuse any typos!</div></div></div></blockquote></div></div><div style="word-wrap:break-word;line-break:after-white-space"><div><blockquote type="cite"><div>
_______________________________________________<br>LLVM Developers mailing list<br><a href="mailto:llvm-dev@lists.llvm.org" target="_blank">llvm-dev@lists.llvm.org</a><br><a href="http://lists.llvm.org/cgi-bin/mailman/listinfo/llvm-dev" target="_blank">http://lists.llvm.org/cgi-bin/mailman/listinfo/llvm-dev</a><br></div></blockquote></div><br></div></blockquote></div><div dir="ltr">-- <br></div><div class="gmail_signature" data-smartmail="gmail_signature"><div dir="ltr">Sending this from my phone, please excuse any typos!</div></div>