1; NOTE: Assertions have been autogenerated by utils/update_test_checks.py 2; RUN: opt -instcombine -S < %s | FileCheck %s 3 4; Given: 5; add (add (xor %x, -1), %y), 1 6; Transform it to: 7; sub %y, %x 8 9;------------------------------------------------------------------------------; 10; Scalar tests 11;------------------------------------------------------------------------------; 12 13define i32 @t0(i32 %x, i32 %y) { 14; CHECK-LABEL: @t0( 15; CHECK-NEXT: [[T2:%.*]] = sub i32 [[Y:%.*]], [[X:%.*]] 16; CHECK-NEXT: ret i32 [[T2]] 17; 18 %t0 = xor i32 %x, -1 19 %t1 = add i32 %t0, %y 20 %t2 = add i32 %t1, 1 21 ret i32 %t2 22} 23 24;------------------------------------------------------------------------------; 25; Vector tests 26;------------------------------------------------------------------------------; 27 28define <4 x i32> @t1_vec_splat(<4 x i32> %x, <4 x i32> %y) { 29; CHECK-LABEL: @t1_vec_splat( 30; CHECK-NEXT: [[T2:%.*]] = sub <4 x i32> [[Y:%.*]], [[X:%.*]] 31; CHECK-NEXT: ret <4 x i32> [[T2]] 32; 33 %t0 = xor <4 x i32> %x, <i32 -1, i32 -1, i32 -1, i32 -1> 34 %t1 = add <4 x i32> %t0, %y 35 %t2 = add <4 x i32> %t1, <i32 1, i32 1, i32 1, i32 1> 36 ret <4 x i32> %t2 37} 38 39define <4 x i32> @t2_vec_undef0(<4 x i32> %x, <4 x i32> %y) { 40; CHECK-LABEL: @t2_vec_undef0( 41; CHECK-NEXT: [[T2:%.*]] = sub <4 x i32> [[Y:%.*]], [[X:%.*]] 42; CHECK-NEXT: ret <4 x i32> [[T2]] 43; 44 %t0 = xor <4 x i32> %x, <i32 -1, i32 -1, i32 undef, i32 -1> 45 %t1 = add <4 x i32> %t0, %y 46 %t2 = add <4 x i32> %t1, <i32 1, i32 1, i32 1, i32 1> 47 ret <4 x i32> %t2 48} 49 50define <4 x i32> @t3_vec_undef1(<4 x i32> %x, <4 x i32> %y) { 51; CHECK-LABEL: @t3_vec_undef1( 52; CHECK-NEXT: [[T2:%.*]] = sub <4 x i32> [[Y:%.*]], [[X:%.*]] 53; CHECK-NEXT: ret <4 x i32> [[T2]] 54; 55 %t0 = xor <4 x i32> %x, <i32 -1, i32 -1, i32 -1, i32 -1> 56 %t1 = add <4 x i32> %t0, %y 57 %t2 = add <4 x i32> %t1, <i32 1, i32 1, i32 undef, i32 1> 58 ret <4 x i32> %t2 59} 60 61define <4 x i32> @t4_vec_undef2(<4 x i32> %x, <4 x i32> %y) { 62; CHECK-LABEL: @t4_vec_undef2( 63; CHECK-NEXT: [[T2:%.*]] = sub <4 x i32> [[Y:%.*]], [[X:%.*]] 64; CHECK-NEXT: ret <4 x i32> [[T2]] 65; 66 %t0 = xor <4 x i32> %x, <i32 -1, i32 -1, i32 undef, i32 -1> 67 %t1 = add <4 x i32> %t0, %y 68 %t2 = add <4 x i32> %t1, <i32 1, i32 1, i32 undef, i32 1> 69 ret <4 x i32> %t2 70} 71 72;------------------------------------------------------------------------------; 73; One-use tests 74;------------------------------------------------------------------------------; 75 76declare void @use32(i32) 77 78define i32 @t5(i32 %x, i32 %y) { 79; CHECK-LABEL: @t5( 80; CHECK-NEXT: [[T0:%.*]] = xor i32 [[X:%.*]], -1 81; CHECK-NEXT: call void @use32(i32 [[T0]]) 82; CHECK-NEXT: [[T2:%.*]] = sub i32 [[Y:%.*]], [[X]] 83; CHECK-NEXT: ret i32 [[T2]] 84; 85 %t0 = xor i32 %x, -1 86 call void @use32(i32 %t0) 87 %t1 = add i32 %t0, %y 88 %t2 = add i32 %t1, 1 89 ret i32 %t2 90} 91 92define i32 @t6(i32 %x, i32 %y) { 93; CHECK-LABEL: @t6( 94; CHECK-NEXT: [[T0:%.*]] = xor i32 [[X:%.*]], -1 95; CHECK-NEXT: [[T1:%.*]] = add i32 [[T0]], [[Y:%.*]] 96; CHECK-NEXT: call void @use32(i32 [[T1]]) 97; CHECK-NEXT: [[T2:%.*]] = sub i32 [[Y]], [[X]] 98; CHECK-NEXT: ret i32 [[T2]] 99; 100 %t0 = xor i32 %x, -1 101 %t1 = add i32 %t0, %y 102 call void @use32(i32 %t1) 103 %t2 = add i32 %t1, 1 104 ret i32 %t2 105} 106 107define i32 @t7(i32 %x, i32 %y) { 108; CHECK-LABEL: @t7( 109; CHECK-NEXT: [[T0:%.*]] = xor i32 [[X:%.*]], -1 110; CHECK-NEXT: call void @use32(i32 [[T0]]) 111; CHECK-NEXT: [[T1:%.*]] = add i32 [[T0]], [[Y:%.*]] 112; CHECK-NEXT: call void @use32(i32 [[T1]]) 113; CHECK-NEXT: [[T2:%.*]] = sub i32 [[Y]], [[X]] 114; CHECK-NEXT: ret i32 [[T2]] 115; 116 %t0 = xor i32 %x, -1 117 call void @use32(i32 %t0) 118 %t1 = add i32 %t0, %y 119 call void @use32(i32 %t1) 120 %t2 = add i32 %t1, 1 121 ret i32 %t2 122} 123 124;------------------------------------------------------------------------------; 125; Commutativity 126;------------------------------------------------------------------------------; 127 128declare i32 @gen32() 129 130define i32 @t8_commutative0(i32 %x) { 131; CHECK-LABEL: @t8_commutative0( 132; CHECK-NEXT: [[Y:%.*]] = call i32 @gen32() 133; CHECK-NEXT: [[T0:%.*]] = xor i32 [[X:%.*]], -1 134; CHECK-NEXT: call void @use32(i32 [[T0]]) 135; CHECK-NEXT: [[T1:%.*]] = add i32 [[Y]], [[T0]] 136; CHECK-NEXT: call void @use32(i32 [[T1]]) 137; CHECK-NEXT: [[T2:%.*]] = sub i32 [[Y]], [[X]] 138; CHECK-NEXT: ret i32 [[T2]] 139; 140 %y = call i32 @gen32() 141 %t0 = xor i32 %x, -1 142 call void @use32(i32 %t0) 143 %t1 = add i32 %y, %t0 ; swapped 144 call void @use32(i32 %t1) 145 %t2 = add i32 %t1, 1 146 ret i32 %t2 147} 148 149define i32 @t9_commutative1(i32 %x, i32 %y) { 150; CHECK-LABEL: @t9_commutative1( 151; CHECK-NEXT: [[T0:%.*]] = xor i32 [[X:%.*]], -1 152; CHECK-NEXT: call void @use32(i32 [[T0]]) 153; CHECK-NEXT: [[T1:%.*]] = sub i32 0, [[X]] 154; CHECK-NEXT: call void @use32(i32 [[T1]]) 155; CHECK-NEXT: [[T2:%.*]] = sub i32 [[Y:%.*]], [[X]] 156; CHECK-NEXT: ret i32 [[T2]] 157; 158 %t0 = xor i32 %x, -1 159 call void @use32(i32 %t0) 160 %t1 = add i32 %t0, 1 ; +1 is not last 161 call void @use32(i32 %t1) 162 %t2 = add i32 %t1, %y ; 163 ret i32 %t2 164} 165 166define i32 @t10_commutative2(i32 %x) { 167; CHECK-LABEL: @t10_commutative2( 168; CHECK-NEXT: [[Y:%.*]] = call i32 @gen32() 169; CHECK-NEXT: [[T0:%.*]] = xor i32 [[X:%.*]], -1 170; CHECK-NEXT: call void @use32(i32 [[T0]]) 171; CHECK-NEXT: [[T1:%.*]] = sub i32 0, [[X]] 172; CHECK-NEXT: call void @use32(i32 [[T1]]) 173; CHECK-NEXT: [[T2:%.*]] = sub i32 [[Y]], [[X]] 174; CHECK-NEXT: ret i32 [[T2]] 175; 176 %y = call i32 @gen32() 177 %t0 = xor i32 %x, -1 178 call void @use32(i32 %t0) 179 %t1 = add i32 %t0, 1 ; +1 is not last 180 call void @use32(i32 %t1) 181 %t2 = add i32 %y, %t1 ; swapped 182 ret i32 %t2 183} 184 185;------------------------------------------------------------------------------; 186; Basic negative tests 187;------------------------------------------------------------------------------; 188 189define i32 @n11(i32 %x, i32 %y) { 190; CHECK-LABEL: @n11( 191; CHECK-NEXT: [[T0:%.*]] = xor i32 [[X:%.*]], 2147483647 192; CHECK-NEXT: [[T1:%.*]] = add i32 [[T0]], [[Y:%.*]] 193; CHECK-NEXT: [[T2:%.*]] = add i32 [[T1]], 1 194; CHECK-NEXT: ret i32 [[T2]] 195; 196 %t0 = xor i32 %x, 2147483647 ; not -1 197 %t1 = add i32 %t0, %y 198 %t2 = add i32 %t1, 1 199 ret i32 %t2 200} 201 202define i32 @n12(i32 %x, i32 %y) { 203; CHECK-LABEL: @n12( 204; CHECK-NEXT: [[T0:%.*]] = xor i32 [[X:%.*]], -1 205; CHECK-NEXT: [[T1:%.*]] = add i32 [[T0]], [[Y:%.*]] 206; CHECK-NEXT: [[T2:%.*]] = add i32 [[T1]], 2 207; CHECK-NEXT: ret i32 [[T2]] 208; 209 %t0 = xor i32 %x, -1 210 %t1 = add i32 %t0, %y 211 %t2 = add i32 %t1, 2 ; not +1 212 ret i32 %t2 213} 214