139 lines · plain
1; NOTE: Assertions have been autogenerated by utils/update_test_checks.py UTC_ARGS: --prefix-filecheck-ir-name V2; RUN: opt < %s -passes=instcombine -S | FileCheck %s3 4; https://bugs.llvm.org/show_bug.cgi?id=384465 6; Pattern:7; ~(x ^ y)8; Should be transformed into:9; (~x) ^ y10; or into11; x ^ (~y)12 13; While -passes=reassociate does handle this simple pattern, it does not handle14; the more complicated motivating pattern.15 16; ============================================================================ ;17; Basic positive tests18; ============================================================================ ;19 20; If the operand is easily-invertible, fold into it.21declare i1 @gen1()22 23define i1 @positive_easyinvert(i16 %x, i8 %y) {24; CHECK-LABEL: @positive_easyinvert(25; CHECK-NEXT: [[VTMP2:%.*]] = icmp slt i8 [[Y:%.*]], 026; CHECK-NEXT: [[TMP1:%.*]] = icmp sgt i16 [[X:%.*]], -127; CHECK-NEXT: [[VTMP4:%.*]] = xor i1 [[VTMP2]], [[TMP1]]28; CHECK-NEXT: ret i1 [[VTMP4]]29;30 %tmp1 = icmp slt i16 %x, 031 %tmp2 = icmp slt i8 %y, 032 %tmp3 = xor i1 %tmp2, %tmp133 %tmp4 = xor i1 %tmp3, true34 ret i1 %tmp435}36 37define i1 @positive_easyinvert0(i8 %y) {38; CHECK-LABEL: @positive_easyinvert0(39; CHECK-NEXT: [[VTMP1:%.*]] = call i1 @gen1()40; CHECK-NEXT: [[TMP1:%.*]] = icmp sgt i8 [[Y:%.*]], -141; CHECK-NEXT: [[VTMP4:%.*]] = xor i1 [[TMP1]], [[VTMP1]]42; CHECK-NEXT: ret i1 [[VTMP4]]43;44 %tmp1 = call i1 @gen1()45 %cond = icmp slt i8 %y, 046 %tmp3 = xor i1 %cond, %tmp147 %tmp4 = xor i1 %tmp3, true48 ret i1 %tmp449}50 51define i1 @positive_easyinvert1(i8 %y) {52; CHECK-LABEL: @positive_easyinvert1(53; CHECK-NEXT: [[VTMP1:%.*]] = call i1 @gen1()54; CHECK-NEXT: [[TMP1:%.*]] = icmp sgt i8 [[Y:%.*]], -155; CHECK-NEXT: [[VTMP4:%.*]] = xor i1 [[VTMP1]], [[TMP1]]56; CHECK-NEXT: ret i1 [[VTMP4]]57;58 %tmp1 = call i1 @gen1()59 %tmp2 = icmp slt i8 %y, 060 %tmp3 = xor i1 %tmp1, %tmp261 %tmp4 = xor i1 %tmp3, true62 ret i1 %tmp463}64 65; ============================================================================ ;66; One-use tests with easily-invertible operand.67; ============================================================================ ;68 69declare void @use1(i1)70 71define i1 @oneuse_easyinvert_0(i8 %y) {72; CHECK-LABEL: @oneuse_easyinvert_0(73; CHECK-NEXT: [[VTMP1:%.*]] = call i1 @gen1()74; CHECK-NEXT: [[VTMP2:%.*]] = icmp slt i8 [[Y:%.*]], 075; CHECK-NEXT: call void @use1(i1 [[VTMP2]])76; CHECK-NEXT: [[VTMP3:%.*]] = xor i1 [[VTMP1]], [[VTMP2]]77; CHECK-NEXT: [[VTMP4:%.*]] = xor i1 [[VTMP3]], true78; CHECK-NEXT: ret i1 [[VTMP4]]79;80 %tmp1 = call i1 @gen1()81 %tmp2 = icmp slt i8 %y, 082 call void @use1(i1 %tmp2)83 %tmp3 = xor i1 %tmp1, %tmp284 %tmp4 = xor i1 %tmp3, true85 ret i1 %tmp486}87 88define i1 @oneuse_easyinvert_1(i8 %y) {89; CHECK-LABEL: @oneuse_easyinvert_1(90; CHECK-NEXT: [[VTMP1:%.*]] = call i1 @gen1()91; CHECK-NEXT: [[VTMP2:%.*]] = icmp slt i8 [[Y:%.*]], 092; CHECK-NEXT: [[VTMP3:%.*]] = xor i1 [[VTMP1]], [[VTMP2]]93; CHECK-NEXT: call void @use1(i1 [[VTMP3]])94; CHECK-NEXT: [[VTMP4:%.*]] = xor i1 [[VTMP3]], true95; CHECK-NEXT: ret i1 [[VTMP4]]96;97 %tmp1 = call i1 @gen1()98 %tmp2 = icmp slt i8 %y, 099 %tmp3 = xor i1 %tmp1, %tmp2100 call void @use1(i1 %tmp3)101 %tmp4 = xor i1 %tmp3, true102 ret i1 %tmp4103}104 105define i1 @oneuse_easyinvert_2(i8 %y) {106; CHECK-LABEL: @oneuse_easyinvert_2(107; CHECK-NEXT: [[VTMP1:%.*]] = call i1 @gen1()108; CHECK-NEXT: [[VTMP2:%.*]] = icmp slt i8 [[Y:%.*]], 0109; CHECK-NEXT: call void @use1(i1 [[VTMP2]])110; CHECK-NEXT: [[VTMP3:%.*]] = xor i1 [[VTMP1]], [[VTMP2]]111; CHECK-NEXT: call void @use1(i1 [[VTMP3]])112; CHECK-NEXT: [[VTMP4:%.*]] = xor i1 [[VTMP3]], true113; CHECK-NEXT: ret i1 [[VTMP4]]114;115 %tmp1 = call i1 @gen1()116 %tmp2 = icmp slt i8 %y, 0117 call void @use1(i1 %tmp2)118 %tmp3 = xor i1 %tmp1, %tmp2119 call void @use1(i1 %tmp3)120 %tmp4 = xor i1 %tmp3, true121 ret i1 %tmp4122}123 124; ============================================================================ ;125; Negative tests126; ============================================================================ ;127 128; Not easily invertible.129define i32 @negative(i32 %x, i32 %y) {130; CHECK-LABEL: @negative(131; CHECK-NEXT: [[VTMP1:%.*]] = xor i32 [[X:%.*]], [[Y:%.*]]132; CHECK-NEXT: [[VTMP2:%.*]] = xor i32 [[VTMP1]], -1133; CHECK-NEXT: ret i32 [[VTMP2]]134;135 %tmp1 = xor i32 %x, %y136 %tmp2 = xor i32 %tmp1, -1137 ret i32 %tmp2138}139