1; NOTE: Assertions have been autogenerated by utils/update_test_checks.py 2; RUN: opt < %s -instsimplify -S | FileCheck %s 3 4define 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 13define <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 22define 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 32define <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 42define 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 52define 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 61define 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 72define 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 85define 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 98define 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 111define <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 122define <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 135define <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 148define <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 161define <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 170define <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