1 ; NOTE: Assertions have been autogenerated by utils/update_test_checks.py 2 ; RUN: opt < %s -instsimplify -S | FileCheck %s 3 4 define i32 @negated_operand(i32 %x) { 5 ; CHECK-LABEL: @negated_operand( 6 ; CHECK-NEXT: ret i32 -1 7 ; 8 %negx = sub nsw i32 0, %x 9 %div = sdiv i32 %negx, %x 10 ret i32 %div 11 } 12 13 define <2 x i32> @negated_operand_commute_vec(<2 x i32> %x) { 14 ; CHECK-LABEL: @negated_operand_commute_vec( 15 ; CHECK-NEXT: ret <2 x i32> <i32 -1, i32 -1> 16 ; 17 %negx = sub nsw <2 x i32> zeroinitializer, %x 18 %div = sdiv <2 x i32> %negx, %x 19 ret <2 x i32> %div 20 } 21 22 define i32 @knownnegation(i32 %x, i32 %y) { 23 ; CHECK-LABEL: @knownnegation( 24 ; CHECK-NEXT: ret i32 -1 25 ; 26 %xy = sub nsw i32 %x, %y 27 %yx = sub nsw i32 %y, %x 28 %div = sdiv i32 %xy, %yx 29 ret i32 %div 30 } 31 32 define <2 x i32> @knownnegation_commute_vec(<2 x i32> %x, <2 x i32> %y) { 33 ; CHECK-LABEL: @knownnegation_commute_vec( 34 ; CHECK-NEXT: ret <2 x i32> <i32 -1, i32 -1> 35 ; 36 %xy = sub nsw <2 x i32> %x, %y 37 %yx = sub nsw <2 x i32> %y, %x 38 %div = sdiv <2 x i32> %xy, %yx 39 ret <2 x i32> %div 40 } 41 42 define i32 @negated_operand_2(i32 %t) { 43 ; CHECK-LABEL: @negated_operand_2( 44 ; CHECK-NEXT: ret i32 -1 45 ; 46 %x = sub i32 %t, 5 47 %negx = sub nsw i32 0, %x 48 %div = sdiv i32 %negx, %x 49 ret i32 %div 50 } 51 52 define i32 @negated_operand_commute(i32 %x) { 53 ; CHECK-LABEL: @negated_operand_commute( 54 ; CHECK-NEXT: ret i32 -1 55 ; 56 %negx = sub nsw i32 0, %x 57 %div = sdiv i32 %x, %negx 58 ret i32 %div 59 } 60 61 define i32 @negated_operand_bad(i32 %x) { 62 ; CHECK-LABEL: @negated_operand_bad( 63 ; CHECK-NEXT: [[NEGX:%.*]] = sub i32 0, [[X:%.*]] 64 ; CHECK-NEXT: [[DIV:%.*]] = sdiv i32 [[NEGX]], [[X]] 65 ; CHECK-NEXT: ret i32 [[DIV]] 66 ; 67 %negx = sub i32 0, %x ; not nsw 68 %div = sdiv i32 %negx, %x 69 ret i32 %div 70 } 71 72 define i32 @knownnegation_bad_1(i32 %x, i32 %y) { 73 ; CHECK-LABEL: @knownnegation_bad_1( 74 ; CHECK-NEXT: [[XY:%.*]] = sub nsw i32 [[X:%.*]], [[Y:%.*]] 75 ; CHECK-NEXT: [[YX:%.*]] = sub i32 [[Y]], [[X]] 76 ; CHECK-NEXT: [[DIV:%.*]] = sdiv i32 [[XY]], [[YX]] 77 ; CHECK-NEXT: ret i32 [[DIV]] 78 ; 79 %xy = sub nsw i32 %x, %y 80 %yx = sub i32 %y, %x ; not nsw 81 %div = sdiv i32 %xy, %yx 82 ret i32 %div 83 } 84 85 define i32 @knownnegation_bad_2(i32 %x, i32 %y) { 86 ; CHECK-LABEL: @knownnegation_bad_2( 87 ; CHECK-NEXT: [[XY:%.*]] = sub i32 [[X:%.*]], [[Y:%.*]] 88 ; CHECK-NEXT: [[YX:%.*]] = sub nsw i32 [[Y]], [[X]] 89 ; CHECK-NEXT: [[DIV:%.*]] = sdiv i32 [[XY]], [[YX]] 90 ; CHECK-NEXT: ret i32 [[DIV]] 91 ; 92 %xy = sub i32 %x, %y ; not nsw 93 %yx = sub nsw i32 %y, %x 94 %div = sdiv i32 %xy, %yx 95 ret i32 %div 96 } 97 98 define i32 @knownnegation_bad_3(i32 %x, i32 %y) { 99 ; CHECK-LABEL: @knownnegation_bad_3( 100 ; CHECK-NEXT: [[XY:%.*]] = sub i32 [[X:%.*]], [[Y:%.*]] 101 ; CHECK-NEXT: [[YX:%.*]] = sub i32 [[Y]], [[X]] 102 ; CHECK-NEXT: [[DIV:%.*]] = sdiv i32 [[XY]], [[YX]] 103 ; CHECK-NEXT: ret i32 [[DIV]] 104 ; 105 %xy = sub i32 %x, %y ; not nsw 106 %yx = sub i32 %y, %x ; not nsw 107 %div = sdiv i32 %xy, %yx 108 ret i32 %div 109 } 110 111 define <2 x i32> @negated_operand_commute_vec_bad(<2 x i32> %x) { 112 ; CHECK-LABEL: @negated_operand_commute_vec_bad( 113 ; CHECK-NEXT: [[NEGX:%.*]] = sub <2 x i32> zeroinitializer, [[X:%.*]] 114 ; CHECK-NEXT: [[DIV:%.*]] = sdiv <2 x i32> [[NEGX]], [[X]] 115 ; CHECK-NEXT: ret <2 x i32> [[DIV]] 116 ; 117 %negx = sub <2 x i32> zeroinitializer, %x ; not nsw 118 %div = sdiv <2 x i32> %negx, %x 119 ret <2 x i32> %div 120 } 121 122 define <2 x i32> @knownnegation_commute_vec_bad1(<2 x i32> %x, <2 x i32> %y) { 123 ; CHECK-LABEL: @knownnegation_commute_vec_bad1( 124 ; CHECK-NEXT: [[XY:%.*]] = sub nsw <2 x i32> [[X:%.*]], [[Y:%.*]] 125 ; CHECK-NEXT: [[YX:%.*]] = sub <2 x i32> [[Y]], [[X]] 126 ; CHECK-NEXT: [[DIV:%.*]] = sdiv <2 x i32> [[XY]], [[YX]] 127 ; CHECK-NEXT: ret <2 x i32> [[DIV]] 128 ; 129 %xy = sub nsw <2 x i32> %x, %y 130 %yx = sub <2 x i32> %y, %x ; not nsw 131 %div = sdiv <2 x i32> %xy, %yx 132 ret <2 x i32> %div 133 } 134 135 define <2 x i32> @knownnegation_commute_vec_bad2(<2 x i32> %x, <2 x i32> %y) { 136 ; CHECK-LABEL: @knownnegation_commute_vec_bad2( 137 ; CHECK-NEXT: [[XY:%.*]] = sub <2 x i32> [[X:%.*]], [[Y:%.*]] 138 ; CHECK-NEXT: [[YX:%.*]] = sub nsw <2 x i32> [[Y]], [[X]] 139 ; CHECK-NEXT: [[DIV:%.*]] = sdiv <2 x i32> [[XY]], [[YX]] 140 ; CHECK-NEXT: ret <2 x i32> [[DIV]] 141 ; 142 %xy = sub <2 x i32> %x, %y ; not nsw 143 %yx = sub nsw <2 x i32> %y, %x 144 %div = sdiv <2 x i32> %xy, %yx 145 ret <2 x i32> %div 146 } 147 148 define <2 x i32> @knownnegation_commute_vec_bad3(<2 x i32> %x, <2 x i32> %y) { 149 ; CHECK-LABEL: @knownnegation_commute_vec_bad3( 150 ; CHECK-NEXT: [[XY:%.*]] = sub <2 x i32> [[X:%.*]], [[Y:%.*]] 151 ; CHECK-NEXT: [[YX:%.*]] = sub <2 x i32> [[Y]], [[X]] 152 ; CHECK-NEXT: [[DIV:%.*]] = sdiv <2 x i32> [[XY]], [[YX]] 153 ; CHECK-NEXT: ret <2 x i32> [[DIV]] 154 ; 155 %xy = sub <2 x i32> %x, %y ; not nsw 156 %yx = sub <2 x i32> %y, %x ; not nsw 157 %div = sdiv <2 x i32> %xy, %yx 158 ret <2 x i32> %div 159 } 160 161 define <3 x i32> @negated_operand_vec_undef(<3 x i32> %x) { 162 ; CHECK-LABEL: @negated_operand_vec_undef( 163 ; CHECK-NEXT: ret <3 x i32> <i32 -1, i32 -1, i32 -1> 164 ; 165 %negx = sub nsw <3 x i32> <i32 0, i32 undef, i32 0>, %x 166 %div = sdiv <3 x i32> %negx, %x 167 ret <3 x i32> %div 168 } 169 170 define <2 x i32> @negated_operand_vec_nonsplat(<2 x i32> %x) { 171 ; CHECK-LABEL: @negated_operand_vec_nonsplat( 172 ; CHECK-NEXT: [[NEGX:%.*]] = sub nsw <2 x i32> <i32 0, i32 1>, [[X:%.*]] 173 ; CHECK-NEXT: [[DIV:%.*]] = sdiv <2 x i32> [[NEGX]], [[X]] 174 ; CHECK-NEXT: ret <2 x i32> [[DIV]] 175 ; 176 %negx = sub nsw <2 x i32> <i32 0, i32 1>, %x ; not 0, don't fold 177 %div = sdiv <2 x i32> %negx, %x 178 ret <2 x i32> %div 179 } 180