insertvalue/extractvalue must consider padding
MODIFY
ir/instr.cpp
ir/instr.cpp
@@ -534,8 +534,9 @@ StateValue BinOp::toSMT(State &s) const {
if (vertical_zip) {
auto ty = lhs->getType().getAsAggregateType();
vector<StateValue> vals1, vals2;
+ unsigned val2idx = 1 + retty->isPadding(1);
auto val1ty = retty->getChild(0).getAsAggregateType();
- auto val2ty = retty->getChild(1).getAsAggregateType();
+ auto val2ty = retty->getChild(val2idx).getAsAggregateType();
for (unsigned i = 0, e = ty->numElementsConst(); i != e; ++i) {
auto ai = ty->extract(a, i);
@@ -593,10 +594,11 @@ expr BinOp::getTypeConstraints(const Function &f) const {
lhs->getType() == rhs->getType();
if (auto ty = getType().getAsStructType()) {
+ unsigned v2idx = 1 + ty->isPadding(1);
instrconstr &= ty->numElementsExcludingPadding() == 2 &&
ty->getChild(0) == lhs->getType() &&
- ty->getChild(1).enforceIntOrVectorType(1) &&
- ty->getChild(1).enforceVectorTypeEquiv(lhs->getType());
+ ty->getChild(v2idx).enforceIntOrVectorType(1) &&
+ ty->getChild(v2idx).enforceVectorTypeEquiv(lhs->getType());
}
break;
case Cttz:

MODIFY
ir/type.cpp
ir/type.cpp
@@ -702,9 +702,13 @@ expr AggregateType::numElements() const {
}
unsigned AggregateType::numPaddingsConst() const {
+ return is_padding.empty() ? 0 : countPaddings(is_padding.size() - 1);
+}
+
+unsigned AggregateType::countPaddings(unsigned to_idx) const {
unsigned count = 0;
- for (bool b : is_padding)
- count += b;
+ for (unsigned i = 0; i <= to_idx; ++i)
+ count += is_padding[i];
return count;
}

MODIFY
ir/type.h
ir/type.h
@@ -274,6 +274,7 @@ public:
bool fromInt = false) const;
Type& getChild(unsigned index) const { return *children[index]; }
bool isPadding(unsigned i) const { return is_padding[i]; }
+ unsigned countPaddings(unsigned to_idx) const;
unsigned bits() const override;
unsigned np_bits() const override;

MODIFY
llvm_util/llvm2alive.cpp
llvm_util/llvm2alive.cpp
@@ -398,8 +398,12 @@ public:
auto inst = make_unique<ExtractValue>(*ty, value_name(i), *val);
+ auto &valty = val->getType();
for (auto idx : i.indices()) {
- inst->addIdx(idx);
+ auto *aty = valty.getAsAggregateType();
+ unsigned idx_with_paddings = aty->countPaddings(idx) + idx;
+ inst->addIdx(idx_with_paddings);
+ valty = aty->getChild(idx_with_paddings);
}
RETURN_IDENTIFIER(move(inst));
@@ -415,7 +419,10 @@ public:
auto inst = make_unique<InsertValue>(*ty, value_name(i), *val, *elt);
for (auto idx : i.indices()) {
- inst->addIdx(idx);
+ auto *aty = ty->getAsAggregateType();
+ unsigned idx_with_paddings = aty->countPaddings(idx) + idx;
+ inst->addIdx(idx_with_paddings);
+ ty = &aty->getChild(idx_with_paddings);
}
RETURN_IDENTIFIER(move(inst));

ADD
tests/alive-tv/insertvalue-padding.srctgt.ll
+define { i8, i32 } @src({ i8*, i32 } %x) {
+ %ex = extractvalue { i8*, i32 } %x, 1
+ %ins = insertvalue { i8, i32 } undef, i32 %ex, 1
+ ret { i8, i32 } %ins
+}
+
+define { i8, i32 } @tgt({ i8*, i32 } %x) {
+ %ex = extractvalue { i8*, i32 } %x, 1
+ %ins = insertvalue { i8, i32 } undef, i32 %ex, 1
+ ret { i8, i32 } %ins
+}

ADD
tests/alive-tv/umul_overflow-vector.srctgt.ll
+define <3 x i1> @src(<3 x i8> %x, <3 x i8> %y) {
+ %t0 = udiv <3 x i8> <i8 -1, i8 undef, i8 -1>, %x
+ %r = icmp uge <3 x i8> %t0, %y
+ ret <3 x i1> %r
+}
+
+define <3 x i1> @tgt(<3 x i8> %x, <3 x i8> %y) {
+ %umul = call { <3 x i8>, <3 x i1> } @llvm.umul.with.overflow.v3i8(<3 x i8> %x, <3 x i8> %y)
+ %umul.ov = extractvalue { <3 x i8>, <3 x i1> } %umul, 1
+ %umul.not.ov = xor <3 x i1> %umul.ov, <i1 true, i1 true, i1 true>
+ ret <3 x i1> %umul.not.ov
+}
+
+declare { <3 x i8>, <3 x i1> } @llvm.umul.with.overflow.v3i8(<3 x i8>, <3 x i8>)

insertvalue/extractvalue must consider padding (#356)