how to use "new instruction()"

I read the tutorial document, but I didn’t understand the it and Ops fields of instruction class well. Can any one give me an example?

Instruction *newInstr = new Instruction(Type *ty, unsigned it, Use *Ops, unsigned NumOps, Instruction *InsertBefore);

For example, I have an instruction *pInst without no the type of operation in advance. If I want to create a new instruction which is similar to the pInst. How can I do it?

Any help will be appreciated. Thanks.

Best,
Zhi

You're probably looking for this method: https://github.com/llvm-mirror/llvm/blob/master/include/llvm/IR/Instruction.h#L395

Jon

Thanks Jonathan. I knew this document. But I didn’t understand the “unsigned iType, Use *Ops” fields. Could you please help how I can create a new instruction to do the example I was giving? Thanks for your time in advance.

Best,
Zhi

You can't. Instruction's constructor is protected so you can't use it
outside implementing a new Instruction no matter how well you
understood its parameters.

But, for the record:
  + "it" is to support LLVM's runtime type identification substitutes
(cast<Ty>, dyn_cast<Ty> and isa<Ty> mostly). I don't think the
permitted values are documented in one place, they're mostly an
implementation detail.
  + "Ops" are the operands: in "add %2, %3" they'd be "%2" and "%3"
(or rather, pointers to instances of Value with those names).

What are you really trying to do (and why)? It's entirely possible
Instruction::clone isn't what you want, but we can't give better
advice without more details.

Cheers.

Tim.

Thanks, Tim. What I want to do is to change the scalar instructions to scalar ones.

For example, if I have to the following one:

%3 = fadd double %1, double %2

I want to change it into
%6 = fadd <2 x double> %4, double %2.

I understand that I can detect the operation first, and use “create” to create for each of them. But I don’t if there is a generic way to do this because if might be add/sub/mul… operations. Clone is not gonna be helpful here because the result type (it is vectortype) should be different to the one being cloned (it is scalar). Any idea about how to do this? Thanks again.

Best,
Zhi

Sorry, I mean change the scalar instructions to vector ones.

I understand that I can detect the operation first, and use "create" to
create for each of them. But I don't if there is a generic way to do this
because if might be add/sub/mul... operations.

I don't think there is. Realistically, just blindly replacing
instructions with vector equivalents is only going to work in a few
cases anyway. You're probably best to intentionally detect those cases
and call the correct CreateXYZ function.

Cheers.

Tim.

Yes. That’s what I was the solution in my mind. But I just wanted to know if there was a generic way to save some code…

But IRBuilder.CreateXYZ only returns a “VALUE” type. Can I get the instruction created by it? For example,

IRBuilder<> builder(&*pinst);
Value *val = builder.CreateFAdd(LV, RV, “”);

How can I get the fadd instruction created by builder?

Value * is the instruction.

use dyn_cast to get to it.

Yes. I was using this. It seems the produced instruction is not correct. There are probably some other problems. I need to recheck it. Thanks for your help, Daniel.

Best,
Zhi

It seems that the problem was because I used builder.CreateFAdd to create a <2 x double> vectortype FADD instruction. It works if I use it to create the scalar version FADD. I want to have an instruction like: %2 = fadd <2 x double> undef, <2 x double> undef. The following is the way I used to create the vectorized FADD instruction:

//pInst is a double type instruction

Type *vecTy = VectorType::get(pInst->getType(), 2);
Value *emptyVec = UndefValue::get(vecTy);

IRBuilder<> builder(&*pInst);
Value *dupVal = builder.CreateFAdd(emptyVec, emptyVec, instName);

std::cout << " dupVal " << *dupVal << “\n”;

It outputs: dupVal <2 x double> <double fadd (double undef, double undef), double fadd (double undef, double undef)>

If I dyn_cast the dupVal to instruction type (dupInst) and print dupInst, it outputs: “dupInst printing a value”
But if I use Instruction *dupInst = (Instruction *) dupVal and print it, I’ll get:
dupInst <2 x double> <double fadd (double undef, double undef), double fadd (double undef, double undef)>

It seems that if simply fails to generate the vectorized FADD instruction. Anything wrong with my code?

Best,
Zhi

zhi chen wrote:

It seems that the problem was because I used builder.CreateFAdd to
create a <2 x double> vectortype FADD instruction. It works if I use it
to create the scalar version FADD. I want to have an instruction like:
*%2 = fadd <2 x double> undef, <2 x double> undef. *The following is the
way I used to create the vectorized FADD instruction:

//pInst is a double type instruction

   Type *vecTy = VectorType::get(pInst->getType(), 2);
Value *emptyVec = UndefValue::get(vecTy);
   IRBuilder<> builder(&*pInst);
   Value *dupVal = builder.CreateFAdd(emptyVec, emptyVec, instName);
   std::cout << " dupVal " << *dupVal << "\n";

