return nullptr;
}
-static Instruction *
-canonicalizeCondSignextOfHighBitExtractToSignextHighBitExtract(
- BinaryOperator &I, InstCombiner::BuilderTy &Builder) {
+Instruction *
+InstCombiner::canonicalizeCondSignextOfHighBitExtractToSignextHighBitExtract(
+ BinaryOperator &I) {
assert((I.getOpcode() == Instruction::Add ||
+ I.getOpcode() == Instruction::Or ||
I.getOpcode() == Instruction::Sub) &&
"Expecting add/sub instruction");
m_Value(Select))))
return nullptr;
- // `add` is commutative; but for `sub`, "select" *must* be on RHS.
+ // `add`/`or` is commutative; but for `sub`, "select" *must* be on RHS.
if (I.getOpcode() == Instruction::Sub && I.getOperand(1) != Select)
return nullptr;
X->getType()->getScalarSizeInBits()))))
return nullptr;
- // Sign-extending value can be sign-extended itself if we `add` it,
- // or zero-extended if we `sub`tract it.
+ // Sign-extending value can be zero-extended if we `sub`tract it,
+ // or sign-extended otherwise.
auto SkipExtInMagic = [&I](Value *&V) {
- if (I.getOpcode() == Instruction::Add)
- match(V, m_SExtOrSelf(m_Value(V)));
- else
+ if (I.getOpcode() == Instruction::Sub)
match(V, m_ZExtOrSelf(m_Value(V)));
+ else
+ match(V, m_SExtOrSelf(m_Value(V)));
};
// Now, finally validate the sign-extending magic.
if (!ShouldSignext)
std::swap(SignExtendingValue, Zero);
- // If we should not perform sign-extension then we must add/subtract zero.
+ // If we should not perform sign-extension then we must add/or/subtract zero.
if (!match(Zero, m_Zero()))
return nullptr;
// Otherwise, it should be some constant, left-shifted by the same NBits we
m_Shl(m_Constant(SignExtendingValueBaseConstant),
m_ZExtOrSelf(m_Specific(NBits)))))
return nullptr;
- // If we `add`, then the constant should be all-ones, else it should be one.
- if (I.getOpcode() == Instruction::Add
- ? !match(SignExtendingValueBaseConstant, m_AllOnes())
- : !match(SignExtendingValueBaseConstant, m_One()))
+ // If we `sub`, then the constant should be one, else it should be all-ones.
+ if (I.getOpcode() == Instruction::Sub
+ ? !match(SignExtendingValueBaseConstant, m_One())
+ : !match(SignExtendingValueBaseConstant, m_AllOnes()))
return nullptr;
auto *NewAShr = BinaryOperator::CreateAShr(X, LowBitsToSkip,
return V;
if (Instruction *V =
- canonicalizeCondSignextOfHighBitExtractToSignextHighBitExtract(
- I, Builder))
+ canonicalizeCondSignextOfHighBitExtractToSignextHighBitExtract(I))
return V;
if (Instruction *SatAdd = foldToUnsignedSaturatedAdd(I))
}
if (Instruction *V =
- canonicalizeCondSignextOfHighBitExtractToSignextHighBitExtract(
- I, Builder))
+ canonicalizeCondSignextOfHighBitExtractToSignextHighBitExtract(I))
return V;
if (Instruction *Ext = narrowMathIfNoOverflow(I))
; CHECK-NEXT: call void @use1(i1 [[SHOULD_SIGNEXT]])
; CHECK-NEXT: call void @use32(i32 [[ALL_BITS_EXCEPT_LOW_NBITS]])
; CHECK-NEXT: call void @use32(i32 [[MAGIC]])
-; CHECK-NEXT: [[SIGNEXTENDED:%.*]] = or i32 [[HIGH_BITS_EXTRACTED]], [[MAGIC]]
+; CHECK-NEXT: [[SIGNEXTENDED:%.*]] = ashr i32 [[DATA]], [[LOW_BITS_TO_SKIP]]
; CHECK-NEXT: ret i32 [[SIGNEXTENDED]]
;
%low_bits_to_skip = sub i32 32, %nbits
; CHECK-NEXT: [[HIGH_BITS_EXTRACTED:%.*]] = trunc i64 [[HIGH_BITS_EXTRACTED_WIDE]] to i32
; CHECK-NEXT: [[SHOULD_SIGNEXT:%.*]] = icmp slt i64 [[DATA]], 0
; CHECK-NEXT: [[ALL_BITS_EXCEPT_LOW_NBITS:%.*]] = shl i32 -1, [[NBITS]]
-; CHECK-NEXT: [[MAGIC:%.*]] = select i1 [[SHOULD_SIGNEXT]], i32 [[ALL_BITS_EXCEPT_LOW_NBITS]], i32 0
; CHECK-NEXT: call void @use32(i32 [[LOW_BITS_TO_SKIP]])
; CHECK-NEXT: call void @use64(i64 [[LOW_BITS_TO_SKIP_WIDE]])
; CHECK-NEXT: call void @use64(i64 [[HIGH_BITS_EXTRACTED_WIDE]])
; CHECK-NEXT: call void @use32(i32 [[HIGH_BITS_EXTRACTED]])
; CHECK-NEXT: call void @use1(i1 [[SHOULD_SIGNEXT]])
; CHECK-NEXT: call void @use32(i32 [[ALL_BITS_EXCEPT_LOW_NBITS]])
-; CHECK-NEXT: [[SIGNEXTENDED:%.*]] = or i32 [[MAGIC]], [[HIGH_BITS_EXTRACTED]]
+; CHECK-NEXT: [[TMP1:%.*]] = ashr i64 [[DATA]], [[LOW_BITS_TO_SKIP_WIDE]]
+; CHECK-NEXT: [[SIGNEXTENDED:%.*]] = trunc i64 [[TMP1]] to i32
; CHECK-NEXT: ret i32 [[SIGNEXTENDED]]
;
%low_bits_to_skip = sub i32 64, %nbits