summaryrefslogtreecommitdiffstats
path: root/llvm/test
diff options
context:
space:
mode:
authorSanjay Patel <spatel@rotateright.com>2017-09-11 19:42:41 +0000
committerSanjay Patel <spatel@rotateright.com>2017-09-11 19:42:41 +0000
commita36eb77118d1c834d97c40779dd1ebbfac2fc677 (patch)
treea21a904c67c8489721897a1f2814f29be07919bf /llvm/test
parent87d1f9ce935f2b2c39bf2d543755a5702f7cdbcc (diff)
downloadbcm5719-llvm-a36eb77118d1c834d97c40779dd1ebbfac2fc677.tar.gz
bcm5719-llvm-a36eb77118d1c834d97c40779dd1ebbfac2fc677.zip
[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. llvm-svn: 312938
Diffstat (limited to 'llvm/test')
-rw-r--r--llvm/test/Transforms/InstSimplify/signed-div-rem.ll354
1 files changed, 354 insertions, 0 deletions
diff --git a/llvm/test/Transforms/InstSimplify/signed-div-rem.ll b/llvm/test/Transforms/InstSimplify/signed-div-rem.ll
new file mode 100644
index 00000000000..84c14757f8a
--- /dev/null
+++ b/llvm/test/Transforms/InstSimplify/signed-div-rem.ll
@@ -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
+}
+
OpenPOWER on IntegriCloud