167 lines · plain
1; NOTE: Assertions have been autogenerated by utils/update_test_checks.py2; RUN: opt -passes=instcombine -S < %s | FileCheck %s3 4; Given:5; icmp eq/ne (urem %x, C), 06; Iff C is not a power of two (those should not get to here though),7; and %x may have at most one bit set, omit the 'urem':8; icmp eq/ne %x, 09 10;------------------------------------------------------------------------------;11; Basic scalar tests12;------------------------------------------------------------------------------;13 14define i1 @p0_scalar_urem_by_const(i32 %x, i32 %y) {15; CHECK-LABEL: @p0_scalar_urem_by_const(16; CHECK-NEXT: [[T0:%.*]] = and i32 [[X:%.*]], 12817; CHECK-NEXT: [[T2:%.*]] = icmp eq i32 [[T0]], 018; CHECK-NEXT: ret i1 [[T2]]19;20 %t0 = and i32 %x, 128 ; clearly a power-of-two or zero21 %t1 = urem i32 %t0, 6 ; '6' is clearly not a power of two22 %t2 = icmp eq i32 %t1, 023 ret i1 %t224}25 26define i1 @p1_scalar_urem_by_nonconst(i32 %x, i32 %y) {27; CHECK-LABEL: @p1_scalar_urem_by_nonconst(28; CHECK-NEXT: [[T0:%.*]] = and i32 [[X:%.*]], 12829; CHECK-NEXT: [[T3:%.*]] = icmp eq i32 [[T0]], 030; CHECK-NEXT: ret i1 [[T3]]31;32 %t0 = and i32 %x, 128 ; clearly a power-of-two or zero33 %t1 = or i32 %y, 6 ; two bits set, clearly not a power of two34 %t2 = urem i32 %t0, %t135 %t3 = icmp eq i32 %t2, 036 ret i1 %t337}38 39define i1 @p2_scalar_shifted_urem_by_const(i32 %x, i32 %y) {40; CHECK-LABEL: @p2_scalar_shifted_urem_by_const(41; CHECK-NEXT: [[T0:%.*]] = and i32 [[X:%.*]], 142; CHECK-NEXT: [[T1:%.*]] = shl nuw i32 [[T0]], [[Y:%.*]]43; CHECK-NEXT: [[T2:%.*]] = urem i32 [[T1]], 344; CHECK-NEXT: [[T3:%.*]] = icmp eq i32 [[T2]], 045; CHECK-NEXT: ret i1 [[T3]]46;47 %t0 = and i32 %x, 1 ; clearly a power-of-two or zero48 %t1 = shl i32 %t0, %y ; will still be a power-of-two or zero with any %y49 %t2 = urem i32 %t1, 3 ; '3' is clearly not a power of two50 %t3 = icmp eq i32 %t2, 051 ret i1 %t352}53 54define i1 @p3_scalar_shifted2_urem_by_const(i32 %x, i32 %y) {55; CHECK-LABEL: @p3_scalar_shifted2_urem_by_const(56; CHECK-NEXT: [[T0:%.*]] = and i32 [[X:%.*]], 257; CHECK-NEXT: [[T1:%.*]] = shl i32 [[T0]], [[Y:%.*]]58; CHECK-NEXT: [[T2:%.*]] = urem i32 [[T1]], 359; CHECK-NEXT: [[T3:%.*]] = icmp eq i32 [[T2]], 060; CHECK-NEXT: ret i1 [[T3]]61;62 %t0 = and i32 %x, 2 ; clearly a power-of-two or zero63 %t1 = shl i32 %t0, %y ; will still be a power-of-two or zero with any %y64 %t2 = urem i32 %t1, 3 ; '3' is clearly not a power of two65 %t3 = icmp eq i32 %t2, 066 ret i1 %t367}68 69;------------------------------------------------------------------------------;70; Basic vector tests71;------------------------------------------------------------------------------;72 73define <4 x i1> @p4_vector_urem_by_const__splat(<4 x i32> %x, <4 x i32> %y) {74; CHECK-LABEL: @p4_vector_urem_by_const__splat(75; CHECK-NEXT: [[T0:%.*]] = and <4 x i32> [[X:%.*]], splat (i32 128)76; CHECK-NEXT: [[T2:%.*]] = icmp eq <4 x i32> [[T0]], zeroinitializer77; CHECK-NEXT: ret <4 x i1> [[T2]]78;79 %t0 = and <4 x i32> %x, <i32 128, i32 128, i32 128, i32 128> ; clearly a power-of-two or zero80 %t1 = urem <4 x i32> %t0, <i32 6, i32 6, i32 6, i32 6> ; '6' is clearly not a power of two81 %t2 = icmp eq <4 x i32> %t1, <i32 0, i32 0, i32 0, i32 0>82 ret <4 x i1> %t283}84 85define <4 x i1> @p5_vector_urem_by_const__nonsplat(<4 x i32> %x, <4 x i32> %y) {86; CHECK-LABEL: @p5_vector_urem_by_const__nonsplat(87; CHECK-NEXT: [[T0:%.*]] = and <4 x i32> [[X:%.*]], <i32 128, i32 2, i32 4, i32 8>88; CHECK-NEXT: [[T1:%.*]] = urem <4 x i32> [[T0]], <i32 3, i32 5, i32 6, i32 9>89; CHECK-NEXT: [[T2:%.*]] = icmp eq <4 x i32> [[T1]], zeroinitializer90; CHECK-NEXT: ret <4 x i1> [[T2]]91;92 %t0 = and <4 x i32> %x, <i32 128, i32 2, i32 4, i32 8>93 %t1 = urem <4 x i32> %t0, <i32 3, i32 5, i32 6, i32 9>94 %t2 = icmp eq <4 x i32> %t1, <i32 0, i32 0, i32 0, i32 0>95 ret <4 x i1> %t296}97 98; The poison value in the vector makes the whole function UB.99 100define <4 x i1> @p6_vector_urem_by_const__nonsplat_poison0(<4 x i32> %x, <4 x i32> %y) {101; CHECK-LABEL: @p6_vector_urem_by_const__nonsplat_poison0(102; CHECK-NEXT: [[T0:%.*]] = and <4 x i32> [[X:%.*]], <i32 128, i32 128, i32 poison, i32 128>103; CHECK-NEXT: [[T2:%.*]] = icmp eq <4 x i32> [[T0]], zeroinitializer104; CHECK-NEXT: ret <4 x i1> [[T2]]105;106 %t0 = and <4 x i32> %x, <i32 128, i32 128, i32 poison, i32 128>107 %t1 = urem <4 x i32> %t0, <i32 6, i32 6, i32 6, i32 6> ; '6' is clearly not a power of two108 %t2 = icmp eq <4 x i32> %t1, <i32 0, i32 0, i32 0, i32 0>109 ret <4 x i1> %t2110}111 112define <4 x i1> @p7_vector_urem_by_const__nonsplat_poison2(<4 x i32> %x, <4 x i32> %y) {113; CHECK-LABEL: @p7_vector_urem_by_const__nonsplat_poison2(114; CHECK-NEXT: [[T0:%.*]] = and <4 x i32> [[X:%.*]], splat (i32 128)115; CHECK-NEXT: [[T2:%.*]] = icmp eq <4 x i32> [[T0]], <i32 0, i32 0, i32 poison, i32 0>116; CHECK-NEXT: ret <4 x i1> [[T2]]117;118 %t0 = and <4 x i32> %x, <i32 128, i32 128, i32 128, i32 128> ; clearly a power-of-two or zero119 %t1 = urem <4 x i32> %t0, <i32 6, i32 6, i32 6, i32 6> ; '6' is clearly not a power of two120 %t2 = icmp eq <4 x i32> %t1, <i32 0, i32 0, i32 poison, i32 0>121 ret <4 x i1> %t2122}123 124define <4 x i1> @p8_vector_urem_by_const__nonsplat_poison3(<4 x i32> %x, <4 x i32> %y) {125; CHECK-LABEL: @p8_vector_urem_by_const__nonsplat_poison3(126; CHECK-NEXT: [[T0:%.*]] = and <4 x i32> [[X:%.*]], <i32 128, i32 128, i32 poison, i32 128>127; CHECK-NEXT: [[T2:%.*]] = icmp eq <4 x i32> [[T0]], <i32 0, i32 0, i32 poison, i32 0>128; CHECK-NEXT: ret <4 x i1> [[T2]]129;130 %t0 = and <4 x i32> %x, <i32 128, i32 128, i32 poison, i32 128>131 %t1 = urem <4 x i32> %t0, <i32 6, i32 6, i32 6, i32 6> ; '6' is clearly not a power of two132 %t2 = icmp eq <4 x i32> %t1, <i32 0, i32 0, i32 poison, i32 0>133 ret <4 x i1> %t2134}135 136;------------------------------------------------------------------------------;137; Basic negative tests138;------------------------------------------------------------------------------;139 140define i1 @n0_urem_of_maybe_not_power_of_two(i32 %x, i32 %y) {141; CHECK-LABEL: @n0_urem_of_maybe_not_power_of_two(142; CHECK-NEXT: [[T0:%.*]] = and i32 [[X:%.*]], 3143; CHECK-NEXT: [[T1:%.*]] = urem i32 [[T0]], 3144; CHECK-NEXT: [[T2:%.*]] = icmp eq i32 [[T1]], 0145; CHECK-NEXT: ret i1 [[T2]]146;147 %t0 = and i32 %x, 3 ; up to two bits set, not power-of-two148 %t1 = urem i32 %t0, 3149 %t2 = icmp eq i32 %t1, 0150 ret i1 %t2151}152 153define i1 @n1_urem_by_maybe_power_of_two(i32 %x, i32 %y) {154; CHECK-LABEL: @n1_urem_by_maybe_power_of_two(155; CHECK-NEXT: [[T0:%.*]] = and i32 [[X:%.*]], 128156; CHECK-NEXT: [[T1:%.*]] = or i32 [[Y:%.*]], 1157; CHECK-NEXT: [[T2:%.*]] = urem i32 [[T0]], [[T1]]158; CHECK-NEXT: [[T3:%.*]] = icmp eq i32 [[T2]], 0159; CHECK-NEXT: ret i1 [[T3]]160;161 %t0 = and i32 %x, 128 ; clearly a power-of-two or zero162 %t1 = or i32 %y, 1 ; one low bit set, may be a power of two163 %t2 = urem i32 %t0, %t1164 %t3 = icmp eq i32 %t2, 0165 ret i1 %t3166}167