diff --git a/llvm/test/Analysis/ValueTracking/knownbits-mul.ll b/llvm/test/Analysis/ValueTracking/knownbits-mul.ll new file mode 100644 index 0000000000000..79df43c99744e --- /dev/null +++ b/llvm/test/Analysis/ValueTracking/knownbits-mul.ll @@ -0,0 +1,152 @@ +; NOTE: Assertions have been autogenerated by utils/update_test_checks.py UTC_ARGS: --version 5 +; RUN: opt < %s -passes=instcombine -S | FileCheck %s + +define i8 @mul_low_bits_know(i8 %xx, i8 %yy) { +; CHECK-LABEL: define i8 @mul_low_bits_know( +; CHECK-SAME: i8 [[XX:%.*]], i8 [[YY:%.*]]) { +; CHECK-NEXT: ret i8 0 +; + %x = and i8 %xx, 2 + %y = and i8 %yy, 4 + %mul = mul i8 %x, %y + %r = and i8 %mul, 6 + ret i8 %r +} + +define i8 @mul_low_bits_know2(i8 %xx, i8 %yy) { +; CHECK-LABEL: define i8 @mul_low_bits_know2( +; CHECK-SAME: i8 [[XX:%.*]], i8 [[YY:%.*]]) { +; CHECK-NEXT: ret i8 0 +; + %x = or i8 %xx, -2 + %y = and i8 %yy, 4 + %mul = mul i8 %x, %y + %r = and i8 %mul, 2 + ret i8 %r +} + +define i8 @mul_low_bits_partially_known(i8 %xx, i8 %yy) { +; CHECK-LABEL: define i8 @mul_low_bits_partially_known( +; CHECK-SAME: i8 [[XX:%.*]], i8 [[YY:%.*]]) { +; CHECK-NEXT: [[Y:%.*]] = or i8 [[YY]], 2 +; CHECK-NEXT: [[MUL:%.*]] = sub nsw i8 0, [[Y]] +; CHECK-NEXT: [[R:%.*]] = and i8 [[MUL]], 2 +; CHECK-NEXT: ret i8 [[R]] +; + %x = or i8 %xx, -4 + %x.notsmin = or i8 %x, 3 + %y = or i8 %yy, -2 + %mul = mul i8 %x.notsmin, %y + %r = and i8 %mul, 6 + ret i8 %r +} + +define i8 @mul_low_bits_unknown(i8 %xx, i8 %yy) { +; CHECK-LABEL: define i8 @mul_low_bits_unknown( +; CHECK-SAME: i8 [[XX:%.*]], i8 [[YY:%.*]]) { +; CHECK-NEXT: [[X:%.*]] = or i8 [[XX]], 4 +; CHECK-NEXT: [[Y:%.*]] = or i8 [[YY]], 6 +; CHECK-NEXT: [[MUL:%.*]] = mul i8 [[X]], [[Y]] +; CHECK-NEXT: [[R:%.*]] = and i8 [[MUL]], 6 +; CHECK-NEXT: ret i8 [[R]] +; + %x = or i8 %xx, -4 + %y = or i8 %yy, -2 + %mul = mul i8 %x, %y + %r = and i8 %mul, 6 + ret i8 %r +} + +define i8 @mul_high_bits_know(i8 %xx, i8 %yy) { +; CHECK-LABEL: define i8 @mul_high_bits_know( +; CHECK-SAME: i8 [[XX:%.*]], i8 [[YY:%.*]]) { +; CHECK-NEXT: ret i8 0 +; + %x = and i8 %xx, 2 + %y = and i8 %yy, 4 + %mul = mul i8 %x, %y + %r = and i8 %mul, 16 + ret i8 %r +} + +define i8 @mul_high_bits_know2(i8 %xx, i8 %yy) { +; CHECK-LABEL: define i8 @mul_high_bits_know2( +; CHECK-SAME: i8 [[XX:%.*]], i8 [[YY:%.*]]) { +; CHECK-NEXT: [[X:%.*]] = or i8 [[XX]], -2 +; CHECK-NEXT: [[Y:%.*]] = and i8 [[YY]], 4 +; CHECK-NEXT: [[Y_NONZERO:%.*]] = or disjoint i8 [[Y]], 1 +; CHECK-NEXT: [[MUL:%.*]] = mul nsw i8 [[X]], [[Y_NONZERO]] +; CHECK-NEXT: [[R:%.*]] = and i8 [[MUL]], -16 +; CHECK-NEXT: ret i8 [[R]] +; + %x = or i8 %xx, -2 + %y = and i8 %yy, 4 + %y.nonzero = or i8 %y, 1 + %mul = mul i8 %x, %y.nonzero + %r = and i8 %mul, -16 + ret i8 %r +} + +define i8 @mul_high_bits_know3(i8 %xx, i8 %yy) { +; CHECK-LABEL: define i8 @mul_high_bits_know3( +; CHECK-SAME: i8 [[XX:%.*]], i8 [[YY:%.*]]) { +; CHECK-NEXT: [[X:%.*]] = or i8 [[XX]], 124 +; CHECK-NEXT: [[Y:%.*]] = or i8 [[YY]], 126 +; CHECK-NEXT: [[MUL:%.*]] = mul i8 [[X]], [[Y]] +; CHECK-NEXT: [[R:%.*]] = and i8 [[MUL]], 112 +; CHECK-NEXT: ret i8 [[R]] +; + %x = or i8 %xx, -4 + %y = or i8 %yy, -2 + %mul = mul i8 %x, %y + %r = and i8 %mul, -16 + ret i8 %r +} + +define i8 @mul_high_bits_unknown(i8 %xx, i8 %yy) { +; CHECK-LABEL: define i8 @mul_high_bits_unknown( +; CHECK-SAME: i8 [[XX:%.*]], i8 [[YY:%.*]]) { +; CHECK-NEXT: [[X:%.*]] = and i8 [[XX]], 2 +; CHECK-NEXT: [[Y:%.*]] = and i8 [[YY]], 4 +; CHECK-NEXT: [[MUL:%.*]] = mul nuw nsw i8 [[X]], [[Y]] +; CHECK-NEXT: ret i8 [[MUL]] +; + %x = and i8 %xx, 2 + %y = and i8 %yy, 4 + %mul = mul i8 %x, %y + %r = and i8 %mul, 8 + ret i8 %r +} + +define i8 @mul_high_bits_unknown2(i8 %xx, i8 %yy) { +; CHECK-LABEL: define i8 @mul_high_bits_unknown2( +; CHECK-SAME: i8 [[XX:%.*]], i8 [[YY:%.*]]) { +; CHECK-NEXT: [[X:%.*]] = or i8 [[XX]], -2 +; CHECK-NEXT: [[Y:%.*]] = and i8 [[YY]], 4 +; CHECK-NEXT: [[MUL:%.*]] = mul nsw i8 [[X]], [[Y]] +; CHECK-NEXT: [[R:%.*]] = and i8 [[MUL]], -16 +; CHECK-NEXT: ret i8 [[R]] +; + %x = or i8 %xx, -2 + %y = and i8 %yy, 4 + %mul = mul i8 %x, %y + %r = and i8 %mul, -16 + ret i8 %r +} + +; TODO: This can be reduced to zero. +define i8 @mul_high_bits_unknown3(i8 %xx, i8 %yy) { +; CHECK-LABEL: define i8 @mul_high_bits_unknown3( +; CHECK-SAME: i8 [[XX:%.*]], i8 [[YY:%.*]]) { +; CHECK-NEXT: [[X:%.*]] = or i8 [[XX]], 28 +; CHECK-NEXT: [[Y:%.*]] = or i8 [[YY]], 30 +; CHECK-NEXT: [[MUL:%.*]] = mul i8 [[X]], [[Y]] +; CHECK-NEXT: [[R:%.*]] = and i8 [[MUL]], 16 +; CHECK-NEXT: ret i8 [[R]] +; + %x = or i8 %xx, -4 + %y = or i8 %yy, -2 + %mul = mul i8 %x, %y + %r = and i8 %mul, 16 + ret i8 %r +}