1; NOTE: Assertions have been autogenerated by utils/update_test_checks.py 2; RUN: opt -passes=instcombine -S < %s | FileCheck %s 3 4declare void @use(i8) 5 6define i8 @basic(i8 %x, i8 %y) { 7; CHECK-LABEL: @basic( 8; CHECK-NEXT: [[NOTA:%.*]] = sub i8 [[X:%.*]], [[Y:%.*]] 9; CHECK-NEXT: ret i8 [[NOTA]] 10; 11 %notx = xor i8 %x, -1 12 %a = add i8 %notx, %y 13 %nota = xor i8 %a, -1 14 ret i8 %nota 15} 16 17define i8 @basic_com_add(i8 %x, i8 %y) { 18; CHECK-LABEL: @basic_com_add( 19; CHECK-NEXT: [[NOTA:%.*]] = sub i8 [[Y:%.*]], [[X:%.*]] 20; CHECK-NEXT: ret i8 [[NOTA]] 21; 22 %noty = xor i8 %y, -1 23 %a = add i8 %x, %noty 24 %nota = xor i8 %a, -1 25 ret i8 %nota 26} 27 28define i8 @basic_use_xor(i8 %x, i8 %y) { 29; CHECK-LABEL: @basic_use_xor( 30; CHECK-NEXT: [[NOTX:%.*]] = xor i8 [[X:%.*]], -1 31; CHECK-NEXT: call void @use(i8 [[NOTX]]) 32; CHECK-NEXT: [[NOTA:%.*]] = sub i8 [[X]], [[Y:%.*]] 33; CHECK-NEXT: ret i8 [[NOTA]] 34; 35 %notx = xor i8 %x, -1 36 call void @use(i8 %notx) 37 %a = add i8 %notx, %y 38 %nota = xor i8 %a, -1 39 ret i8 %nota 40} 41 42define i8 @basic_use_add(i8 %x, i8 %y) { 43; CHECK-LABEL: @basic_use_add( 44; CHECK-NEXT: [[NOTX:%.*]] = xor i8 [[X:%.*]], -1 45; CHECK-NEXT: [[A:%.*]] = add i8 [[Y:%.*]], [[NOTX]] 46; CHECK-NEXT: call void @use(i8 [[A]]) 47; CHECK-NEXT: [[NOTA:%.*]] = sub i8 [[X]], [[Y]] 48; CHECK-NEXT: ret i8 [[NOTA]] 49; 50 %notx = xor i8 %x, -1 51 %a = add i8 %notx, %y 52 call void @use(i8 %a) 53 %nota = xor i8 %a, -1 54 ret i8 %nota 55} 56 57define i8 @basic_use_both(i8 %x, i8 %y) { 58; CHECK-LABEL: @basic_use_both( 59; CHECK-NEXT: [[NOTX:%.*]] = xor i8 [[X:%.*]], -1 60; CHECK-NEXT: call void @use(i8 [[NOTX]]) 61; CHECK-NEXT: [[A:%.*]] = add i8 [[Y:%.*]], [[NOTX]] 62; CHECK-NEXT: call void @use(i8 [[A]]) 63; CHECK-NEXT: [[NOTA:%.*]] = sub i8 [[X]], [[Y]] 64; CHECK-NEXT: ret i8 [[NOTA]] 65; 66 %notx = xor i8 %x, -1 67 call void @use(i8 %notx) 68 %a = add i8 %notx, %y 69 call void @use(i8 %a) 70 %nota = xor i8 %a, -1 71 ret i8 %nota 72} 73 74define i8 @basic_preserve_nsw(i8 %x, i8 %y) { 75; CHECK-LABEL: @basic_preserve_nsw( 76; CHECK-NEXT: [[NOTA:%.*]] = sub nsw i8 [[X:%.*]], [[Y:%.*]] 77; CHECK-NEXT: ret i8 [[NOTA]] 78; 79 %notx = xor i8 %x, -1 80 %a = add nsw i8 %notx, %y 81 %nota = xor i8 %a, -1 82 ret i8 %nota 83} 84 85define i8 @basic_preserve_nuw(i8 %x, i8 %y) { 86; CHECK-LABEL: @basic_preserve_nuw( 87; CHECK-NEXT: [[NOTA:%.*]] = sub nuw i8 [[X:%.*]], [[Y:%.*]] 88; CHECK-NEXT: ret i8 [[NOTA]] 89; 90 %notx = xor i8 %x, -1 91 %a = add nuw i8 %notx, %y 92 %nota = xor i8 %a, -1 93 ret i8 %nota 94} 95 96define i8 @basic_preserve_nuw_nsw(i8 %x, i8 %y) { 97; CHECK-LABEL: @basic_preserve_nuw_nsw( 98; CHECK-NEXT: [[NOTA:%.*]] = sub nuw nsw i8 [[X:%.*]], [[Y:%.*]] 99; CHECK-NEXT: ret i8 [[NOTA]] 100; 101 %notx = xor i8 %x, -1 102 %a = add nuw nsw i8 %notx, %y 103 %nota = xor i8 %a, -1 104 ret i8 %nota 105} 106 107define <4 x i32> @vector_test(<4 x i32> %x, <4 x i32> %y) { 108; CHECK-LABEL: @vector_test( 109; CHECK-NEXT: [[NOTA:%.*]] = sub <4 x i32> [[X:%.*]], [[Y:%.*]] 110; CHECK-NEXT: ret <4 x i32> [[NOTA]] 111; 112 %notx = xor <4 x i32> %x, <i32 -1, i32 -1, i32 -1, i32 -1> 113 %a = add <4 x i32> %notx, %y 114 %nota = xor <4 x i32> %a, <i32 -1, i32 -1, i32 -1, i32 -1> 115 ret <4 x i32> %nota 116} 117 118define <4 x i32> @vector_test_poison(<4 x i32> %x, <4 x i32> %y) { 119; CHECK-LABEL: @vector_test_poison( 120; CHECK-NEXT: [[NOTA:%.*]] = sub <4 x i32> [[X:%.*]], [[Y:%.*]] 121; CHECK-NEXT: ret <4 x i32> [[NOTA]] 122; 123 %notx = xor <4 x i32> %x, <i32 -1, i32 poison, i32 poison, i32 -1> 124 %a = add <4 x i32> %notx, %y 125 %nota = xor <4 x i32> %a, <i32 -1, i32 -1, i32 poison, i32 poison> 126 ret <4 x i32> %nota 127} 128 129 130define <4 x i32> @vector_test_poison_nsw_nuw(<4 x i32> %x, <4 x i32> %y) { 131; CHECK-LABEL: @vector_test_poison_nsw_nuw( 132; CHECK-NEXT: [[NOTA:%.*]] = sub nuw nsw <4 x i32> [[X:%.*]], [[Y:%.*]] 133; CHECK-NEXT: ret <4 x i32> [[NOTA]] 134; 135 %notx = xor <4 x i32> %x, <i32 -1, i32 poison, i32 poison, i32 -1> 136 %a = add nsw nuw <4 x i32> %notx, %y 137 %nota = xor <4 x i32> %a, <i32 -1, i32 -1, i32 poison, i32 poison> 138 ret <4 x i32> %nota 139} 140 141define i32 @pr50308(i1 %c1, i32 %v1, i32 %v2, i32 %v3) { 142; CHECK-LABEL: @pr50308( 143; CHECK-NEXT: entry: 144; CHECK-NEXT: br i1 [[C1:%.*]], label [[COND_TRUE:%.*]], label [[COND_END:%.*]] 145; CHECK: cond.true: 146; CHECK-NEXT: [[TMP0:%.*]] = sub i32 -2, [[V1:%.*]] 147; CHECK-NEXT: [[ADD1_NEG:%.*]] = xor i32 [[TMP0]], [[V2:%.*]] 148; CHECK-NEXT: br label [[COND_END]] 149; CHECK: cond.end: 150; CHECK-NEXT: [[COND_NEG:%.*]] = phi i32 [ [[ADD1_NEG]], [[COND_TRUE]] ], [ 0, [[ENTRY:%.*]] ] 151; CHECK-NEXT: [[SUB:%.*]] = add i32 [[COND_NEG]], [[V3:%.*]] 152; CHECK-NEXT: ret i32 [[SUB]] 153; 154entry: 155 br i1 %c1, label %cond.true, label %cond.end 156 157cond.true: 158 %add = add nsw i32 1, %v1 159 %xor = xor i32 %add, %v2 160 %add1 = add nsw i32 1, %xor 161 br label %cond.end 162 163cond.end: 164 %cond = phi i32 [ %add1, %cond.true ], [ 0, %entry ] 165 %sub = sub nsw i32 %v3, %cond 166 ret i32 %sub 167} 168 169@g = extern_weak global i32 170define void @pr50370(i32 %x) { 171; CHECK-LABEL: @pr50370( 172; CHECK-NEXT: entry: 173; CHECK-NEXT: store i32 poison, ptr undef, align 4 174; CHECK-NEXT: ret void 175; 176entry: 177 %xor = xor i32 %x, 1 178 %cmp = icmp eq ptr @g, null 179 %ext = zext i1 %cmp to i32 180 %or = or i32 %ext, 1 181 %or4 = or i32 %or, 65536 182 %B6 = ashr i32 65536, %or4 183 %B15 = srem i32 %B6, %xor 184 %B20 = sdiv i32 %or4, 2147483647 185 %B22 = add i32 %B15, %B20 186 %B14 = srem i32 %B6, %B22 187 %B12 = add i32 %B15, %B6 188 %B8 = shl i32 %B20, %B14 189 %B2 = xor i32 %B12, %B8 190 %B3 = or i32 %B12, undef 191 %B = xor i32 %B2, %B3 192 store i32 %B, ptr undef, align 4 193 ret void 194} 195