[llvm] r312938 - [InstSimplify] add tests for possible sdiv/srem simplifications; NFC

Sanjay Patel via llvm-commits llvm-commits at lists.llvm.org
Mon Sep 11 12:42:41 PDT 2017


Author: spatel
Date: Mon Sep 11 12:42:41 2017
New Revision: 312938

URL: http://llvm.org/viewvc/llvm-project?rev=312938&view=rev
Log:
[InstSimplify] add tests for possible sdiv/srem simplifications; NFC

As noted in PR34517, the handling of signed div/rem is not on par with
unsigned div/rem. Signed is harder to reason about, but it should be
possible to handle at least some of these using the same technique that
we use for unsigned: use icmp logic to see if there's a relationship
between the quotient and divisor.

Added:
    llvm/trunk/test/Transforms/InstSimplify/signed-div-rem.ll

Added: llvm/trunk/test/Transforms/InstSimplify/signed-div-rem.ll
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/test/Transforms/InstSimplify/signed-div-rem.ll?rev=312938&view=auto
==============================================================================
--- llvm/trunk/test/Transforms/InstSimplify/signed-div-rem.ll (added)
+++ llvm/trunk/test/Transforms/InstSimplify/signed-div-rem.ll Mon Sep 11 12:42:41 2017
@@ -0,0 +1,354 @@
+; RUN: opt < %s -instsimplify -S | FileCheck %s
+
+define i32 @sdiv_sext_big_divisor(i8 %x) {
+; CHECK-LABEL: @sdiv_sext_big_divisor(
+; CHECK-NEXT:    [[CONV:%.*]] = sext i8 %x to i32
+; CHECK-NEXT:    [[DIV:%.*]] = sdiv i32 [[CONV]], 129
+; CHECK-NEXT:    ret i32 [[DIV]]
+;
+  %conv = sext i8 %x to i32
+  %div = sdiv i32 %conv, 129
+  ret i32 %div
+}
+
+define i32 @not_sdiv_sext_big_divisor(i8 %x) {
+; CHECK-LABEL: @not_sdiv_sext_big_divisor(
+; CHECK-NEXT:    [[CONV:%.*]] = sext i8 %x to i32
+; CHECK-NEXT:    [[DIV:%.*]] = sdiv i32 [[CONV]], 128
+; CHECK-NEXT:    ret i32 [[DIV]]
+;
+  %conv = sext i8 %x to i32
+  %div = sdiv i32 %conv, 128
+  ret i32 %div
+}
+
+define i32 @sdiv_sext_small_divisor(i8 %x) {
+; CHECK-LABEL: @sdiv_sext_small_divisor(
+; CHECK-NEXT:    [[CONV:%.*]] = sext i8 %x to i32
+; CHECK-NEXT:    [[DIV:%.*]] = sdiv i32 [[CONV]], -129
+; CHECK-NEXT:    ret i32 [[DIV]]
+;
+  %conv = sext i8 %x to i32
+  %div = sdiv i32 %conv, -129
+  ret i32 %div
+}
+
+define i32 @not_sdiv_sext_small_divisor(i8 %x) {
+; CHECK-LABEL: @not_sdiv_sext_small_divisor(
+; CHECK-NEXT:    [[CONV:%.*]] = sext i8 %x to i32
+; CHECK-NEXT:    [[DIV:%.*]] = sdiv i32 [[CONV]], -128
+; CHECK-NEXT:    ret i32 [[DIV]]
+;
+  %conv = sext i8 %x to i32
+  %div = sdiv i32 %conv, -128
+  ret i32 %div
+}
+
+define i32 @sdiv_zext_big_divisor(i8 %x) {
+; CHECK-LABEL: @sdiv_zext_big_divisor(
+; CHECK-NEXT:    [[CONV:%.*]] = zext i8 %x to i32
+; CHECK-NEXT:    [[DIV:%.*]] = sdiv i32 [[CONV]], 256
+; CHECK-NEXT:    ret i32 [[DIV]]
+;
+  %conv = zext i8 %x to i32
+  %div = sdiv i32 %conv, 256
+  ret i32 %div
+}
+
+define i32 @not_sdiv_zext_big_divisor(i8 %x) {
+; CHECK-LABEL: @not_sdiv_zext_big_divisor(
+; CHECK-NEXT:    [[CONV:%.*]] = zext i8 %x to i32
+; CHECK-NEXT:    [[DIV:%.*]] = sdiv i32 [[CONV]], 255
+; CHECK-NEXT:    ret i32 [[DIV]]
+;
+  %conv = zext i8 %x to i32
+  %div = sdiv i32 %conv, 255
+  ret i32 %div
+}
+
+define i32 @sdiv_zext_small_divisor(i8 %x) {
+; CHECK-LABEL: @sdiv_zext_small_divisor(
+; CHECK-NEXT:    [[CONV:%.*]] = zext i8 %x to i32
+; CHECK-NEXT:    [[DIV:%.*]] = sdiv i32 [[CONV]], -256
+; CHECK-NEXT:    ret i32 [[DIV]]
+;
+  %conv = zext i8 %x to i32
+  %div = sdiv i32 %conv, -256
+  ret i32 %div
+}
+
+define i32 @not_sdiv_zext_small_divisor(i8 %x) {
+; CHECK-LABEL: @not_sdiv_zext_small_divisor(
+; CHECK-NEXT:    [[CONV:%.*]] = zext i8 %x to i32
+; CHECK-NEXT:    [[DIV:%.*]] = sdiv i32 [[CONV]], -255
+; CHECK-NEXT:    ret i32 [[DIV]]
+;
+  %conv = zext i8 %x to i32
+  %div = sdiv i32 %conv, -255
+  ret i32 %div
+}
+
+define i32 @sdiv_quotient_known_smaller_than_pos_divisor_clear_bits(i32 %x) {
+; CHECK-LABEL: @sdiv_quotient_known_smaller_than_pos_divisor_clear_bits(
+; CHECK-NEXT:    [[AND:%.*]] = and i32 %x, 253
+; CHECK-NEXT:    [[DIV:%.*]] = sdiv i32 [[AND]], 254
+; CHECK-NEXT:    ret i32 [[DIV]]
+;
+  %and = and i32 %x, 253
+  %div = sdiv i32 %and, 254
+  ret i32 %div
+}
+
+define i32 @not_sdiv_quotient_known_smaller_than_pos_divisor_clear_bits(i32 %x) {
+; CHECK-LABEL: @not_sdiv_quotient_known_smaller_than_pos_divisor_clear_bits(
+; CHECK-NEXT:    [[AND:%.*]] = and i32 %x, 253
+; CHECK-NEXT:    [[DIV:%.*]] = sdiv i32 [[AND]], 253
+; CHECK-NEXT:    ret i32 [[DIV]]
+;
+  %and = and i32 %x, 253
+  %div = sdiv i32 %and, 253
+  ret i32 %div
+}
+
+define i32 @sdiv_quotient_known_smaller_than_neg_divisor_clear_bits(i32 %x) {
+; CHECK-LABEL: @sdiv_quotient_known_smaller_than_neg_divisor_clear_bits(
+; CHECK-NEXT:    [[AND:%.*]] = and i32 %x, 253
+; CHECK-NEXT:    [[DIV:%.*]] = sdiv i32 [[AND]], -254
+; CHECK-NEXT:    ret i32 [[DIV]]
+;
+  %and = and i32 %x, 253
+  %div = sdiv i32 %and, -254
+  ret i32 %div
+}
+
+define i32 @not_sdiv_quotient_known_smaller_than_neg_divisor_clear_bits(i32 %x) {
+; CHECK-LABEL: @not_sdiv_quotient_known_smaller_than_neg_divisor_clear_bits(
+; CHECK-NEXT:    [[AND:%.*]] = and i32 %x, 253
+; CHECK-NEXT:    [[DIV:%.*]] = sdiv i32 [[AND]], -253
+; CHECK-NEXT:    ret i32 [[DIV]]
+;
+  %and = and i32 %x, 253
+  %div = sdiv i32 %and, -253
+  ret i32 %div
+}
+
+define i32 @sdiv_quotient_known_smaller_than_pos_divisor_set_bits(i32 %x) {
+; CHECK-LABEL: @sdiv_quotient_known_smaller_than_pos_divisor_set_bits(
+; CHECK-NEXT:    [[OR:%.*]] = or i32 %x, -253
+; CHECK-NEXT:    [[DIV:%.*]] = sdiv i32 [[OR]], 254
+; CHECK-NEXT:    ret i32 [[DIV]]
+;
+  %or = or i32 %x, -253
+  %div = sdiv i32 %or, 254
+  ret i32 %div
+}
+
+define i32 @not_sdiv_quotient_known_smaller_than_pos_divisor_set_bits(i32 %x) {
+; CHECK-LABEL: @not_sdiv_quotient_known_smaller_than_pos_divisor_set_bits(
+; CHECK-NEXT:    [[OR:%.*]] = or i32 %x, -253
+; CHECK-NEXT:    [[DIV:%.*]] = sdiv i32 [[OR]], 253
+; CHECK-NEXT:    ret i32 [[DIV]]
+;
+  %or = or i32 %x, -253
+  %div = sdiv i32 %or, 253
+  ret i32 %div
+}
+
+define i32 @sdiv_quotient_known_smaller_than_neg_divisor_set_bits(i32 %x) {
+; CHECK-LABEL: @sdiv_quotient_known_smaller_than_neg_divisor_set_bits(
+; CHECK-NEXT:    [[OR:%.*]] = or i32 %x, -253
+; CHECK-NEXT:    [[DIV:%.*]] = sdiv i32 [[OR]], -254
+; CHECK-NEXT:    ret i32 [[DIV]]
+;
+  %or = or i32 %x, -253
+  %div = sdiv i32 %or, -254
+  ret i32 %div
+}
+
+define i32 @not_sdiv_quotient_known_smaller_than_neg_divisor_set_bits(i32 %x) {
+; CHECK-LABEL: @not_sdiv_quotient_known_smaller_than_neg_divisor_set_bits(
+; CHECK-NEXT:    [[OR:%.*]] = or i32 %x, -253
+; CHECK-NEXT:    [[DIV:%.*]] = sdiv i32 [[OR]], -253
+; CHECK-NEXT:    ret i32 [[DIV]]
+;
+  %or = or i32 %x, -253
+  %div = sdiv i32 %or, -253
+  ret i32 %div
+}
+
+define i32 @srem_sext_big_divisor(i8 %x) {
+; CHECK-LABEL: @srem_sext_big_divisor(
+; CHECK-NEXT:    [[CONV:%.*]] = sext i8 %x to i32
+; CHECK-NEXT:    [[REM:%.*]] = srem i32 [[CONV]], 129
+; CHECK-NEXT:    ret i32 [[REM]]
+;
+  %conv = sext i8 %x to i32
+  %rem = srem i32 %conv, 129
+  ret i32 %rem
+}
+
+define i32 @not_srem_sext_big_divisor(i8 %x) {
+; CHECK-LABEL: @not_srem_sext_big_divisor(
+; CHECK-NEXT:    [[CONV:%.*]] = sext i8 %x to i32
+; CHECK-NEXT:    [[REM:%.*]] = srem i32 [[CONV]], 128
+; CHECK-NEXT:    ret i32 [[REM]]
+;
+  %conv = sext i8 %x to i32
+  %rem = srem i32 %conv, 128
+  ret i32 %rem
+}
+
+define i32 @srem_sext_small_divisor(i8 %x) {
+; CHECK-LABEL: @srem_sext_small_divisor(
+; CHECK-NEXT:    [[CONV:%.*]] = sext i8 %x to i32
+; CHECK-NEXT:    [[REM:%.*]] = srem i32 [[CONV]], -129
+; CHECK-NEXT:    ret i32 [[REM]]
+;
+  %conv = sext i8 %x to i32
+  %rem = srem i32 %conv, -129
+  ret i32 %rem
+}
+
+define i32 @not_srem_sext_small_divisor(i8 %x) {
+; CHECK-LABEL: @not_srem_sext_small_divisor(
+; CHECK-NEXT:    [[CONV:%.*]] = sext i8 %x to i32
+; CHECK-NEXT:    [[REM:%.*]] = srem i32 [[CONV]], -128
+; CHECK-NEXT:    ret i32 [[REM]]
+;
+  %conv = sext i8 %x to i32
+  %rem = srem i32 %conv, -128
+  ret i32 %rem
+}
+
+define i32 @srem_zext_big_divisor(i8 %x) {
+; CHECK-LABEL: @srem_zext_big_divisor(
+; CHECK-NEXT:    [[CONV:%.*]] = zext i8 %x to i32
+; CHECK-NEXT:    [[REM:%.*]] = srem i32 [[CONV]], 256
+; CHECK-NEXT:    ret i32 [[REM]]
+;
+  %conv = zext i8 %x to i32
+  %rem = srem i32 %conv, 256
+  ret i32 %rem
+}
+
+define i32 @not_srem_zext_big_divisor(i8 %x) {
+; CHECK-LABEL: @not_srem_zext_big_divisor(
+; CHECK-NEXT:    [[CONV:%.*]] = zext i8 %x to i32
+; CHECK-NEXT:    [[REM:%.*]] = srem i32 [[CONV]], 255
+; CHECK-NEXT:    ret i32 [[REM]]
+;
+  %conv = zext i8 %x to i32
+  %rem = srem i32 %conv, 255
+  ret i32 %rem
+}
+
+define i32 @srem_zext_small_divisor(i8 %x) {
+; CHECK-LABEL: @srem_zext_small_divisor(
+; CHECK-NEXT:    [[CONV:%.*]] = zext i8 %x to i32
+; CHECK-NEXT:    [[REM:%.*]] = srem i32 [[CONV]], -256
+; CHECK-NEXT:    ret i32 [[REM]]
+;
+  %conv = zext i8 %x to i32
+  %rem = srem i32 %conv, -256
+  ret i32 %rem
+}
+
+define i32 @not_srem_zext_small_divisor(i8 %x) {
+; CHECK-LABEL: @not_srem_zext_small_divisor(
+; CHECK-NEXT:    [[CONV:%.*]] = zext i8 %x to i32
+; CHECK-NEXT:    [[REM:%.*]] = srem i32 [[CONV]], -255
+; CHECK-NEXT:    ret i32 [[REM]]
+;
+  %conv = zext i8 %x to i32
+  %rem = srem i32 %conv, -255
+  ret i32 %rem
+}
+
+define i32 @srem_quotient_known_smaller_than_pos_divisor_clear_bits(i32 %x) {
+; CHECK-LABEL: @srem_quotient_known_smaller_than_pos_divisor_clear_bits(
+; CHECK-NEXT:    [[AND:%.*]] = and i32 %x, 253
+; CHECK-NEXT:    [[REM:%.*]] = srem i32 [[AND]], 254
+; CHECK-NEXT:    ret i32 [[REM]]
+;
+  %and = and i32 %x, 253
+  %rem = srem i32 %and, 254
+  ret i32 %rem
+}
+
+define i32 @not_srem_quotient_known_smaller_than_pos_divisor_clear_bits(i32 %x) {
+; CHECK-LABEL: @not_srem_quotient_known_smaller_than_pos_divisor_clear_bits(
+; CHECK-NEXT:    [[AND:%.*]] = and i32 %x, 253
+; CHECK-NEXT:    [[REM:%.*]] = srem i32 [[AND]], 253
+; CHECK-NEXT:    ret i32 [[REM]]
+;
+  %and = and i32 %x, 253
+  %rem = srem i32 %and, 253
+  ret i32 %rem
+}
+
+define i32 @srem_quotient_known_smaller_than_neg_divisor_clear_bits(i32 %x) {
+; CHECK-LABEL: @srem_quotient_known_smaller_than_neg_divisor_clear_bits(
+; CHECK-NEXT:    [[AND:%.*]] = and i32 %x, 253
+; CHECK-NEXT:    [[REM:%.*]] = srem i32 [[AND]], -254
+; CHECK-NEXT:    ret i32 [[REM]]
+;
+  %and = and i32 %x, 253
+  %rem = srem i32 %and, -254
+  ret i32 %rem
+}
+
+define i32 @not_srem_quotient_known_smaller_than_neg_divisor_clear_bits(i32 %x) {
+; CHECK-LABEL: @not_srem_quotient_known_smaller_than_neg_divisor_clear_bits(
+; CHECK-NEXT:    [[AND:%.*]] = and i32 %x, 253
+; CHECK-NEXT:    [[REM:%.*]] = srem i32 [[AND]], -253
+; CHECK-NEXT:    ret i32 [[REM]]
+;
+  %and = and i32 %x, 253
+  %rem = srem i32 %and, -253
+  ret i32 %rem
+}
+
+define i32 @srem_quotient_known_smaller_than_pos_divisor_set_bits(i32 %x) {
+; CHECK-LABEL: @srem_quotient_known_smaller_than_pos_divisor_set_bits(
+; CHECK-NEXT:    [[OR:%.*]] = or i32 %x, -253
+; CHECK-NEXT:    [[REM:%.*]] = srem i32 [[OR]], 254
+; CHECK-NEXT:    ret i32 [[REM]]
+;
+  %or = or i32 %x, -253
+  %rem = srem i32 %or, 254
+  ret i32 %rem
+}
+
+define i32 @not_srem_quotient_known_smaller_than_pos_divisor_set_bits(i32 %x) {
+; CHECK-LABEL: @not_srem_quotient_known_smaller_than_pos_divisor_set_bits(
+; CHECK-NEXT:    [[OR:%.*]] = or i32 %x, -253
+; CHECK-NEXT:    [[REM:%.*]] = srem i32 [[OR]], 253
+; CHECK-NEXT:    ret i32 [[REM]]
+;
+  %or = or i32 %x, -253
+  %rem = srem i32 %or, 253
+  ret i32 %rem
+}
+
+define i32 @srem_quotient_known_smaller_than_neg_divisor_set_bits(i32 %x) {
+; CHECK-LABEL: @srem_quotient_known_smaller_than_neg_divisor_set_bits(
+; CHECK-NEXT:    [[OR:%.*]] = or i32 %x, -253
+; CHECK-NEXT:    [[REM:%.*]] = srem i32 [[OR]], -254
+; CHECK-NEXT:    ret i32 [[REM]]
+;
+  %or = or i32 %x, -253
+  %rem = srem i32 %or, -254
+  ret i32 %rem
+}
+
+define i32 @not_srem_quotient_known_smaller_than_neg_divisor_set_bits(i32 %x) {
+; CHECK-LABEL: @not_srem_quotient_known_smaller_than_neg_divisor_set_bits(
+; CHECK-NEXT:    [[OR:%.*]] = or i32 %x, -253
+; CHECK-NEXT:    [[REM:%.*]] = srem i32 [[OR]], -253
+; CHECK-NEXT:    ret i32 [[REM]]
+;
+  %or = or i32 %x, -253
+  %rem = srem i32 %or, -253
+  ret i32 %rem
+}
+




More information about the llvm-commits mailing list