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

target datalayout = "e-m:o-i64:64-f80:128-n8:16:32:64-S128"

; Tests folding constants from two similar selects that feed a add

define float @test1a(i1 zeroext %arg) #0 {
; CHECK-LABEL: @test1a(
; CHECK-NEXT:    [[TMP2:%.*]] = select i1 [[ARG:%.*]], float 6.000000e+00, float 1.500000e+01
; CHECK-NEXT:    ret float [[TMP2]]
;
  %tmp = select i1 %arg, float 5.000000e+00, float 6.000000e+00
  %tmp1 = select i1 %arg, float 1.000000e+00, float 9.000000e+00
  %tmp2 = fadd float %tmp, %tmp1
  ret float %tmp2
}

; Tests folding multiple expression constants from similar selects that feed a adds

define float @test1b(i1 zeroext %arg) #0 {
; CHECK-LABEL: @test1b(
; CHECK-NEXT:    [[TMP5:%.*]] = select i1 [[ARG:%.*]], float 7.250000e+00, float 2.800000e+01
; CHECK-NEXT:    ret float [[TMP5]]
;
  %tmp = select i1 %arg, float 5.000000e+00, float 6.000000e+00
  %tmp1 = select i1 %arg, float 1.000000e+00, float 9.000000e+00
  %tmp2 = select i1 %arg, float 2.500000e-01, float 4.000000e+00
  %tmp3 = fadd float %tmp, %tmp1
  %tmp4 = fadd float %tmp2, %tmp1
  %tmp5 = fadd float %tmp4, %tmp3
  ret float %tmp5
}

; Tests folding constants from two similar selects that feed a sub

define float @test2(i1 zeroext %arg) #0 {
; CHECK-LABEL: @test2(
; CHECK-NEXT:    [[TMP2:%.*]] = select i1 [[ARG:%.*]], float 4.000000e+00, float -3.000000e+00
; CHECK-NEXT:    ret float [[TMP2]]
;
  %tmp = select i1 %arg, float 5.000000e+00, float 6.000000e+00
  %tmp1 = select i1 %arg, float 1.000000e+00, float 9.000000e+00
  %tmp2 = fsub float %tmp, %tmp1
  ret float %tmp2
}

; Tests folding constants from two similar selects that feed a mul

define float @test3(i1 zeroext %arg) #0 {
; CHECK-LABEL: @test3(
; CHECK-NEXT:    [[TMP2:%.*]] = select i1 [[ARG:%.*]], float 5.000000e+00, float 5.400000e+01
; CHECK-NEXT:    ret float [[TMP2]]
;
  %tmp = select i1 %arg, float 5.000000e+00, float 6.000000e+00
  %tmp1 = select i1 %arg, float 1.000000e+00, float 9.000000e+00
  %tmp2 = fmul float %tmp, %tmp1
  ret float %tmp2
}

declare void @use_float(float)

; Tests folding constants if the selects have multiple uses but
; we can fold away the binary op with a select.

define float @test4(i1 zeroext %arg) #0 {
; CHECK-LABEL: @test4(
; CHECK-NEXT:    [[TMP:%.*]] = select i1 [[ARG:%.*]], float 5.000000e+00, float 6.000000e+00
; CHECK-NEXT:    [[TMP2:%.*]] = select i1 [[ARG]], float 5.000000e+00, float 5.400000e+01
; CHECK-NEXT:    call void @use_float(float [[TMP]])
; CHECK-NEXT:    ret float [[TMP2]]
;
  %tmp = select i1 %arg, float 5.000000e+00, float 6.000000e+00
  %tmp1 = select i1 %arg, float 1.000000e+00, float 9.000000e+00
  %tmp2 = fmul float %tmp, %tmp1
  call void @use_float(float %tmp)
  ret float %tmp2
}

; Tests not folding constants if we cannot fold away any of the selects.

define float @test5(i1 zeroext %arg, float %div) {
; CHECK-LABEL: @test5(
; CHECK-NEXT:    [[TMP:%.*]] = select i1 [[ARG:%.*]], float [[DIV:%.*]], float 5.000000e+00
; CHECK-NEXT:    [[MUL:%.*]] = fmul contract float [[TMP]], [[TMP]]
; CHECK-NEXT:    call void @use_float(float [[TMP]])
; CHECK-NEXT:    ret float [[MUL]]
;
  %tmp = select i1 %arg, float %div, float 5.000000e+00
  %mul = fmul contract float %tmp, %tmp
  call void @use_float(float %tmp)
  ret float %mul
}

define float @fmul_nnan_nsz(i1 %cond, float %val) {
; CHECK-LABEL: @fmul_nnan_nsz(
; CHECK-NEXT:    ret float 0.000000e+00
;
  %lhs = select i1 %cond, float %val, float +0.0
  %rhs = select i1 %cond, float -0.0, float %val
  %mul = fmul nnan nsz float %lhs, %rhs
  ret float %mul
}

define <2 x float> @fadd_nsz(<2 x i1> %cond, <2 x float> %val) {
; CHECK-LABEL: @fadd_nsz(
; CHECK-NEXT:    ret <2 x float> [[VAL:%.*]]
;
  %lhs = select <2 x i1> %cond, <2 x float> %val, <2 x float> <float +0.0, float +0.0>
  %rhs = select <2 x i1> %cond, <2 x float> <float +0.0, float +0.0>, <2 x float> %val
  %add = fadd nsz <2 x float> %lhs, %rhs
  ret <2 x float> %add
}

define double @fsub_nnan(i1 %cond, double %val, double %val2) {
; CHECK-LABEL: @fsub_nnan(
; CHECK-NEXT:    [[TMP1:%.*]] = fadd nnan double [[VAL2:%.*]], -7.000000e+00
; CHECK-NEXT:    [[ADD:%.*]] = select nnan i1 [[COND:%.*]], double 0.000000e+00, double [[TMP1]]
; CHECK-NEXT:    ret double [[ADD]]
;
  %lhs = select i1 %cond, double %val, double %val2
  %rhs = select i1 %cond, double %val, double 7.0
  %add = fsub nnan double %lhs, %rhs
  ret double %add
}

; TODO combine selects feeding fdiv like we do for fmul, fadd and fsub
define double @fdiv_nnan_nsz(i1 %cond, double %val, double %val2) {
; CHECK-LABEL: @fdiv_nnan_nsz(
; CHECK-NEXT:    [[LHS:%.*]] = select i1 [[COND:%.*]], double [[VAL2:%.*]], double 0.000000e+00
; CHECK-NEXT:    [[RHS:%.*]] = select i1 [[COND]], double 4.200000e+01, double [[VAL:%.*]]
; CHECK-NEXT:    [[ADD:%.*]] = fdiv nnan nsz double [[LHS]], [[RHS]]
; CHECK-NEXT:    ret double [[ADD]]
;
  %lhs = select i1 %cond, double %val2, double 0.0
  %rhs = select i1 %cond, double 42.0, double %val
  %add = fdiv nnan nsz double %lhs, %rhs
  ret double %add
}