214 lines · plain
1; NOTE: Assertions have been autogenerated by utils/update_test_checks.py2; RUN: opt -passes=instcombine -S < %s | FileCheck %s3 4; Given:5; add (add (xor %x, -1), %y), 16; Transform it to:7; sub %y, %x8 9;------------------------------------------------------------------------------;10; Scalar tests11;------------------------------------------------------------------------------;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, -119 %t1 = add i32 %t0, %y20 %t2 = add i32 %t1, 121 ret i32 %t222}23 24;------------------------------------------------------------------------------;25; Vector tests26;------------------------------------------------------------------------------;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, %y35 %t2 = add <4 x i32> %t1, <i32 1, i32 1, i32 1, i32 1>36 ret <4 x i32> %t237}38 39define <4 x i32> @t2_vec_poison0(<4 x i32> %x, <4 x i32> %y) {40; CHECK-LABEL: @t2_vec_poison0(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 poison, i32 -1>45 %t1 = add <4 x i32> %t0, %y46 %t2 = add <4 x i32> %t1, <i32 1, i32 1, i32 1, i32 1>47 ret <4 x i32> %t248}49 50define <4 x i32> @t3_vec_poison1(<4 x i32> %x, <4 x i32> %y) {51; CHECK-LABEL: @t3_vec_poison1(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, %y57 %t2 = add <4 x i32> %t1, <i32 1, i32 1, i32 poison, i32 1>58 ret <4 x i32> %t259}60 61define <4 x i32> @t4_vec_poison2(<4 x i32> %x, <4 x i32> %y) {62; CHECK-LABEL: @t4_vec_poison2(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 poison, i32 -1>67 %t1 = add <4 x i32> %t0, %y68 %t2 = add <4 x i32> %t1, <i32 1, i32 1, i32 poison, i32 1>69 ret <4 x i32> %t270}71 72;------------------------------------------------------------------------------;73; One-use tests74;------------------------------------------------------------------------------;75 76declare void @use32(i32)77 78define i32 @t5(i32 %x, i32 %y) {79; CHECK-LABEL: @t5(80; CHECK-NEXT: [[T0:%.*]] = xor i32 [[X:%.*]], -181; 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, -186 call void @use32(i32 %t0)87 %t1 = add i32 %t0, %y88 %t2 = add i32 %t1, 189 ret i32 %t290}91 92define i32 @t6(i32 %x, i32 %y) {93; CHECK-LABEL: @t6(94; CHECK-NEXT: [[T0:%.*]] = xor i32 [[X:%.*]], -195; CHECK-NEXT: [[T1:%.*]] = add i32 [[Y:%.*]], [[T0]]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, -1101 %t1 = add i32 %t0, %y102 call void @use32(i32 %t1)103 %t2 = add i32 %t1, 1104 ret i32 %t2105}106 107define i32 @t7(i32 %x, i32 %y) {108; CHECK-LABEL: @t7(109; CHECK-NEXT: [[T0:%.*]] = xor i32 [[X:%.*]], -1110; CHECK-NEXT: call void @use32(i32 [[T0]])111; CHECK-NEXT: [[T1:%.*]] = add i32 [[Y:%.*]], [[T0]]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, -1117 call void @use32(i32 %t0)118 %t1 = add i32 %t0, %y119 call void @use32(i32 %t1)120 %t2 = add i32 %t1, 1121 ret i32 %t2122}123 124;------------------------------------------------------------------------------;125; Commutativity126;------------------------------------------------------------------------------;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:%.*]], -1134; 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, -1142 call void @use32(i32 %t0)143 %t1 = add i32 %y, %t0 ; swapped144 call void @use32(i32 %t1)145 %t2 = add i32 %t1, 1146 ret i32 %t2147}148 149define i32 @t9_commutative1(i32 %x, i32 %y) {150; CHECK-LABEL: @t9_commutative1(151; CHECK-NEXT: [[T0:%.*]] = xor i32 [[X:%.*]], -1152; 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, -1159 call void @use32(i32 %t0)160 %t1 = add i32 %t0, 1 ; +1 is not last161 call void @use32(i32 %t1)162 %t2 = add i32 %t1, %y ;163 ret i32 %t2164}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:%.*]], -1170; 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, -1178 call void @use32(i32 %t0)179 %t1 = add i32 %t0, 1 ; +1 is not last180 call void @use32(i32 %t1)181 %t2 = add i32 %y, %t1 ; swapped182 ret i32 %t2183}184 185;------------------------------------------------------------------------------;186; Basic negative tests187;------------------------------------------------------------------------------;188 189define i32 @n11(i32 %x, i32 %y) {190; CHECK-LABEL: @n11(191; CHECK-NEXT: [[T0:%.*]] = xor i32 [[X:%.*]], 2147483647192; CHECK-NEXT: [[T1:%.*]] = add i32 [[T0]], [[Y:%.*]]193; CHECK-NEXT: [[T2:%.*]] = add i32 [[T1]], 1194; CHECK-NEXT: ret i32 [[T2]]195;196 %t0 = xor i32 %x, 2147483647 ; not -1197 %t1 = add i32 %t0, %y198 %t2 = add i32 %t1, 1199 ret i32 %t2200}201 202define i32 @n12(i32 %x, i32 %y) {203; CHECK-LABEL: @n12(204; CHECK-NEXT: [[T0:%.*]] = xor i32 [[X:%.*]], -1205; CHECK-NEXT: [[T1:%.*]] = add i32 [[Y:%.*]], [[T0]]206; CHECK-NEXT: [[T2:%.*]] = add i32 [[T1]], 2207; CHECK-NEXT: ret i32 [[T2]]208;209 %t0 = xor i32 %x, -1210 %t1 = add i32 %t0, %y211 %t2 = add i32 %t1, 2 ; not +1212 ret i32 %t2213}214