diff --git a/llvm/test/Transforms/InstCombine/and.ll b/llvm/test/Transforms/InstCombine/and.ll index eb39ff9014ff3a..989640ed41f2d2 100644 --- a/llvm/test/Transforms/InstCombine/and.ll +++ b/llvm/test/Transforms/InstCombine/and.ll @@ -2582,3 +2582,126 @@ define i32 @canonicalize_and_sub_power2_or_zero(i32 %x, i32 %y) { %and = and i32 %val, %p2 ret i32 %and } + +define i32 @canonicalize_and_add_power2_or_zero_commuted1(i32 %x, i32 %y) { +; CHECK-LABEL: @canonicalize_and_add_power2_or_zero_commuted1( +; CHECK-NEXT: [[NY:%.*]] = sub i32 0, [[Y:%.*]] +; CHECK-NEXT: [[P2:%.*]] = and i32 [[NY]], [[Y]] +; CHECK-NEXT: call void @use32(i32 [[P2]]) +; CHECK-NEXT: [[TMP1:%.*]] = xor i32 [[X:%.*]], -1 +; CHECK-NEXT: [[AND:%.*]] = and i32 [[P2]], [[TMP1]] +; CHECK-NEXT: ret i32 [[AND]] +; + %ny = sub i32 0, %y + %p2 = and i32 %y, %ny + call void @use32(i32 %p2) ; keep p2 + + %val = add i32 %p2, %x + %and = and i32 %val, %p2 + ret i32 %and +} + +define i32 @canonicalize_and_add_power2_or_zero_commuted2(i32 %x, i32 %y) { +; CHECK-LABEL: @canonicalize_and_add_power2_or_zero_commuted2( +; CHECK-NEXT: [[NY:%.*]] = sub i32 0, [[Y:%.*]] +; CHECK-NEXT: [[P2:%.*]] = and i32 [[NY]], [[Y]] +; CHECK-NEXT: call void @use32(i32 [[P2]]) +; CHECK-NEXT: [[TMP1:%.*]] = xor i32 [[X:%.*]], -1 +; CHECK-NEXT: [[AND:%.*]] = and i32 [[P2]], [[TMP1]] +; CHECK-NEXT: ret i32 [[AND]] +; + %ny = sub i32 0, %y + %p2 = and i32 %y, %ny + call void @use32(i32 %p2) ; keep p2 + + %val = add i32 %x, %p2 + %and = and i32 %p2, %val + ret i32 %and +} + +define i32 @canonicalize_and_add_power2_or_zero_commuted3(i32 %x, i32 %y) { +; CHECK-LABEL: @canonicalize_and_add_power2_or_zero_commuted3( +; CHECK-NEXT: [[NY:%.*]] = sub i32 0, [[Y:%.*]] +; CHECK-NEXT: [[P2:%.*]] = and i32 [[NY]], [[Y]] +; CHECK-NEXT: call void @use32(i32 [[P2]]) +; CHECK-NEXT: [[TMP1:%.*]] = xor i32 [[X:%.*]], -1 +; CHECK-NEXT: [[AND:%.*]] = and i32 [[P2]], [[TMP1]] +; CHECK-NEXT: ret i32 [[AND]] +; + %ny = sub i32 0, %y + %p2 = and i32 %y, %ny + call void @use32(i32 %p2) ; keep p2 + + %val = add i32 %p2, %x + %and = and i32 %p2, %val + ret i32 %and +} + +define i32 @canonicalize_and_sub_power2_or_zero_commuted_nofold(i32 %x, i32 %y) { +; CHECK-LABEL: @canonicalize_and_sub_power2_or_zero_commuted_nofold( +; CHECK-NEXT: [[NY:%.*]] = sub i32 0, [[Y:%.*]] +; CHECK-NEXT: [[P2:%.*]] = and i32 [[NY]], [[Y]] +; CHECK-NEXT: call void @use32(i32 [[P2]]) +; CHECK-NEXT: [[VAL:%.*]] = sub i32 [[P2]], [[X:%.*]] +; CHECK-NEXT: [[AND:%.*]] = and i32 [[VAL]], [[P2]] +; CHECK-NEXT: ret i32 [[AND]] +; + %ny = sub i32 0, %y + %p2 = and i32 %y, %ny + call void @use32(i32 %p2) ; keep p2 + + %val = sub i32 %p2, %x + %and = and i32 %val, %p2 + ret i32 %and +} + +define i32 @canonicalize_and_add_non_power2_or_zero_nofold(i32 %x, i32 %y) { +; CHECK-LABEL: @canonicalize_and_add_non_power2_or_zero_nofold( +; CHECK-NEXT: [[VAL:%.*]] = add i32 [[X:%.*]], [[Y:%.*]] +; CHECK-NEXT: [[AND:%.*]] = and i32 [[VAL]], [[Y]] +; CHECK-NEXT: ret i32 [[AND]] +; + %val = add i32 %x, %y + %and = and i32 %val, %y + ret i32 %and +} + +define i32 @canonicalize_and_add_power2_or_zero_multiuse_nofold(i32 %x, i32 %y) { +; CHECK-LABEL: @canonicalize_and_add_power2_or_zero_multiuse_nofold( +; CHECK-NEXT: [[NY:%.*]] = sub i32 0, [[Y:%.*]] +; CHECK-NEXT: [[P2:%.*]] = and i32 [[NY]], [[Y]] +; CHECK-NEXT: call void @use32(i32 [[P2]]) +; CHECK-NEXT: [[VAL:%.*]] = add i32 [[P2]], [[X:%.*]] +; CHECK-NEXT: call void @use32(i32 [[VAL]]) +; CHECK-NEXT: [[AND:%.*]] = and i32 [[VAL]], [[P2]] +; CHECK-NEXT: ret i32 [[AND]] +; + %ny = sub i32 0, %y + %p2 = and i32 %y, %ny + call void @use32(i32 %p2) ; keep p2 + + %val = add i32 %x, %p2 + call void @use32(i32 %val) + %and = and i32 %val, %p2 + ret i32 %and +} + +define i32 @canonicalize_and_sub_power2_or_zero_multiuse_nofold(i32 %x, i32 %y) { +; CHECK-LABEL: @canonicalize_and_sub_power2_or_zero_multiuse_nofold( +; CHECK-NEXT: [[NY:%.*]] = sub i32 0, [[Y:%.*]] +; CHECK-NEXT: [[P2:%.*]] = and i32 [[NY]], [[Y]] +; CHECK-NEXT: call void @use32(i32 [[P2]]) +; CHECK-NEXT: [[VAL:%.*]] = sub i32 [[X:%.*]], [[P2]] +; CHECK-NEXT: call void @use32(i32 [[VAL]]) +; CHECK-NEXT: [[AND:%.*]] = and i32 [[VAL]], [[P2]] +; CHECK-NEXT: ret i32 [[AND]] +; + %ny = sub i32 0, %y + %p2 = and i32 %y, %ny + call void @use32(i32 %p2) ; keep p2 + + %val = sub i32 %x, %p2 + call void @use32(i32 %val) + %and = and i32 %val, %p2 + ret i32 %and +}