return MIB;
}
- template <typename... ArgTys>
MachineInstrBuilder buildInsert(unsigned Res, unsigned Src,
- unsigned Op, unsigned Index, ArgTys... Args) {
- MachineInstrBuilder MIB =
- buildInstr(TargetOpcode::G_INSERT).addDef(Res).addUse(Src);
- addUsesWithIndices(MIB, Op, Index, Args...);
- return MIB;
- }
+ unsigned Op, unsigned Index);
/// Build and insert either a G_INTRINSIC (if \p HasSideEffects is false) or
/// G_INTRINSIC_W_SIDE_EFFECTS instruction. Its first operand will be the
let hasSideEffects = 0;
}
-// Insert a sequence of smaller registers into a larger one at the specified
-// indices (interleaved with the values in the operand list "op0, bit0, op1,
-// bit1, ...")).
+// Insert a smaller register into a larger one at the specified bit-index.
def G_INSERT : Instruction {
let OutOperandList = (outs type0:$dst);
- let InOperandList = (ins type0:$src, variable_ops);
+ let InOperandList = (ins type0:$src, type1:$op, unknown:$offset);
let hasSideEffects = 0;
}
return MIB;
}
+MachineInstrBuilder MachineIRBuilder::buildInsert(unsigned Res, unsigned Src,
+ unsigned Op, unsigned Index) {
+ return buildInstr(TargetOpcode::G_INSERT)
+ .addDef(Res)
+ .addUse(Src)
+ .addUse(Op)
+ .addImm(Index);
+}
+
MachineInstrBuilder MachineIRBuilder::buildIntrinsic(Intrinsic::ID ID,
unsigned Res,
bool HasSideEffects) {
setAction({BinOp, s64}, Libcall);
}
- // FIXME: what should we do about G_INSERTs with more than one source value?
- // For now the default of not specifying means we'll fall back.
- for (auto Ty : {s32, s64}) {
+ for (auto Ty : {s32, s64, p0}) {
setAction({G_INSERT, Ty}, Legal);
setAction({G_INSERT, 1, Ty}, Legal);
}
for (auto Ty : {s1, s8, s16}) {
setAction({G_INSERT, Ty}, WidenScalar);
+ setAction({G_INSERT, 1, Ty}, Legal);
// FIXME: Can't widen the sources because that violates the constraints on
// G_INSERT (It seems entirely reasonable that inputs shouldn't overlap).
}
; CHECK-LABEL: name: test_insertvalue
; CHECK: [[VAL:%[0-9]+]](s32) = COPY %w1
; CHECK: [[STRUCT:%[0-9]+]](s128) = G_LOAD
-; CHECK: [[NEWSTRUCT:%[0-9]+]](s128) = G_INSERT [[STRUCT]](s128), [[VAL]](s32), 64
+; CHECK: [[NEWSTRUCT:%[0-9]+]](s128) = G_INSERT [[STRUCT]], [[VAL]](s32), 64
; CHECK: G_STORE [[NEWSTRUCT]](s128),
define void @test_insertvalue(%struct.nested* %addr, i32 %val) {
%struct = load %struct.nested, %struct.nested* %addr
; CHECK-LABEL: name: test_insertvalue_agg
; CHECK: [[SMALLSTRUCT:%[0-9]+]](s64) = G_LOAD
; CHECK: [[STRUCT:%[0-9]+]](s128) = G_LOAD
-; CHECK: [[RES:%[0-9]+]](s128) = G_INSERT [[STRUCT]](s128), [[SMALLSTRUCT]](s64), 32
+; CHECK: [[RES:%[0-9]+]](s128) = G_INSERT [[STRUCT]], [[SMALLSTRUCT]](s64), 32
; CHECK: G_STORE [[RES]](s128)
define void @test_insertvalue_agg(%struct.nested* %addr, {i8, i32}* %addr2) {
%smallstruct = load {i8, i32}, {i8, i32}* %addr2
; CHECK: [[GOOD]]:
; CHECK: [[SEL:%[0-9]+]](s32) = G_CONSTANT i32 1
-; CHECK: {{%[0-9]+}}(s128) = G_INSERT {{%[0-9]+}}(s128), [[SEL]](s32), 64
+; CHECK: {{%[0-9]+}}(s128) = G_INSERT {{%[0-9]+}}, [[SEL]](s32), 64
define { i8*, i32 } @bar() personality i8* bitcast (i32 (...)* @__gxx_personality_v0 to i8*) {
%res32 = invoke i32 @foo(i32 42) to label %continue unwind label %broken
; CHECK-LABEL: name: test_inserts_2
; CHECK: [[LO:%[0-9]+]](s64) = G_LOAD
; CHECK: [[HI:%[0-9]+]](s64) = G_LOAD
- ; CHECK: [[NEWHI:%[0-9]+]](s64) = G_INSERT [[HI]](s64), %1(s32), 0
+ ; CHECK: [[NEWHI:%[0-9]+]](s64) = G_INSERT [[HI]], %1(s32), 0
; CHECK: G_STORE %0(s64)
; CHECK: G_STORE [[NEWHI]]
%0:_(s64) = COPY %x0
; CHECK-LABEL: name: test_inserts_3
; CHECK: [[LO:%[0-9]+]](s64) = G_LOAD
; CHECK: [[HI:%[0-9]+]](s64) = G_LOAD
- ; CHECK: [[NEWLO:%[0-9]+]](s64) = G_INSERT [[LO]](s64), %0(p0), 0
+ ; CHECK: [[NEWLO:%[0-9]+]](s64) = G_INSERT [[LO]], %0(p0), 0
; CHECK: G_STORE [[NEWLO]](s64)
; CHECK: G_STORE [[HI]]
%0:_(p0) = COPY %x0
; A narrow insert gets surrounded by a G_ANYEXT/G_TRUNC pair.
; CHECK-LABEL: name: test_inserts_4
; CHECK: [[VALEXT:%[0-9]+]](s32) = G_ANYEXT %1(s8)
- ; CHECK: [[VAL:%[0-9]+]](s32) = G_INSERT [[VALEXT]](s32), %0(s1), 0
+ ; CHECK: [[VAL:%[0-9]+]](s32) = G_INSERT [[VALEXT]], %0(s1), 0
; CHECK: %3(s8) = G_TRUNC [[VAL]](s32)
%0:_(s1) = COPY %w0
%1:_(s8) = COPY %w1