define i5 @demand_low_bits_uses(i8 %x, i8 %y) {
; CHECK-LABEL: @demand_low_bits_uses(
-; CHECK-NEXT: [[M:%.*]] = mul i8 [[X:%.*]], -32
-; CHECK-NEXT: [[A:%.*]] = add i8 [[M]], [[Y:%.*]]
+; CHECK-NEXT: [[TMP1:%.*]] = shl i8 [[X:%.*]], 5
+; CHECK-NEXT: [[A:%.*]] = sub i8 [[Y:%.*]], [[TMP1]]
; CHECK-NEXT: call void @use(i8 [[A]])
; CHECK-NEXT: [[R:%.*]] = trunc i8 [[Y]] to i5
; CHECK-NEXT: ret i5 [[R]]
define i6 @demand_low_bits_uses_extra_bit(i8 %x, i8 %y) {
; CHECK-LABEL: @demand_low_bits_uses_extra_bit(
-; CHECK-NEXT: [[M:%.*]] = mul i8 [[X:%.*]], -32
-; CHECK-NEXT: [[A:%.*]] = add i8 [[M]], [[Y:%.*]]
+; CHECK-NEXT: [[TMP1:%.*]] = shl i8 [[X:%.*]], 5
+; CHECK-NEXT: [[A:%.*]] = sub i8 [[Y:%.*]], [[TMP1]]
; CHECK-NEXT: call void @use(i8 [[A]])
; CHECK-NEXT: [[R:%.*]] = trunc i8 [[A]] to i6
; CHECK-NEXT: ret i6 [[R]]
; CHECK-NEXT: [[ZW:%.*]] = zext i64 [[W:%.*]] to i128
; CHECK-NEXT: [[ZZ:%.*]] = zext i64 [[Z:%.*]] to i128
; CHECK-NEXT: [[SHY:%.*]] = shl nuw i128 [[ZY]], 64
-; CHECK-NEXT: [[MW:%.*]] = mul i128 [[ZW]], -18446744073709551616
; CHECK-NEXT: [[XY:%.*]] = or i128 [[SHY]], [[ZX]]
-; CHECK-NEXT: [[SUB:%.*]] = sub i128 [[XY]], [[ZZ]]
-; CHECK-NEXT: [[ADD:%.*]] = add i128 [[SUB]], [[MW]]
-; CHECK-NEXT: [[T:%.*]] = trunc i128 [[SUB]] to i64
+; CHECK-NEXT: [[TMP1:%.*]] = shl nuw i128 [[ZW]], 64
+; CHECK-NEXT: [[TMP2:%.*]] = or i128 [[TMP1]], [[ZZ]]
+; CHECK-NEXT: [[ADD:%.*]] = sub i128 [[XY]], [[TMP2]]
+; CHECK-NEXT: [[T:%.*]] = trunc i128 [[ADD]] to i64
; CHECK-NEXT: [[H:%.*]] = lshr i128 [[ADD]], 64
; CHECK-NEXT: [[T2:%.*]] = trunc i128 [[H]] to i64
; CHECK-NEXT: [[R1:%.*]] = insertvalue { i64, i64 } poison, i64 [[T]], 0
define i8 @mul_negpow2(i8 %x, i8 %y) {
; CHECK-LABEL: @mul_negpow2(
-; CHECK-NEXT: [[M:%.*]] = mul i8 [[X:%.*]], -2
-; CHECK-NEXT: [[A:%.*]] = add i8 [[M]], [[Y:%.*]]
+; CHECK-NEXT: [[TMP1:%.*]] = shl i8 [[X:%.*]], 1
+; CHECK-NEXT: [[A:%.*]] = sub i8 [[Y:%.*]], [[TMP1]]
; CHECK-NEXT: ret i8 [[A]]
;
%m = mul i8 %x, -2
define <2 x i8> @mul_negpow2_commute_vec(<2 x i8> %x, <2 x i8> %p) {
; CHECK-LABEL: @mul_negpow2_commute_vec(
; CHECK-NEXT: [[Y:%.*]] = mul <2 x i8> [[P:%.*]], [[P]]
-; CHECK-NEXT: [[M:%.*]] = mul <2 x i8> [[X:%.*]], <i8 -8, i8 -8>
-; CHECK-NEXT: [[A:%.*]] = add <2 x i8> [[Y]], [[M]]
+; CHECK-NEXT: [[TMP1:%.*]] = shl <2 x i8> [[X:%.*]], <i8 3, i8 3>
+; CHECK-NEXT: [[A:%.*]] = sub <2 x i8> [[Y]], [[TMP1]]
; CHECK-NEXT: ret <2 x i8> [[A]]
;
%y = mul <2 x i8> %p, %p ; thwart complexity-based canonicalization
ret <2 x i8> %a
}
+; negative test - extra use
+
define i8 @mul_negpow2_use(i8 %x) {
; CHECK-LABEL: @mul_negpow2_use(
; CHECK-NEXT: [[M:%.*]] = mul i8 [[X:%.*]], -2
ret i8 %a
}
+; negative test - not negative-power-of-2 multiplier
+
define i8 @mul_not_negpow2(i8 %x) {
; CHECK-LABEL: @mul_not_negpow2(
; CHECK-NEXT: [[M:%.*]] = mul i8 [[X:%.*]], -3