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
; NOTE: Assertions have been autogenerated by utils/update_test_checks.py
; RUN: opt < %s -instcombine -S | FileCheck %s

define double @x(i32 %a, i32 %b) {
; CHECK-LABEL: @x(
; CHECK-NEXT:    [[M:%.*]] = lshr i32 [[A:%.*]], 24
; CHECK-NEXT:    [[N:%.*]] = and i32 [[M]], [[B:%.*]]
; CHECK-NEXT:    [[ADDCONV:%.*]] = add nuw nsw i32 [[N]], 1
; CHECK-NEXT:    [[P:%.*]] = sitofp i32 [[ADDCONV]] to double
; CHECK-NEXT:    ret double [[P]]
;
  %m = lshr i32 %a, 24
  %n = and i32 %m, %b
  %o = sitofp i32 %n to double
  %p = fadd double %o, 1.0
  ret double %p
}

define double @test(i32 %a) {
; CHECK-LABEL: @test(
; CHECK-NEXT:    [[A_AND:%.*]] = and i32 [[A:%.*]], 1073741823
; CHECK-NEXT:    [[ADDCONV:%.*]] = add nuw nsw i32 [[A_AND]], 1
; CHECK-NEXT:    [[RES:%.*]] = sitofp i32 [[ADDCONV]] to double
; CHECK-NEXT:    ret double [[RES]]
;
  ; Drop two highest bits to guarantee that %a + 1 doesn't overflow
  %a_and = and i32 %a, 1073741823
  %a_and_fp = sitofp i32 %a_and to double
  %res = fadd double %a_and_fp, 1.0
  ret double %res
}

define float @test_neg(i32 %a) {
; CHECK-LABEL: @test_neg(
; CHECK-NEXT:    [[A_AND:%.*]] = and i32 [[A:%.*]], 1073741823
; CHECK-NEXT:    [[A_AND_FP:%.*]] = sitofp i32 [[A_AND]] to float
; CHECK-NEXT:    [[RES:%.*]] = fadd float [[A_AND_FP]], 1.000000e+00
; CHECK-NEXT:    ret float [[RES]]
;
  ; Drop two highest bits to guarantee that %a + 1 doesn't overflow
  %a_and = and i32 %a, 1073741823
  %a_and_fp = sitofp i32 %a_and to float
  %res = fadd float %a_and_fp, 1.0
  ret float %res
}

define double @test_2(i32 %a, i32 %b) {
; CHECK-LABEL: @test_2(
; CHECK-NEXT:    [[A_AND:%.*]] = and i32 [[A:%.*]], 1073741823
; CHECK-NEXT:    [[B_AND:%.*]] = and i32 [[B:%.*]], 1073741823
; CHECK-NEXT:    [[ADDCONV:%.*]] = add nuw nsw i32 [[A_AND]], [[B_AND]]
; CHECK-NEXT:    [[RES:%.*]] = sitofp i32 [[ADDCONV]] to double
; CHECK-NEXT:    ret double [[RES]]
;
  ; Drop two highest bits to guarantee that %a + %b doesn't overflow
  %a_and = and i32 %a, 1073741823
  %b_and = and i32 %b, 1073741823

  %a_and_fp = sitofp i32 %a_and to double
  %b_and_fp = sitofp i32 %b_and to double

  %res = fadd double %a_and_fp, %b_and_fp
  ret double %res
}

define float @test_2_neg(i32 %a, i32 %b) {
; CHECK-LABEL: @test_2_neg(
; CHECK-NEXT:    [[A_AND:%.*]] = and i32 [[A:%.*]], 1073741823
; CHECK-NEXT:    [[B_AND:%.*]] = and i32 [[B:%.*]], 1073741823
; CHECK-NEXT:    [[A_AND_FP:%.*]] = sitofp i32 [[A_AND]] to float
; CHECK-NEXT:    [[B_AND_FP:%.*]] = sitofp i32 [[B_AND]] to float
; CHECK-NEXT:    [[RES:%.*]] = fadd float [[A_AND_FP]], [[B_AND_FP]]
; CHECK-NEXT:    ret float [[RES]]
;
  ; Drop two highest bits to guarantee that %a + %b doesn't overflow
  %a_and = and i32 %a, 1073741823
  %b_and = and i32 %b, 1073741823

  %a_and_fp = sitofp i32 %a_and to float
  %b_and_fp = sitofp i32 %b_and to float

  %res = fadd float %a_and_fp, %b_and_fp
  ret float %res
}

; This test demonstrates overly conservative legality check. The float addition
; can be replaced with the integer addition because the result of the operation
; can be represented in float, but we don't do that now.
define float @test_3(i32 %a, i32 %b) {
; CHECK-LABEL: @test_3(
; CHECK-NEXT:    [[M:%.*]] = lshr i32 [[A:%.*]], 24
; CHECK-NEXT:    [[N:%.*]] = and i32 [[M]], [[B:%.*]]
; CHECK-NEXT:    [[O:%.*]] = sitofp i32 [[N]] to float
; CHECK-NEXT:    [[P:%.*]] = fadd float [[O]], 1.000000e+00
; CHECK-NEXT:    ret float [[P]]
;
  %m = lshr i32 %a, 24
  %n = and i32 %m, %b
  %o = sitofp i32 %n to float
  %p = fadd float %o, 1.0
  ret float %p
}

define <4 x double> @test_4(<4 x i32> %a, <4 x i32> %b) {
; CHECK-LABEL: @test_4(
; CHECK-NEXT:    [[A_AND:%.*]] = and <4 x i32> [[A:%.*]], <i32 1073741823, i32 1073741823, i32 1073741823, i32 1073741823>
; CHECK-NEXT:    [[B_AND:%.*]] = and <4 x i32> [[B:%.*]], <i32 1073741823, i32 1073741823, i32 1073741823, i32 1073741823>
; CHECK-NEXT:    [[ADDCONV:%.*]] = add nuw nsw <4 x i32> [[A_AND]], [[B_AND]]
; CHECK-NEXT:    [[RES:%.*]] = sitofp <4 x i32> [[ADDCONV]] to <4 x double>
; CHECK-NEXT:    ret <4 x double> [[RES]]
;
  ; Drop two highest bits to guarantee that %a + %b doesn't overflow
  %a_and = and <4 x i32> %a, <i32 1073741823, i32 1073741823, i32 1073741823, i32 1073741823>
  %b_and = and <4 x i32> %b, <i32 1073741823, i32 1073741823, i32 1073741823, i32 1073741823>

  %a_and_fp = sitofp <4 x i32> %a_and to <4 x double>
  %b_and_fp = sitofp <4 x i32> %b_and to <4 x double>

  %res = fadd <4 x double> %a_and_fp, %b_and_fp
  ret <4 x double> %res
}

define <4 x float> @test_4_neg(<4 x i32> %a, <4 x i32> %b) {
; CHECK-LABEL: @test_4_neg(
; CHECK-NEXT:    [[A_AND:%.*]] = and <4 x i32> [[A:%.*]], <i32 1073741823, i32 1073741823, i32 1073741823, i32 1073741823>
; CHECK-NEXT:    [[B_AND:%.*]] = and <4 x i32> [[B:%.*]], <i32 1073741823, i32 1073741823, i32 1073741823, i32 1073741823>
; CHECK-NEXT:    [[A_AND_FP:%.*]] = sitofp <4 x i32> [[A_AND]] to <4 x float>
; CHECK-NEXT:    [[B_AND_FP:%.*]] = sitofp <4 x i32> [[B_AND]] to <4 x float>
; CHECK-NEXT:    [[RES:%.*]] = fadd <4 x float> [[A_AND_FP]], [[B_AND_FP]]
; CHECK-NEXT:    ret <4 x float> [[RES]]
;
  ; Drop two highest bits to guarantee that %a + %b doesn't overflow
  %a_and = and <4 x i32> %a, <i32 1073741823, i32 1073741823, i32 1073741823, i32 1073741823>
  %b_and = and <4 x i32> %b, <i32 1073741823, i32 1073741823, i32 1073741823, i32 1073741823>

  %a_and_fp = sitofp <4 x i32> %a_and to <4 x float>
  %b_and_fp = sitofp <4 x i32> %b_and to <4 x float>

  %res = fadd <4 x float> %a_and_fp, %b_and_fp
  ret <4 x float> %res
}