1; NOTE: Assertions have been autogenerated by utils/update_test_checks.py UTC_ARGS: --version 2 2; RUN: opt < %s -passes=ipsccp -S | FileCheck %s 3 4declare void @llvm.assume(i1) 5declare i8 @llvm.ctpop.i8(i8) 6 7; https://alive2.llvm.org/ce/z/LV_8xy 8define i8 @and_add_shl(i8 %x) { 9; CHECK-LABEL: define i8 @and_add_shl 10; CHECK-SAME: (i8 [[X:%.*]]) { 11; CHECK-NEXT: [[OP1_P2:%.*]] = icmp ule i8 [[X]], 5 12; CHECK-NEXT: call void @llvm.assume(i1 [[OP1_P2]]) 13; CHECK-NEXT: [[SHIFT:%.*]] = shl nuw nsw i8 1, [[X]] 14; CHECK-NEXT: [[SUB:%.*]] = add nsw i8 [[SHIFT]], -1 15; CHECK-NEXT: ret i8 0 16; 17 %op1_p2 = icmp ule i8 %x, 5 18 call void @llvm.assume(i1 %op1_p2) 19 %shift = shl i8 1, %x 20 %sub = add i8 %shift, -1 21 %r = and i8 %sub, 32 22 ret i8 %r 23} 24 25; https://alive2.llvm.org/ce/z/YNYYdV 26define i8 @and_not_shl(i8 %x) { 27; CHECK-LABEL: define i8 @and_not_shl 28; CHECK-SAME: (i8 [[X:%.*]]) { 29; CHECK-NEXT: [[OP1_P2:%.*]] = icmp ule i8 [[X]], 5 30; CHECK-NEXT: call void @llvm.assume(i1 [[OP1_P2]]) 31; CHECK-NEXT: [[SHIFT:%.*]] = shl nsw i8 -1, [[X]] 32; CHECK-NEXT: [[NOT:%.*]] = xor i8 [[SHIFT]], -1 33; CHECK-NEXT: ret i8 0 34; 35 %op1_p2 = icmp ule i8 %x, 5 36 call void @llvm.assume(i1 %op1_p2) 37 %shift = shl i8 -1, %x 38 %not = xor i8 %shift, -1 39 %r = and i8 %not, 32 40 ret i8 %r 41} 42 43define i8 @and_not_shl_1(i8 %x) { 44; CHECK-LABEL: define i8 @and_not_shl_1 45; CHECK-SAME: (i8 [[X:%.*]]) { 46; CHECK-NEXT: [[OP1_P2:%.*]] = icmp ule i8 [[X]], 4 47; CHECK-NEXT: call void @llvm.assume(i1 [[OP1_P2]]) 48; CHECK-NEXT: [[SHIFT:%.*]] = shl nsw i8 -1, [[X]] 49; CHECK-NEXT: [[NOT:%.*]] = xor i8 [[SHIFT]], -1 50; CHECK-NEXT: ret i8 0 51; 52 %op1_p2 = icmp ule i8 %x, 4 53 call void @llvm.assume(i1 %op1_p2) 54 %shift = shl i8 -1, %x 55 %not = xor i8 %shift, -1 56 %r = and i8 %not, 48 ; 3 * 16 57 ret i8 %r 58} 59 60; Negative test: https://alive2.llvm.org/ce/z/Zv4Pyu 61define i8 @and_add_shl_overlap(i8 %x) { 62; CHECK-LABEL: define range(i8 0, 33) i8 @and_add_shl_overlap 63; CHECK-SAME: (i8 [[X:%.*]]) { 64; CHECK-NEXT: [[OP1_P2:%.*]] = icmp ule i8 [[X]], 6 65; CHECK-NEXT: call void @llvm.assume(i1 [[OP1_P2]]) 66; CHECK-NEXT: [[SHIFT:%.*]] = shl nuw nsw i8 1, [[X]] 67; CHECK-NEXT: [[SUB:%.*]] = add nsw i8 [[SHIFT]], -1 68; CHECK-NEXT: [[R:%.*]] = and i8 [[SUB]], 32 69; CHECK-NEXT: ret i8 [[R]] 70; 71 %op1_p2 = icmp ule i8 %x, 6 72 call void @llvm.assume(i1 %op1_p2) 73 %shift = shl i8 1, %x 74 %sub = add i8 %shift, -1 75 %r = and i8 %sub, 32 ; expect 64 76 ret i8 %r 77} 78 79define i8 @and_not_shl_overlap(i8 %x) { 80; CHECK-LABEL: define range(i8 0, 5) i8 @and_not_shl_overlap 81; CHECK-SAME: (i8 [[X:%.*]]) { 82; CHECK-NEXT: [[OP1_P2:%.*]] = icmp ule i8 [[X]], 3 83; CHECK-NEXT: call void @llvm.assume(i1 [[OP1_P2]]) 84; CHECK-NEXT: [[SHIFT:%.*]] = shl nsw i8 -1, [[X]] 85; CHECK-NEXT: [[NOT:%.*]] = xor i8 [[SHIFT]], -1 86; CHECK-NEXT: [[R:%.*]] = and i8 [[NOT]], 4 87; CHECK-NEXT: ret i8 [[R]] 88; 89 %op1_p2 = icmp ule i8 %x, 3 90 call void @llvm.assume(i1 %op1_p2) 91 %shift = shl i8 -1, %x 92 %not = xor i8 %shift, -1 93 %r = and i8 %not, 4 ; expect 8 94 ret i8 %r 95} 96