It outputs: dupVal <2 x double> <double fadd (double undef, double
undef), double fadd (double undef, double undef)>

If I dyn_cast the dupVal to instruction type (dupInst) and print
dupInst, it outputs: "dupInst printing a <null> value"
But if I use Instruction *dupInst = (Instruction *) dupVal and print it,
I'll get:
dupInst <2 x double> <double fadd (double undef, double undef), double
fadd (double undef, double undef)>

It seems that if simply fails to generate the vectorized FADD
instruction. Anything wrong with my code?

IRBuilder gave you back a constant instead of an Instruction. This is why it returns a Value*. For a simple example, if you ask it to create "add i32 1, 2" it will not return an add instruction, it will instead return "i32 3" which is a ConstantInt.

In your case, it returned to you a ConstantExpr whose getOpcode() shows Instruction::FAdd, and getOperand(0) and getOperand(1) show 'undef', but it is not an instruction. "Undef" is treated as a constant, so an fadd between two constants gets you a constant instead of an instruction.

Usually it won't matter, just build the function top down and don't look at whether you're getting an Instruction* or Constant* and everything will be fine.

Nick

I got it. Thanks, Nick. So, it is back to the previous problem. If I have the following instruction:

%3 = fadd double %1, double %2

I want to change it into
%6 = fadd <2 x double> %4, double %5

where %4 = <double %1, double %1>, %5 = <double %2, double %2>, how can I do this?

Thanks,
Best

zhi chen wrote:

I got it. Thanks, Nick. So, it is back to the previous problem. If I
have the following instruction:

%3 = fadd double %1, double %2

I want to change it into
%6 = fadd <2 x double> %4, double %5

where %4 = <double %1, double %1>, %5 = <double %2, double %2>, how can
I do this?

%4 = <double %1, double %1> isn't valid syntax, the way you would do it is:

%tmp4 = insertelement <2 x double> undef, double %1, i32 0
%4 = insertelement <2 x double> %A, double %1, i32 1

and similarly for %5, then you create the fadd of the two of them.

Nick

Thanks Nick, that’s something what I am trying to implement as the following. But it seems I still only get the constant value not the instruction. Could you please go over the following instruction and see what wrong with it? Thanks for your time again.

Value *vecVal = NULL;
IRBuilder<> builder(&*pInst);
Type *vecTy = VectorType::get(Type::getDoubleTy(ctxt), 2);
Value emptyVec = UndefValue::get(vecTy);
Type
u32Ty = Type::getInt32Ty(currF->getContext());
Value *index0 = ConstantInt::get(u32Ty, 0);
Value *index1 = ConstantInt::get(u32Ty, 1);

Instruction *InsertVal = InsertElementInst::Create(emptyVec, oprnd, index0, “insert”);
InsertVal = InsertElementInst::Create(emptyVec, oprnd, index1, “insert”);

vecVal = builder.CreateFAdd(emptyVec, emptyVec, “”);

Best,
Zhi

zhi chen wrote:

Thanks Nick, that's something what I am trying to implement as the
following. But it seems I still only get the constant value not the
instruction. Could you please go over the following instruction and see
what wrong with it? Thanks for your time again.

   Value *vecVal = NULL;
   IRBuilder<> builder(&*pInst);
   Type *vecTy = VectorType::get(Type::getDoubleTy(ctxt), 2);
   Value *emptyVec = UndefValue::get(vecTy);
   Type* u32Ty = Type::getInt32Ty(currF->getContext());
   Value *index0 = ConstantInt::get(u32Ty, 0);
   Value *index1 = ConstantInt::get(u32Ty, 1);

    Instruction *InsertVal = InsertElementInst::Create(emptyVec, oprnd,
index0, "insert");

This makes you:

%insert = insertelement <2 x double> undef, double %oprnd, i32 0

So far so good.

    InsertVal = InsertElementInst::Create(emptyVec, oprnd, index1,
"insert");

This makes you:

%insert1 = insertelement <2 x double> undef, double %oprnd, i32 1

Not what you wanted. You meant to create:

%insert1 = insertelement <2 x double> %insert, double %oprnd, i32 1

by calling

InsertVal = InsertElementInst::Create(InsertVal, oprnd, index1, "insert");

    vecVal = builder.CreateFAdd(emptyVec, emptyVec, "");

This makes you:

%0 = fadd <2 x double> undef, undef

which constant folds away into a non-instruction. You wanted to sum

vecVal = builder.CreateFAdd(InsertVal, [...], "");

where the [...] is because you haven't yet written the code to create the second vector (%5) yet.

Nick

Thank you Nick, that’s was a stupid error.