diff --git a/llvm/test/Transforms/InstCombine/binop-and-shifts.ll b/llvm/test/Transforms/InstCombine/binop-and-shifts.ll --- a/llvm/test/Transforms/InstCombine/binop-and-shifts.ll +++ b/llvm/test/Transforms/InstCombine/binop-and-shifts.ll @@ -549,3 +549,350 @@ %bw1 = and i8 %shift1, %bw2 ret i8 %bw1 } + + +define i8 @lshr_ors_x9_noconsts(i8 %amt, i8 %x, i8 %y, i8 %z0, i8 %z1, i8 %z2, i8 %z3, i8 %z4, i8 %z5, i8 %z6, i8 %z7, i8 %z8, i8 %z9) { +; CHECK-LABEL: @lshr_ors_x9_noconsts( +; CHECK-NEXT: [[SX:%.*]] = lshr i8 [[X:%.*]], [[AMT:%.*]] +; CHECK-NEXT: [[SY:%.*]] = lshr i8 [[Y:%.*]], [[AMT]] +; CHECK-NEXT: [[X0:%.*]] = or i8 [[SX]], [[Z0:%.*]] +; CHECK-NEXT: [[X1:%.*]] = or i8 [[X0]], [[Z1:%.*]] +; CHECK-NEXT: [[X2:%.*]] = or i8 [[X1]], [[Z2:%.*]] +; CHECK-NEXT: [[X3:%.*]] = or i8 [[X2]], [[Z3:%.*]] +; CHECK-NEXT: [[X4:%.*]] = or i8 [[X3]], [[Z4:%.*]] +; CHECK-NEXT: [[X5:%.*]] = or i8 [[X4]], [[Z5:%.*]] +; CHECK-NEXT: [[X6:%.*]] = or i8 [[X5]], [[Z6:%.*]] +; CHECK-NEXT: [[X7:%.*]] = or i8 [[X6]], [[Z7:%.*]] +; CHECK-NEXT: [[X8:%.*]] = or i8 [[X7]], [[Z8:%.*]] +; CHECK-NEXT: [[X9:%.*]] = or i8 [[X8]], [[Z9:%.*]] +; CHECK-NEXT: [[R:%.*]] = or i8 [[SY]], [[X9]] +; CHECK-NEXT: ret i8 [[R]] +; + %sx = lshr i8 %x, %amt + %sy = lshr i8 %y, %amt + %x0 = or i8 %sx, %z0 + %x1 = or i8 %x0, %z1 + %x2 = or i8 %x1, %z2 + %x3 = or i8 %x2, %z3 + %x4 = or i8 %x3, %z4 + %x5 = or i8 %x4, %z5 + %x6 = or i8 %x5, %z6 + %x7 = or i8 %x6, %z7 + %x8 = or i8 %x7, %z8 + %x9 = or i8 %x8, %z9 + %r = or i8 %sy, %x9 + ret i8 %r +} + +define i8 @shl_xors_x8_noconsts(i8 %amt, i8 %x, i8 %y, i8 %z0, i8 %z1, i8 %z2, i8 %z3, i8 %z4, i8 %z5, i8 %z6, i8 %z7, i8 %z8, i8 %z9) { +; CHECK-LABEL: @shl_xors_x8_noconsts( +; CHECK-NEXT: [[SX:%.*]] = shl i8 [[X:%.*]], [[AMT:%.*]] +; CHECK-NEXT: [[SY:%.*]] = shl i8 [[Y:%.*]], [[AMT]] +; CHECK-NEXT: [[X0:%.*]] = xor i8 [[SX]], [[Z0:%.*]] +; CHECK-NEXT: [[X1:%.*]] = xor i8 [[X0]], [[Z1:%.*]] +; CHECK-NEXT: [[X2:%.*]] = xor i8 [[X1]], [[Z2:%.*]] +; CHECK-NEXT: [[X3:%.*]] = xor i8 [[X2]], [[Z3:%.*]] +; CHECK-NEXT: [[X4:%.*]] = xor i8 [[X3]], [[Z4:%.*]] +; CHECK-NEXT: [[X5:%.*]] = xor i8 [[X4]], [[Z5:%.*]] +; CHECK-NEXT: [[X6:%.*]] = xor i8 [[X5]], [[Z6:%.*]] +; CHECK-NEXT: [[X7:%.*]] = xor i8 [[X6]], [[Z7:%.*]] +; CHECK-NEXT: [[X8:%.*]] = xor i8 [[X7]], [[Z8:%.*]] +; CHECK-NEXT: [[Y9:%.*]] = xor i8 [[SY]], [[Z9:%.*]] +; CHECK-NEXT: [[R:%.*]] = xor i8 [[Y9]], [[X8]] +; CHECK-NEXT: ret i8 [[R]] +; + %sx = shl i8 %x, %amt + %sy = shl i8 %y, %amt + %x0 = xor i8 %sx, %z0 + %x1 = xor i8 %x0, %z1 + %x2 = xor i8 %x1, %z2 + %x3 = xor i8 %x2, %z3 + %x4 = xor i8 %x3, %z4 + %x5 = xor i8 %x4, %z5 + %x6 = xor i8 %x5, %z6 + %x7 = xor i8 %x6, %z7 + %x8 = xor i8 %x7, %z8 + %y9 = xor i8 %sy, %z9 + %r = xor i8 %y9, %x8 + ret i8 %r +} + +define i8 @lshr_ands_x7_noconsts(i8 %amt, i8 %x, i8 %y, i8 %z0, i8 %z1, i8 %z2, i8 %z3, i8 %z4, i8 %z5, i8 %z6, i8 %z7, i8 %z8, i8 %z9) { +; CHECK-LABEL: @lshr_ands_x7_noconsts( +; CHECK-NEXT: [[SX:%.*]] = lshr i8 [[X:%.*]], [[AMT:%.*]] +; CHECK-NEXT: [[SY:%.*]] = lshr i8 [[Y:%.*]], [[AMT]] +; CHECK-NEXT: [[X0:%.*]] = and i8 [[SX]], [[Z0:%.*]] +; CHECK-NEXT: [[X1:%.*]] = and i8 [[X0]], [[Z1:%.*]] +; CHECK-NEXT: [[X2:%.*]] = and i8 [[X1]], [[Z2:%.*]] +; CHECK-NEXT: [[X3:%.*]] = and i8 [[X2]], [[Z3:%.*]] +; CHECK-NEXT: [[X4:%.*]] = and i8 [[X3]], [[Z4:%.*]] +; CHECK-NEXT: [[X5:%.*]] = and i8 [[X4]], [[Z5:%.*]] +; CHECK-NEXT: [[X6:%.*]] = and i8 [[X5]], [[Z6:%.*]] +; CHECK-NEXT: [[X7:%.*]] = and i8 [[X6]], [[Z7:%.*]] +; CHECK-NEXT: [[Y8:%.*]] = and i8 [[SY]], [[Z8:%.*]] +; CHECK-NEXT: [[Y9:%.*]] = and i8 [[Y8]], [[Z9:%.*]] +; CHECK-NEXT: [[R:%.*]] = and i8 [[X7]], [[Y9]] +; CHECK-NEXT: ret i8 [[R]] +; + %sx = lshr i8 %x, %amt + %sy = lshr i8 %y, %amt + %x0 = and i8 %sx, %z0 + %x1 = and i8 %x0, %z1 + %x2 = and i8 %x1, %z2 + %x3 = and i8 %x2, %z3 + %x4 = and i8 %x3, %z4 + %x5 = and i8 %x4, %z5 + %x6 = and i8 %x5, %z6 + %x7 = and i8 %x6, %z7 + %y8 = and i8 %sy, %z8 + %y9 = and i8 %y8, %z9 + %r = and i8 %x7, %y9 + ret i8 %r +} + +define i8 @shl_adds_x6_noconsts(i8 %amt, i8 %x, i8 %y, i8 %z0, i8 %z1, i8 %z2, i8 %z3, i8 %z4, i8 %z5, i8 %z6, i8 %z7, i8 %z8, i8 %z9) { +; CHECK-LABEL: @shl_adds_x6_noconsts( +; CHECK-NEXT: [[SX:%.*]] = shl i8 [[X:%.*]], [[AMT:%.*]] +; CHECK-NEXT: [[SY:%.*]] = shl i8 [[Y:%.*]], [[AMT]] +; CHECK-NEXT: [[X0:%.*]] = add i8 [[SX]], [[Z0:%.*]] +; CHECK-NEXT: [[X1:%.*]] = add i8 [[X0]], [[Z1:%.*]] +; CHECK-NEXT: [[X2:%.*]] = add i8 [[X1]], [[Z2:%.*]] +; CHECK-NEXT: [[X3:%.*]] = add i8 [[X2]], [[Z3:%.*]] +; CHECK-NEXT: [[X4:%.*]] = add i8 [[X3]], [[Z4:%.*]] +; CHECK-NEXT: [[X5:%.*]] = add i8 [[X4]], [[Z5:%.*]] +; CHECK-NEXT: [[X6:%.*]] = add i8 [[X5]], [[Z6:%.*]] +; CHECK-NEXT: [[Y7:%.*]] = add i8 [[SY]], [[Z7:%.*]] +; CHECK-NEXT: [[Y8:%.*]] = add i8 [[Y7]], [[Z8:%.*]] +; CHECK-NEXT: [[Y9:%.*]] = add i8 [[Y8]], [[Z9:%.*]] +; CHECK-NEXT: [[R:%.*]] = add i8 [[X6]], [[Y9]] +; CHECK-NEXT: ret i8 [[R]] +; + %sx = shl i8 %x, %amt + %sy = shl i8 %y, %amt + %x0 = add i8 %sx, %z0 + %x1 = add i8 %x0, %z1 + %x2 = add i8 %x1, %z2 + %x3 = add i8 %x2, %z3 + %x4 = add i8 %x3, %z4 + %x5 = add i8 %x4, %z5 + %x6 = add i8 %x5, %z6 + %y7 = add i8 %sy, %z7 + %y8 = add i8 %y7, %z8 + %y9 = add i8 %y8, %z9 + %r = add i8 %x6, %y9 + ret i8 %r +} + +define i8 @shl_adds_x5(i8 %amt, i8 %x, i8 %y, i8 %z0, i8 %z1, i8 %z2, i8 %z3, i8 %z4, i8 %z5, i8 %z6, i8 %z7, i8 %z8, i8 %z9) { +; CHECK-LABEL: @shl_adds_x5( +; CHECK-NEXT: [[SX:%.*]] = shl i8 [[X:%.*]], [[AMT:%.*]] +; CHECK-NEXT: [[SY:%.*]] = shl i8 [[Y:%.*]], [[AMT]] +; CHECK-NEXT: [[X0:%.*]] = add i8 [[SX]], [[Z0:%.*]] +; CHECK-NEXT: [[X1:%.*]] = add i8 [[X0]], 88 +; CHECK-NEXT: [[X2:%.*]] = add i8 [[X1]], [[Z2:%.*]] +; CHECK-NEXT: [[X4:%.*]] = add i8 [[X2]], -46 +; CHECK-NEXT: [[X5:%.*]] = add i8 [[X4]], [[Z5:%.*]] +; CHECK-NEXT: [[Y7:%.*]] = add i8 [[SY]], -23 +; CHECK-NEXT: [[Y8:%.*]] = add i8 [[Y7]], [[Z8:%.*]] +; CHECK-NEXT: [[Y9:%.*]] = add i8 [[Y8]], 22 +; CHECK-NEXT: [[R:%.*]] = add i8 [[X5]], [[Y9]] +; CHECK-NEXT: ret i8 [[R]] +; + %sx = shl i8 %x, %amt + %sy = shl i8 %y, %amt + %x0 = add i8 %sx, %z0 + %x1 = add i8 %x0, 88 + %x2 = add i8 %x1, %z2 + %x3 = add i8 %x2, 99 + %x4 = add i8 %x3, 111 + %x5 = add i8 %x4, %z5 + %y6 = add i8 %sy, 222 + %y7 = add i8 %y6, 11 + %y8 = add i8 %y7, %z8 + %y9 = add i8 %y8, 22 + %r = add i8 %x5, %y9 + ret i8 %r +} + +declare void @use.i8(i8) +define i8 @lshr_ors_x9_noconsts_fail_multiuse1(i8 %amt, i8 %x, i8 %y, i8 %z0, i8 %z1, i8 %z2, i8 %z3, i8 %z4, i8 %z5, i8 %z6, i8 %z7, i8 %z8, i8 %z9) { +; CHECK-LABEL: @lshr_ors_x9_noconsts_fail_multiuse1( +; CHECK-NEXT: [[SX:%.*]] = lshr i8 [[X:%.*]], [[AMT:%.*]] +; CHECK-NEXT: [[SY:%.*]] = lshr i8 [[Y:%.*]], [[AMT]] +; CHECK-NEXT: [[X0:%.*]] = or i8 [[SX]], [[Z0:%.*]] +; CHECK-NEXT: [[X1:%.*]] = or i8 [[X0]], [[Z1:%.*]] +; CHECK-NEXT: [[X2:%.*]] = or i8 [[X1]], [[Z2:%.*]] +; CHECK-NEXT: [[X3:%.*]] = or i8 [[X2]], [[Z3:%.*]] +; CHECK-NEXT: [[X4:%.*]] = or i8 [[X3]], [[Z4:%.*]] +; CHECK-NEXT: [[X5:%.*]] = or i8 [[X4]], [[Z5:%.*]] +; CHECK-NEXT: [[X6:%.*]] = or i8 [[X5]], [[Z6:%.*]] +; CHECK-NEXT: [[X7:%.*]] = or i8 [[X6]], [[Z7:%.*]] +; CHECK-NEXT: [[X8:%.*]] = or i8 [[X7]], [[Z8:%.*]] +; CHECK-NEXT: [[TMP1:%.*]] = or i8 [[SY]], [[Z9:%.*]] +; CHECK-NEXT: [[R:%.*]] = or i8 [[TMP1]], [[X8]] +; CHECK-NEXT: call void @use.i8(i8 [[X8]]) +; CHECK-NEXT: ret i8 [[R]] +; + %sx = lshr i8 %x, %amt + %sy = lshr i8 %y, %amt + %x0 = or i8 %sx, %z0 + %x1 = or i8 %x0, %z1 + %x2 = or i8 %x1, %z2 + %x3 = or i8 %x2, %z3 + %x4 = or i8 %x3, %z4 + %x5 = or i8 %x4, %z5 + %x6 = or i8 %x5, %z6 + %x7 = or i8 %x6, %z7 + %x8 = or i8 %x7, %z8 + %x9 = or i8 %x8, %z9 + %r = or i8 %sy, %x9 + call void @use.i8(i8 %x8) + ret i8 %r +} + +define i8 @shl_adds_x5_fail_multiuse2(i8 %amt, i8 %x, i8 %y, i8 %z0, i8 %z1, i8 %z2, i8 %z3, i8 %z4, i8 %z5, i8 %z6, i8 %z7, i8 %z8, i8 %z9) { +; CHECK-LABEL: @shl_adds_x5_fail_multiuse2( +; CHECK-NEXT: [[SX:%.*]] = shl i8 [[X:%.*]], [[AMT:%.*]] +; CHECK-NEXT: [[SY:%.*]] = shl i8 [[Y:%.*]], [[AMT]] +; CHECK-NEXT: [[X0:%.*]] = add i8 [[SX]], [[Z0:%.*]] +; CHECK-NEXT: [[X1:%.*]] = add i8 [[X0]], 88 +; CHECK-NEXT: [[X2:%.*]] = add i8 [[X1]], [[Z2:%.*]] +; CHECK-NEXT: [[X4:%.*]] = add i8 [[X2]], -46 +; CHECK-NEXT: [[X5:%.*]] = add i8 [[X4]], [[Z5:%.*]] +; CHECK-NEXT: [[Y7:%.*]] = add i8 [[SY]], -23 +; CHECK-NEXT: [[Y8:%.*]] = add i8 [[Y7]], [[Z8:%.*]] +; CHECK-NEXT: [[Y9:%.*]] = add i8 [[Y8]], 22 +; CHECK-NEXT: call void @use.i8(i8 [[SY]]) +; CHECK-NEXT: [[R:%.*]] = add i8 [[X5]], [[Y9]] +; CHECK-NEXT: ret i8 [[R]] +; + %sx = shl i8 %x, %amt + %sy = shl i8 %y, %amt + %x0 = add i8 %sx, %z0 + %x1 = add i8 %x0, 88 + %x2 = add i8 %x1, %z2 + %x3 = add i8 %x2, 99 + %x4 = add i8 %x3, 111 + %x5 = add i8 %x4, %z5 + %y6 = add i8 %sy, 222 + %y7 = add i8 %y6, 11 + %y8 = add i8 %y7, %z8 + %y9 = add i8 %y8, 22 + call void @use.i8(i8 %sy) + %r = add i8 %x5, %y9 + ret i8 %r +} + +define <2 x i8> @shl_xor_add_and_fail(<2 x i8> %x, <2 x i8> %y) { +; CHECK-LABEL: @shl_xor_add_and_fail( +; CHECK-NEXT: [[SHIFT1:%.*]] = shl <2 x i8> [[X:%.*]], +; CHECK-NEXT: [[SHIFT2:%.*]] = shl <2 x i8> [[Y:%.*]], +; CHECK-NEXT: [[BW3:%.*]] = xor <2 x i8> [[SHIFT1]], +; CHECK-NEXT: [[BW2:%.*]] = add <2 x i8> [[BW3]], +; CHECK-NEXT: [[BW1:%.*]] = and <2 x i8> [[SHIFT2]], [[BW2]] +; CHECK-NEXT: ret <2 x i8> [[BW1]] +; + %shift1 = shl <2 x i8> %x, + %shift2 = shl <2 x i8> %y, + %bw3 = xor <2 x i8> %shift1, + %bw2 = add <2 x i8> %bw3, + %bw1 = and <2 x i8> %shift2, %bw2 + ret <2 x i8> %bw1 +} + + +define <2 x i8> @shl_xor_add_and(<2 x i8> %x, <2 x i8> %y) { +; CHECK-LABEL: @shl_xor_add_and( +; CHECK-NEXT: [[SHIFT1:%.*]] = shl <2 x i8> [[X:%.*]], +; CHECK-NEXT: [[SHIFT2:%.*]] = shl <2 x i8> [[Y:%.*]], +; CHECK-NEXT: [[BW3:%.*]] = xor <2 x i8> [[SHIFT1]], +; CHECK-NEXT: [[BW2:%.*]] = add <2 x i8> [[BW3]], +; CHECK-NEXT: [[BW1:%.*]] = and <2 x i8> [[SHIFT2]], [[BW2]] +; CHECK-NEXT: ret <2 x i8> [[BW1]] +; + %shift1 = shl <2 x i8> %x, + %shift2 = shl <2 x i8> %y, + %bw3 = xor <2 x i8> %shift1, + %bw2 = add <2 x i8> %bw3, + %bw1 = and <2 x i8> %shift2, %bw2 + ret <2 x i8> %bw1 +} + + +define <2 x i8> @shl_xor_or_add_xor(<2 x i8> %x, <2 x i8> %y) { +; CHECK-LABEL: @shl_xor_or_add_xor( +; CHECK-NEXT: [[SHIFT1:%.*]] = shl <2 x i8> [[X:%.*]], +; CHECK-NEXT: [[SHIFT2:%.*]] = shl <2 x i8> [[Y:%.*]], +; CHECK-NEXT: [[BW3:%.*]] = xor <2 x i8> [[SHIFT1]], +; CHECK-NEXT: [[BW2:%.*]] = or <2 x i8> [[BW3]], +; CHECK-NEXT: [[BW1:%.*]] = add <2 x i8> [[SHIFT2]], +; CHECK-NEXT: [[BW0:%.*]] = xor <2 x i8> [[BW1]], [[BW2]] +; CHECK-NEXT: ret <2 x i8> [[BW0]] +; + %shift1 = shl <2 x i8> %x, + %shift2 = shl <2 x i8> %y, + %bw3 = xor <2 x i8> %shift1, + %bw2 = or <2 x i8> %bw3, + %bw1 = add <2 x i8> %shift2, + %bw0 = xor <2 x i8> %bw1, %bw2 + ret <2 x i8> %bw0 +} + + +define <2 x i8> @lshr_xor_or_add_and_fail(<2 x i8> %x, <2 x i8> %y) { +; CHECK-LABEL: @lshr_xor_or_add_and_fail( +; CHECK-NEXT: [[SHIFT1:%.*]] = lshr <2 x i8> [[X:%.*]], +; CHECK-NEXT: [[SHIFT2:%.*]] = lshr <2 x i8> [[Y:%.*]], +; CHECK-NEXT: [[BW3:%.*]] = xor <2 x i8> [[SHIFT1]], +; CHECK-NEXT: [[BW2:%.*]] = or <2 x i8> [[BW3]], +; CHECK-NEXT: [[BW1:%.*]] = add nuw <2 x i8> [[SHIFT2]], +; CHECK-NEXT: [[BW0:%.*]] = and <2 x i8> [[BW1]], [[BW2]] +; CHECK-NEXT: ret <2 x i8> [[BW0]] +; + %shift1 = lshr <2 x i8> %x, + %shift2 = lshr <2 x i8> %y, + %bw3 = xor <2 x i8> %shift1, + %bw2 = or <2 x i8> %bw3, + %bw1 = add <2 x i8> %shift2, + %bw0 = and <2 x i8> %bw1, %bw2 + ret <2 x i8> %bw0 +} + +define <2 x i8> @shl_xor_or_add_and(<2 x i8> %x, <2 x i8> %y) { +; CHECK-LABEL: @shl_xor_or_add_and( +; CHECK-NEXT: [[SHIFT1:%.*]] = shl <2 x i8> [[X:%.*]], +; CHECK-NEXT: [[SHIFT2:%.*]] = shl <2 x i8> [[Y:%.*]], +; CHECK-NEXT: [[BW3:%.*]] = xor <2 x i8> [[SHIFT1]], +; CHECK-NEXT: [[BW2:%.*]] = or <2 x i8> [[BW3]], +; CHECK-NEXT: [[BW1:%.*]] = add <2 x i8> [[SHIFT2]], +; CHECK-NEXT: [[BW0:%.*]] = and <2 x i8> [[BW1]], [[BW2]] +; CHECK-NEXT: ret <2 x i8> [[BW0]] +; + %shift1 = shl <2 x i8> %x, + %shift2 = shl <2 x i8> %y, + %bw3 = xor <2 x i8> %shift1, + %bw2 = or <2 x i8> %bw3, + %bw1 = add <2 x i8> %shift2, + %bw0 = and <2 x i8> %bw1, %bw2 + ret <2 x i8> %bw0 +} + + +define <2 x i8> @shl_xor_and_add_and_fail(<2 x i8> %x, <2 x i8> %y) { +; CHECK-LABEL: @shl_xor_and_add_and_fail( +; CHECK-NEXT: [[SHIFT1:%.*]] = shl <2 x i8> [[X:%.*]], +; CHECK-NEXT: [[SHIFT2:%.*]] = shl <2 x i8> [[Y:%.*]], +; CHECK-NEXT: [[BW3:%.*]] = xor <2 x i8> [[SHIFT1]], +; CHECK-NEXT: [[BW2:%.*]] = and <2 x i8> [[BW3]], +; CHECK-NEXT: [[BW1:%.*]] = add <2 x i8> [[SHIFT2]], +; CHECK-NEXT: [[BW0:%.*]] = and <2 x i8> [[BW1]], [[BW2]] +; CHECK-NEXT: ret <2 x i8> [[BW0]] +; + %shift1 = shl <2 x i8> %x, + %shift2 = shl <2 x i8> %y, + %bw3 = xor <2 x i8> %shift1, + %bw2 = and <2 x i8> %bw3, + %bw1 = add <2 x i8> %shift2, + %bw0 = and <2 x i8> %bw1, %bw2 + ret <2 x i8> %bw0 +}