diff --git a/llvm/test/Transforms/InstCombine/add.ll b/llvm/test/Transforms/InstCombine/add.ll index 522dcf8db27f4..846da7f760b1d 100644 --- a/llvm/test/Transforms/InstCombine/add.ll +++ b/llvm/test/Transforms/InstCombine/add.ll @@ -3986,5 +3986,84 @@ define i32 @add_reduce_sqr_sum_varC_invalid2(i32 %a, i32 %b) { ret i32 %ab2 } +define i32 @fold_sext_addition_or_disjoint(i8 %x) { +; CHECK-LABEL: @fold_sext_addition_or_disjoint( +; CHECK-NEXT: [[XX:%.*]] = or disjoint i8 [[X:%.*]], 12 +; CHECK-NEXT: [[SE:%.*]] = sext i8 [[XX]] to i32 +; CHECK-NEXT: [[R:%.*]] = add nsw i32 [[SE]], 1234 +; CHECK-NEXT: ret i32 [[R]] +; + %xx = or disjoint i8 %x, 12 + %se = sext i8 %xx to i32 + %r = add i32 %se, 1234 + ret i32 %r +} + +define i32 @fold_sext_addition_fail(i8 %x) { +; CHECK-LABEL: @fold_sext_addition_fail( +; CHECK-NEXT: [[XX:%.*]] = or i8 [[X:%.*]], 12 +; CHECK-NEXT: [[SE:%.*]] = sext i8 [[XX]] to i32 +; CHECK-NEXT: [[R:%.*]] = add nsw i32 [[SE]], 1234 +; CHECK-NEXT: ret i32 [[R]] +; + %xx = or i8 %x, 12 + %se = sext i8 %xx to i32 + %r = add i32 %se, 1234 + ret i32 %r +} + +define i32 @fold_zext_addition_or_disjoint(i8 %x) { +; CHECK-LABEL: @fold_zext_addition_or_disjoint( +; CHECK-NEXT: [[XX:%.*]] = or disjoint i8 [[X:%.*]], 12 +; CHECK-NEXT: [[SE:%.*]] = zext i8 [[XX]] to i32 +; CHECK-NEXT: [[R:%.*]] = add nuw nsw i32 [[SE]], 1234 +; CHECK-NEXT: ret i32 [[R]] +; + %xx = or disjoint i8 %x, 12 + %se = zext i8 %xx to i32 + %r = add i32 %se, 1234 + ret i32 %r +} + +define i32 @fold_zext_addition_or_disjoint2(i8 %x) { +; CHECK-LABEL: @fold_zext_addition_or_disjoint2( +; CHECK-NEXT: [[XX:%.*]] = or disjoint i8 [[X:%.*]], 18 +; CHECK-NEXT: [[SE:%.*]] = zext i8 [[XX]] to i32 +; CHECK-NEXT: [[R:%.*]] = add nsw i32 [[SE]], -14 +; CHECK-NEXT: ret i32 [[R]] +; + %xx = or disjoint i8 %x, 18 + %se = zext i8 %xx to i32 + %r = add i32 %se, -14 + ret i32 %r +} + +define i32 @fold_zext_addition_fail(i8 %x) { +; CHECK-LABEL: @fold_zext_addition_fail( +; CHECK-NEXT: [[XX:%.*]] = or i8 [[X:%.*]], 12 +; CHECK-NEXT: [[SE:%.*]] = zext i8 [[XX]] to i32 +; CHECK-NEXT: [[R:%.*]] = add nuw nsw i32 [[SE]], 1234 +; CHECK-NEXT: ret i32 [[R]] +; + %xx = or i8 %x, 12 + %se = zext i8 %xx to i32 + %r = add i32 %se, 1234 + ret i32 %r +} + +define i32 @fold_zext_addition_fail2(i8 %x) { +; CHECK-LABEL: @fold_zext_addition_fail2( +; CHECK-NEXT: [[XX:%.*]] = or i8 [[X:%.*]], 18 +; CHECK-NEXT: [[SE:%.*]] = zext i8 [[XX]] to i32 +; CHECK-NEXT: [[R:%.*]] = add nsw i32 [[SE]], -14 +; CHECK-NEXT: ret i32 [[R]] +; + %xx = or i8 %x, 18 + %se = zext i8 %xx to i32 + %r = add i32 %se, -14 + ret i32 %r +} + + declare void @llvm.assume(i1) declare void @fake_func(i32) diff --git a/llvm/test/Transforms/InstCombine/div.ll b/llvm/test/Transforms/InstCombine/div.ll index 1309dee817cf6..a4d604b329c3c 100644 --- a/llvm/test/Transforms/InstCombine/div.ll +++ b/llvm/test/Transforms/InstCombine/div.ll @@ -1810,3 +1810,29 @@ define i6 @udiv_distribute_mul_nsw_add_nuw(i6 %x) { %div = udiv i6 %add, 3 ret i6 %div } + +define i32 @fold_disjoint_or_over_sdiv(i32 %x) { +; CHECK-LABEL: @fold_disjoint_or_over_sdiv( +; CHECK-NEXT: [[MUL:%.*]] = mul nsw i32 [[X:%.*]], 9 +; CHECK-NEXT: [[OR:%.*]] = or disjoint i32 [[MUL]], 81 +; CHECK-NEXT: [[R:%.*]] = sdiv i32 [[OR]], 9 +; CHECK-NEXT: ret i32 [[R]] +; + %mul = mul nsw i32 %x, 9 + %or = or disjoint i32 %mul, 81 + %r = sdiv i32 %or, 9 + ret i32 %r +} + +define i32 @fold_disjoint_or_over_udiv(i32 %x) { +; CHECK-LABEL: @fold_disjoint_or_over_udiv( +; CHECK-NEXT: [[MUL:%.*]] = mul nuw i32 [[X:%.*]], 9 +; CHECK-NEXT: [[OR:%.*]] = or disjoint i32 [[MUL]], 81 +; CHECK-NEXT: [[R:%.*]] = udiv i32 [[OR]], 9 +; CHECK-NEXT: ret i32 [[R]] +; + %mul = mul nuw i32 %x, 9 + %or = or disjoint i32 %mul, 81 + %r = udiv i32 %or, 9 + ret i32 %r +} diff --git a/llvm/test/Transforms/InstCombine/sadd-with-overflow.ll b/llvm/test/Transforms/InstCombine/sadd-with-overflow.ll index 4b37ccbe3370b..904dd480caafa 100644 --- a/llvm/test/Transforms/InstCombine/sadd-with-overflow.ll +++ b/llvm/test/Transforms/InstCombine/sadd-with-overflow.ll @@ -122,3 +122,36 @@ define { i32, i1 } @fold_sub_simple(i32 %x) { %b = tail call { i32, i1 } @llvm.sadd.with.overflow.i32(i32 %a, i32 30) ret { i32, i1 } %b } + +define { i32, i1 } @fold_with_distjoin_or(i32 %x) { +; CHECK-LABEL: @fold_with_distjoin_or( +; CHECK-NEXT: [[B:%.*]] = add i32 [[X:%.*]], 6 +; CHECK-NEXT: [[TMP1:%.*]] = insertvalue { i32, i1 } { i32 poison, i1 false }, i32 [[B]], 0 +; CHECK-NEXT: ret { i32, i1 } [[TMP1]] +; + %a = or disjoint i32 %x, 13 + %b = tail call { i32, i1 } @llvm.sadd.with.overflow.i32(i32 %a, i32 -7) + ret { i32, i1 } %b +} + +define { i32, i1 } @fold_with_disjoint_or2(i32 %x) { +; CHECK-LABEL: @fold_with_disjoint_or2( +; CHECK-NEXT: [[A:%.*]] = or disjoint i32 [[X:%.*]], 100 +; CHECK-NEXT: [[B:%.*]] = tail call { i32, i1 } @llvm.sadd.with.overflow.i32(i32 [[A]], i32 27) +; CHECK-NEXT: ret { i32, i1 } [[B]] +; + %a = or disjoint i32 %x, 100 + %b = tail call { i32, i1 } @llvm.sadd.with.overflow.i32(i32 %a, i32 27) + ret { i32, i1 } %b +} + +define { i32, i1 } @fold_with_or_fail(i32 %x) { +; CHECK-LABEL: @fold_with_or_fail( +; CHECK-NEXT: [[A:%.*]] = or i32 [[X:%.*]], 100 +; CHECK-NEXT: [[B:%.*]] = tail call { i32, i1 } @llvm.sadd.with.overflow.i32(i32 [[A]], i32 27) +; CHECK-NEXT: ret { i32, i1 } [[B]] +; + %a = or i32 %x, 100 + %b = tail call { i32, i1 } @llvm.sadd.with.overflow.i32(i32 %a, i32 27) + ret { i32, i1 } %b +} diff --git a/llvm/test/Transforms/InstCombine/shift-add.ll b/llvm/test/Transforms/InstCombine/shift-add.ll index 1b25675059930..2be6d9b29d526 100644 --- a/llvm/test/Transforms/InstCombine/shift-add.ll +++ b/llvm/test/Transforms/InstCombine/shift-add.ll @@ -775,3 +775,36 @@ define <3 x i32> @add3_i96(<3 x i32> %0, <3 x i32> %1) { %25 = insertelement <3 x i32> %24, i32 %20, i32 2 ret <3 x i32> %25 } + +define i8 @shl_fold_or_disjoint_cnt(i8 %x) { +; CHECK-LABEL: @shl_fold_or_disjoint_cnt( +; CHECK-NEXT: [[A:%.*]] = or disjoint i8 [[X:%.*]], 3 +; CHECK-NEXT: [[R:%.*]] = shl i8 2, [[A]] +; CHECK-NEXT: ret i8 [[R]] +; + %a = or disjoint i8 %x, 3 + %r = shl i8 2, %a + ret i8 %r +} + +define <2 x i8> @ashr_fold_or_disjoint_cnt(<2 x i8> %x) { +; CHECK-LABEL: @ashr_fold_or_disjoint_cnt( +; CHECK-NEXT: [[A:%.*]] = or disjoint <2 x i8> [[X:%.*]], +; CHECK-NEXT: [[R:%.*]] = lshr <2 x i8> , [[A]] +; CHECK-NEXT: ret <2 x i8> [[R]] +; + %a = or disjoint <2 x i8> %x, + %r = ashr <2 x i8> , %a + ret <2 x i8> %r +} + +define <2 x i8> @lshr_fold_or_disjoint_cnt_out_of_bounds(<2 x i8> %x) { +; CHECK-LABEL: @lshr_fold_or_disjoint_cnt_out_of_bounds( +; CHECK-NEXT: [[A:%.*]] = or disjoint <2 x i8> [[X:%.*]], +; CHECK-NEXT: [[R:%.*]] = lshr <2 x i8> , [[A]] +; CHECK-NEXT: ret <2 x i8> [[R]] +; + %a = or disjoint <2 x i8> %x, + %r = lshr <2 x i8> , %a + ret <2 x i8> %r +} diff --git a/llvm/test/Transforms/InstCombine/uadd-with-overflow.ll b/llvm/test/Transforms/InstCombine/uadd-with-overflow.ll index 28d309baaa41d..b1819e6c3e2b6 100644 --- a/llvm/test/Transforms/InstCombine/uadd-with-overflow.ll +++ b/llvm/test/Transforms/InstCombine/uadd-with-overflow.ll @@ -124,3 +124,27 @@ define { i32, i1 } @no_fold_wrapped_add(i32 %x) { %b = tail call { i32, i1 } @llvm.uadd.with.overflow.i32(i32 30, i32 %a) ret { i32, i1 } %b } + + +define { <2 x i32>, <2 x i1> } @fold_simple_splat_with_disjoint_or_constant(<2 x i32> %x) { +; CHECK-LABEL: @fold_simple_splat_with_disjoint_or_constant( +; CHECK-NEXT: [[A:%.*]] = or disjoint <2 x i32> [[X:%.*]], +; CHECK-NEXT: [[B:%.*]] = tail call { <2 x i32>, <2 x i1> } @llvm.uadd.with.overflow.v2i32(<2 x i32> [[A]], <2 x i32> ) +; CHECK-NEXT: ret { <2 x i32>, <2 x i1> } [[B]] +; + %a = or disjoint <2 x i32> %x, + %b = tail call { <2 x i32>, <2 x i1> } @llvm.uadd.with.overflow.v2i32(<2 x i32> %a, <2 x i32> ) + ret { <2 x i32>, <2 x i1> } %b +} + + +define { <2 x i32>, <2 x i1> } @fold_simple_splat_constant_with_or_fail(<2 x i32> %x) { +; CHECK-LABEL: @fold_simple_splat_constant_with_or_fail( +; CHECK-NEXT: [[A:%.*]] = or <2 x i32> [[X:%.*]], +; CHECK-NEXT: [[B:%.*]] = tail call { <2 x i32>, <2 x i1> } @llvm.uadd.with.overflow.v2i32(<2 x i32> [[A]], <2 x i32> ) +; CHECK-NEXT: ret { <2 x i32>, <2 x i1> } [[B]] +; + %a = or <2 x i32> %x, + %b = tail call { <2 x i32>, <2 x i1> } @llvm.uadd.with.overflow.v2i32(<2 x i32> %a, <2 x i32> ) + ret { <2 x i32>, <2 x i1> } %b +}