170 lines · plain
1; NOTE: Assertions have been autogenerated by utils/update_test_checks.py2; RUN: opt < %s -passes=instcombine -S | FileCheck %s3 4; Basic functional test5define i32 @basic(i32 %a, i32 %b) {6; CHECK-LABEL: @basic(7; CHECK-NEXT: [[CMP:%.*]] = icmp eq i32 [[A:%.*]], 08; CHECK-NEXT: [[RES:%.*]] = select i1 [[CMP]], i32 [[B:%.*]], i32 [[A]]9; CHECK-NEXT: ret i32 [[RES]]10;11 %cmp = icmp eq i32 %a, 012 %sel = select i1 %cmp, i32 %b, i32 013 %or = or i32 %sel, %a14 ret i32 %or15}16 17; Operand order swap test18define i32 @swap_operand_order(i32 %x, i32 %y) {19; CHECK-LABEL: @swap_operand_order(20; CHECK-NEXT: [[CMP:%.*]] = icmp eq i32 [[X:%.*]], 021; CHECK-NEXT: [[SEL:%.*]] = select i1 [[CMP]], i32 [[Y:%.*]], i32 022; CHECK-NEXT: [[RES:%.*]] = or i32 [[X]], [[SEL]]23; CHECK-NEXT: ret i32 [[RES]]24;25 %cmp = icmp eq i32 %x, 026 %sel = select i1 %cmp, i32 %y, i32 027 %or = or i32 %x, %sel28 ret i32 %or29}30 31; Negative test: Non-zero false value in select32define i32 @negative_non_zero_false_val(i32 %a, i32 %b) {33; CHECK-LABEL: @negative_non_zero_false_val(34; CHECK-NEXT: [[CMP:%.*]] = icmp eq i32 [[A:%.*]], 035; CHECK-NEXT: [[SEL:%.*]] = select i1 [[CMP]], i32 [[B:%.*]], i32 136; CHECK-NEXT: [[OR:%.*]] = or i32 [[SEL]], [[A]]37; CHECK-NEXT: ret i32 [[OR]]38;39 %cmp = icmp eq i32 %a, 040 %sel = select i1 %cmp, i32 %b, i32 141 %or = or i32 %sel, %a42 ret i32 %or43}44 45; Negative test: Incorrect comparison predicate (NE)46define i32 @negative_wrong_predicate(i32 %a, i32 %b) {47; CHECK-LABEL: @negative_wrong_predicate(48; CHECK-NEXT: [[CMP:%.*]] = icmp eq i32 [[A:%.*]], 049; CHECK-NEXT: [[OR:%.*]] = select i1 [[CMP]], i32 0, i32 [[TMP1:%.*]]50; CHECK-NEXT: [[OR1:%.*]] = or i32 [[OR]], [[A]]51; CHECK-NEXT: ret i32 [[OR1]]52;53 %cmp = icmp ne i32 %a, 054 %sel = select i1 %cmp, i32 %b, i32 055 %or = or i32 %sel, %a56 ret i32 %or57}58 59; Comparison direction swap test (0 == X)60define i32 @cmp_swapped(i32 %x, i32 %y) {61; CHECK-LABEL: @cmp_swapped(62; CHECK-NEXT: [[CMP:%.*]] = icmp eq i32 [[X:%.*]], 063; CHECK-NEXT: [[SEL:%.*]] = select i1 [[CMP]], i32 [[Y:%.*]], i32 064; CHECK-NEXT: [[RES:%.*]] = or i32 [[X]], [[SEL]]65; CHECK-NEXT: ret i32 [[RES]]66;67 %cmp = icmp eq i32 0, %x68 %sel = select i1 %cmp, i32 %y, i32 069 %or = or i32 %x, %sel70 ret i32 %or71}72 73; Complex expression test74define i32 @complex_expression(i32 %a, i32 %b) {75; CHECK-LABEL: @complex_expression(76; CHECK-NEXT: [[X:%.*]] = add i32 [[A:%.*]], 177; CHECK-NEXT: [[CMP:%.*]] = icmp eq i32 [[X]], 078; CHECK-NEXT: [[RES:%.*]] = select i1 [[CMP]], i32 [[B:%.*]], i32 [[X]]79; CHECK-NEXT: ret i32 [[RES]]80;81 %x = add i32 %a, 182 %cmp = icmp eq i32 %x, 083 %sel = select i1 %cmp, i32 %b, i32 084 %or = or i32 %sel, %x85 ret i32 %or86}87 88; zext test89define i32 @zext_cond(i8 %a, i32 %b) {90; CHECK-LABEL: @zext_cond(91; CHECK-NEXT: [[Z:%.*]] = zext i8 [[A:%.*]] to i3292; CHECK-NEXT: [[CMP:%.*]] = icmp eq i8 [[A]], 093; CHECK-NEXT: [[SEL:%.*]] = select i1 [[CMP]], i32 [[B:%.*]], i32 094; CHECK-NEXT: [[OR:%.*]] = or i32 [[SEL]], [[Z]]95; CHECK-NEXT: ret i32 [[OR]]96;97 %z = zext i8 %a to i3298 %cmp = icmp eq i8 %a, 099 %sel = select i1 %cmp, i32 %b, i32 0100 %or = or i32 %sel, %z101 ret i32 %or102}103 104; sext test105define i32 @sext_cond(i8 %a, i32 %b) {106; CHECK-LABEL: @sext_cond(107; CHECK-NEXT: [[S:%.*]] = sext i8 [[A:%.*]] to i32108; CHECK-NEXT: [[CMP:%.*]] = icmp eq i8 [[A]], 0109; CHECK-NEXT: [[SEL:%.*]] = select i1 [[CMP]], i32 [[B:%.*]], i32 0110; CHECK-NEXT: [[OR:%.*]] = or i32 [[SEL]], [[S]]111; CHECK-NEXT: ret i32 [[OR]]112;113 %s = sext i8 %a to i32114 %cmp = icmp eq i8 %a, 0115 %sel = select i1 %cmp, i32 %b, i32 0116 %or = or i32 %sel, %s117 ret i32 %or118}119 120; Vector type test121define <2 x i32> @vector_type(<2 x i32> %a, <2 x i32> %b) {122; CHECK-LABEL: @vector_type(123; CHECK-NEXT: [[CMP:%.*]] = icmp eq <2 x i32> [[A:%.*]], zeroinitializer124; CHECK-NEXT: [[RES:%.*]] = select <2 x i1> [[CMP]], <2 x i32> [[B:%.*]], <2 x i32> [[A]]125; CHECK-NEXT: ret <2 x i32> [[RES]]126;127 %cmp = icmp eq <2 x i32> %a, zeroinitializer128 %sel = select <2 x i1> %cmp, <2 x i32> %b, <2 x i32> zeroinitializer129 %or = or <2 x i32> %sel, %a130 ret <2 x i32> %or131}132 133; Pointer type test (should not trigger optimization)134define ptr @pointer_type(ptr %p, ptr %q) {135; CHECK-LABEL: @pointer_type(136; CHECK-NEXT: [[A:%.*]] = ptrtoint ptr [[P:%.*]] to i64137; CHECK-NEXT: [[CMP:%.*]] = icmp eq ptr [[P]], null138; CHECK-NEXT: [[SEL:%.*]] = select i1 [[CMP]], ptr [[Q:%.*]], ptr null139; CHECK-NEXT: [[SEL_INT:%.*]] = ptrtoint ptr [[SEL]] to i64140; CHECK-NEXT: [[OR:%.*]] = or i64 [[A]], [[SEL_INT]]141; CHECK-NEXT: [[RET:%.*]] = inttoptr i64 [[OR]] to ptr142; CHECK-NEXT: ret ptr [[RET]]143;144 %a = ptrtoint ptr %p to i64145 %cmp = icmp eq i64 %a, 0146 %sel = select i1 %cmp, ptr %q, ptr null147 %sel_int = ptrtoint ptr %sel to i64148 %or_val = or i64 %a, %sel_int149 %ret = inttoptr i64 %or_val to ptr150 ret ptr %ret151}152 153; Multi-use test (should not trigger optimization)154define i32 @multi_use_test(i32 %x, i32 %m) {155; CHECK-LABEL: @multi_use_test(156; CHECK-NEXT: [[CMP:%.*]] = icmp eq i32 [[X:%.*]], 0157; CHECK-NEXT: [[SEL:%.*]] = select i1 [[CMP]], i32 [[M:%.*]], i32 0158; CHECK-NEXT: [[OR:%.*]] = or i32 [[SEL]], [[X]]159; CHECK-NEXT: [[ADD:%.*]] = add i32 [[SEL]], [[X]]160; CHECK-NEXT: [[O2:%.*]] = sub i32 [[OR]], [[ADD]]161; CHECK-NEXT: ret i32 [[O2]]162;163 %cmp = icmp eq i32 %x, 0164 %sel = select i1 %cmp, i32 %m, i32 0165 %or = or i32 %sel, %x166 %add = add i32 %sel, %x167 %res = sub i32 %or, %add168 ret i32 %res169}170