137 lines · plain
1; NOTE: Assertions have been autogenerated by utils/update_test_checks.py UTC_ARGS: --version 42; RUN: opt < %s -passes=instcombine -S | FileCheck %s3 4define i32 @shl_cttz_false(i32 %x, i32 %y) {5; CHECK-LABEL: define i32 @shl_cttz_false(6; CHECK-SAME: i32 [[X:%.*]], i32 [[Y:%.*]]) {7; CHECK-NEXT: entry:8; CHECK-NEXT: [[CTTZ:%.*]] = call range(i32 0, 33) i32 @llvm.cttz.i32(i32 [[Y]], i1 true)9; CHECK-NEXT: [[RES:%.*]] = shl i32 [[X]], [[CTTZ]]10; CHECK-NEXT: ret i32 [[RES]]11;12entry:13 %cttz = call i32 @llvm.cttz.i32(i32 %y, i1 false)14 %res = shl i32 %x, %cttz15 ret i32 %res16}17 18; Make sure that noundef is dropped.19 20define i32 @shl_cttz_false_noundef(i32 %x, i32 %y) {21; CHECK-LABEL: define i32 @shl_cttz_false_noundef(22; CHECK-SAME: i32 [[X:%.*]], i32 [[Y:%.*]]) {23; CHECK-NEXT: entry:24; CHECK-NEXT: [[CTTZ:%.*]] = call range(i32 0, 33) i32 @llvm.cttz.i32(i32 [[Y]], i1 true)25; CHECK-NEXT: [[RES:%.*]] = shl i32 [[X]], [[CTTZ]]26; CHECK-NEXT: ret i32 [[RES]]27;28entry:29 %cttz = call noundef i32 @llvm.cttz.i32(i32 %y, i1 false)30 %res = shl i32 %x, %cttz31 ret i32 %res32}33 34define i32 @shl_ctlz_false(i32 %x, i32 %y) {35; CHECK-LABEL: define i32 @shl_ctlz_false(36; CHECK-SAME: i32 [[X:%.*]], i32 [[Y:%.*]]) {37; CHECK-NEXT: entry:38; CHECK-NEXT: [[CTTZ:%.*]] = call range(i32 0, 33) i32 @llvm.ctlz.i32(i32 [[Y]], i1 true)39; CHECK-NEXT: [[RES:%.*]] = shl i32 [[X]], [[CTTZ]]40; CHECK-NEXT: ret i32 [[RES]]41;42entry:43 %cttz = call i32 @llvm.ctlz.i32(i32 %y, i1 false)44 %res = shl i32 %x, %cttz45 ret i32 %res46}47 48define i32 @lshr_cttz_false(i32 %x, i32 %y) {49; CHECK-LABEL: define i32 @lshr_cttz_false(50; CHECK-SAME: i32 [[X:%.*]], i32 [[Y:%.*]]) {51; CHECK-NEXT: entry:52; CHECK-NEXT: [[CTTZ:%.*]] = call range(i32 0, 33) i32 @llvm.cttz.i32(i32 [[Y]], i1 true)53; CHECK-NEXT: [[RES:%.*]] = lshr i32 [[X]], [[CTTZ]]54; CHECK-NEXT: ret i32 [[RES]]55;56entry:57 %cttz = call i32 @llvm.cttz.i32(i32 %y, i1 false)58 %res = lshr i32 %x, %cttz59 ret i32 %res60}61 62define i32 @ashr_cttz_false(i32 %x, i32 %y) {63; CHECK-LABEL: define i32 @ashr_cttz_false(64; CHECK-SAME: i32 [[X:%.*]], i32 [[Y:%.*]]) {65; CHECK-NEXT: entry:66; CHECK-NEXT: [[CTTZ:%.*]] = call range(i32 0, 33) i32 @llvm.cttz.i32(i32 [[Y]], i1 true)67; CHECK-NEXT: [[RES:%.*]] = ashr i32 [[X]], [[CTTZ]]68; CHECK-NEXT: ret i32 [[RES]]69;70entry:71 %cttz = call i32 @llvm.cttz.i32(i32 %y, i1 false)72 %res = ashr i32 %x, %cttz73 ret i32 %res74}75 76define i32 @shl_cttz_false_multiuse(i32 %x, i32 %y) {77; CHECK-LABEL: define i32 @shl_cttz_false_multiuse(78; CHECK-SAME: i32 [[X:%.*]], i32 [[Y:%.*]]) {79; CHECK-NEXT: entry:80; CHECK-NEXT: [[CTTZ:%.*]] = call range(i32 0, 33) i32 @llvm.cttz.i32(i32 [[Y]], i1 false)81; CHECK-NEXT: call void @use(i32 [[CTTZ]])82; CHECK-NEXT: [[RES:%.*]] = shl i32 [[X]], [[CTTZ]]83; CHECK-NEXT: ret i32 [[RES]]84;85entry:86 %cttz = call i32 @llvm.cttz.i32(i32 %y, i1 false)87 call void @use(i32 %cttz)88 %res = shl i32 %x, %cttz89 ret i32 %res90}91 92define i32 @shl_cttz_as_lhs(i32 %x, i32 %y) {93; CHECK-LABEL: define i32 @shl_cttz_as_lhs(94; CHECK-SAME: i32 [[X:%.*]], i32 [[Y:%.*]]) {95; CHECK-NEXT: entry:96; CHECK-NEXT: [[CTTZ:%.*]] = call range(i32 0, 33) i32 @llvm.cttz.i32(i32 [[Y]], i1 false)97; CHECK-NEXT: [[RES:%.*]] = shl i32 [[CTTZ]], [[X]]98; CHECK-NEXT: ret i32 [[RES]]99;100entry:101 %cttz = call i32 @llvm.cttz.i32(i32 %y, i1 false)102 %res = shl i32 %cttz, %x103 ret i32 %res104}105 106define i64 @fold_cttz_64() vscale_range(1,16) {107; CHECK-LABEL: define i64 @fold_cttz_64(108; CHECK-SAME: ) #[[ATTR0:[0-9]+]] {109; CHECK-NEXT: entry:110; CHECK-NEXT: ret i64 4111;112entry:113 %vscale = tail call i64 @llvm.vscale.i64()114 %shl0 = shl nuw nsw i64 %vscale, 4115 %shl1 = shl nuw nsw i64 %vscale, 2116 %cttz = tail call range(i64 2, 65) i64 @llvm.cttz.i64(i64 %shl1, i1 true)117 %div1 = lshr i64 %shl0, %cttz118 ret i64 %div1119}120 121define i32 @fold_cttz_32() vscale_range(1,16) {122; CHECK-LABEL: define i32 @fold_cttz_32(123; CHECK-SAME: ) #[[ATTR0]] {124; CHECK-NEXT: entry:125; CHECK-NEXT: ret i32 4126;127entry:128 %vscale = tail call i32 @llvm.vscale.i32()129 %shl0 = shl nuw nsw i32 %vscale, 4130 %shl1 = shl nuw nsw i32 %vscale, 2131 %cttz = tail call range(i32 2, 65) i32 @llvm.cttz.i32(i32 %shl1, i1 true)132 %div1 = lshr i32 %shl0, %cttz133 ret i32 %div1134}135 136declare void @use(i32)137