reference, declarationdefinition
definition → references, declarations, derived classes, virtual overrides
reference to multiple definitions → definitions
unreferenced
    1
    2
    3
    4
    5
    6
    7
    8
    9
   10
   11
   12
   13
   14
   15
   16
   17
   18
   19
   20
   21
   22
   23
   24
   25
   26
   27
   28
   29
   30
   31
   32
   33
   34
   35
   36
   37
   38
   39
   40
   41
   42
   43
   44
   45
   46
   47
   48
   49
   50
   51
   52
   53
   54
   55
   56
   57
   58
   59
   60
   61
   62
   63
   64
   65
   66
   67
   68
   69
   70
   71
   72
   73
   74
   75
   76
   77
   78
   79
   80
   81
   82
   83
   84
   85
   86
   87
   88
   89
   90
   91
   92
   93
   94
   95
   96
   97
   98
   99
  100
  101
  102
  103
  104
  105
  106
  107
  108
  109
  110
  111
  112
  113
  114
  115
  116
  117
  118
  119
  120
  121
  122
  123
  124
  125
  126
  127
  128
  129
  130
  131
  132
  133
  134
  135
  136
  137
  138
  139
  140
  141
  142
  143
  144
  145
  146
  147
  148
  149
  150
  151
  152
  153
  154
  155
  156
  157
  158
  159
; NOTE: Assertions have been autogenerated by utils/update_test_checks.py
; RUN: opt < %s -instcombine -S | FileCheck %s

; Tests for Integer BitWidth <= 64 && BitWidth % 8 != 0.

