1; NOTE: Assertions have been autogenerated by utils/update_test_checks.py UTC_ARGS: --version 4 2; RUN: opt < %s -passes=instcombine -S | FileCheck %s 3 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, %cttz 15 ret i32 %res 16} 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, %cttz 31 ret i32 %res 32} 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, %cttz 45 ret i32 %res 46} 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, %cttz 59 ret i32 %res 60} 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, %cttz 73 ret i32 %res 74} 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, %cttz 89 ret i32 %res 90} 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, %x 103 ret i32 %res 104} 105 106declare void @use(i32) 107