;; Flip sign bit then add INT_MIN -> nop.
define i1 @test1(i1 %x) {
; CHECK-LABEL: @test1(
; CHECK-NEXT:    ret i1 %x
;
  %tmp.2 = xor i1 %x, 1
  %tmp.4 = add i1 %tmp.2, 1
  ret i1 %tmp.4
}

;; Flip sign bit then add INT_MIN -> nop.
define i47 @test2(i47 %x) {
; CHECK-LABEL: @test2(
; CHECK-NEXT:    ret i47 %x
;
  %tmp.2 = xor i47 %x, 70368744177664
  %tmp.4 = add i47 %tmp.2, 70368744177664
  ret i47 %tmp.4
}

;; Flip sign bit then add INT_MIN -> nop.
define i15 @test3(i15 %x) {
; CHECK-LABEL: @test3(
; CHECK-NEXT:    ret i15 %x
;
  %tmp.2 = xor i15 %x, 16384
  %tmp.4 = add i15 %tmp.2, 16384
  ret i15 %tmp.4
}

; X + signbit --> X ^ signbit
define <2 x i5> @test3vec(<2 x i5> %x) {
; CHECK-LABEL: @test3vec(
; CHECK-NEXT:    [[Y:%.*]] = xor <2 x i5> %x, <i5 -16, i5 -16>
; CHECK-NEXT:    ret <2 x i5> [[Y]]
;
  %y = add <2 x i5> %x, <i5 16, i5 16>
  ret <2 x i5> %y
}

;; (x & 0b1111..0) + 1 -> x | 1
define i49 @test4(i49 %x) {
; CHECK-LABEL: @test4(
; CHECK-NEXT:    [[TMP_4:%.*]] = or i49 %x, 1
; CHECK-NEXT:    ret i49 [[TMP_4]]
;
  %tmp.2 = and i49 %x, 562949953421310
  %tmp.4 = add i49 %tmp.2, 1
  ret i49 %tmp.4
}

define i7 @sext(i4 %x) {
; CHECK-LABEL: @sext(
; CHECK-NEXT:    [[ADD:%.*]] = sext i4 %x to i7
; CHECK-NEXT:    ret i7 [[ADD]]
;
  %xor = xor i4 %x, -8
  %zext = zext i4 %xor to i7
  %add = add nsw i7 %zext, -8
  ret i7 %add
}

define <2 x i10> @sext_vec(<2 x i3> %x) {
; CHECK-LABEL: @sext_vec(
; CHECK-NEXT:    [[ADD:%.*]] = sext <2 x i3> %x to <2 x i10>
; CHECK-NEXT:    ret <2 x i10> [[ADD]]
;
  %xor = xor <2 x i3> %x, <i3 -4, i3 -4>
  %zext = zext <2 x i3> %xor to <2 x i10>
  %add = add nsw <2 x i10> %zext, <i10 -4, i10 -4>
  ret <2 x i10> %add
}

; Multiple uses of the operands don't prevent the fold.

define i4 @sext_multiuse(i4 %x) {
; CHECK-LABEL: @sext_multiuse(
; CHECK-NEXT:    [[XOR:%.*]] = xor i4 %x, -8
; CHECK-NEXT:    [[ZEXT:%.*]] = zext i4 [[XOR]] to i7
; CHECK-NEXT:    [[ADD:%.*]] = sext i4 %x to i7
; CHECK-NEXT:    [[MUL:%.*]] = sdiv i7 [[ZEXT]], [[ADD]]
; CHECK-NEXT:    [[TRUNC:%.*]] = trunc i7 [[MUL]] to i4
; CHECK-NEXT:    [[DIV:%.*]] = sdiv i4 [[TRUNC]], [[XOR]]
; CHECK-NEXT:    ret i4 [[DIV]]
;
  %xor = xor i4 %x, -8
  %zext = zext i4 %xor to i7
  %add = add nsw i7 %zext, -8
  %mul = sdiv i7 %zext, %add
  %trunc = trunc i7 %mul to i4
  %div = sdiv i4 %trunc, %xor
  ret i4 %div
}

; Tests for Integer BitWidth > 64 && BitWidth <= 1024.

;; Flip sign bit then add INT_MIN -> nop.
define i111 @test5(i111 %x) {
; CHECK-LABEL: @test5(
; CHECK-NEXT:    ret i111 %x
;
  %tmp.2 = shl i111 1, 110
  %tmp.4 = xor i111 %x, %tmp.2
  %tmp.6 = add i111 %tmp.4, %tmp.2
  ret i111 %tmp.6
}

;; Flip sign bit then add INT_MIN -> nop.
define i65 @test6(i65 %x) {
; CHECK-LABEL: @test6(
; CHECK-NEXT:    ret i65 %x
;
  %tmp.0 = shl i65 1, 64
  %tmp.2 = xor i65 %x, %tmp.0
  %tmp.4 = add i65 %tmp.2, %tmp.0
  ret i65 %tmp.4
}

;; Flip sign bit then add INT_MIN -> nop.
define i1024 @test7(i1024 %x) {
; CHECK-LABEL: @test7(
; CHECK-NEXT:    ret i1024 %x
;
  %tmp.0 = shl i1024 1, 1023
  %tmp.2 = xor i1024 %x, %tmp.0
  %tmp.4 = add i1024 %tmp.2, %tmp.0
  ret i1024 %tmp.4
}

;; If we have add(xor(X, 0xF..F80..), 0x80..), it's an xor.
define i128 @test8(i128 %x) {
; CHECK-LABEL: @test8(
; CHECK-NEXT:    [[TMP_4:%.*]] = xor i128 %x, 170141183460469231731687303715884105600
; CHECK-NEXT:    ret i128 [[TMP_4]]
;
  %tmp.5 = shl i128 1, 127
  %tmp.1 = ashr i128 %tmp.5, 120
  %tmp.2 = xor i128 %x, %tmp.1
  %tmp.4 = add i128 %tmp.2, %tmp.5
  ret i128 %tmp.4
}

;; (x & 254)+1 -> (x & 254)|1
define i77 @test9(i77 %x) {
; CHECK-LABEL: @test9(
; CHECK-NEXT:    [[TMP_2:%.*]] = and i77 %x, 562949953421310
; CHECK-NEXT:    [[TMP_4:%.*]] = or i77 [[TMP_2]], 1
; CHECK-NEXT:    ret i77 [[TMP_4]]
;
  %tmp.2 = and i77 %x, 562949953421310
  %tmp.4 = add i77 %tmp.2, 1
  ret i77 %tmp.4
}