1; NOTE: Assertions have been autogenerated by utils/update_analyze_test_checks.py 2; RUN: opt -S -analyze -enable-new-pm=0 -scalar-evolution < %s | FileCheck %s 3; RUN: opt -S -disable-output "-passes=print<scalar-evolution>" < %s 2>&1 | FileCheck %s 4 5; These testcases aren't *identical* but they have the same/similar meaning. 6 7; The obvious case. 8define i32 @mul(i32 %val, i32 %num) nounwind { 9; CHECK-LABEL: 'mul' 10; CHECK-NEXT: Classifying expressions for: @mul 11; CHECK-NEXT: %tmp1 = mul i32 %val, %num 12; CHECK-NEXT: --> (%val * %num) U: full-set S: full-set 13; CHECK-NEXT: %tmp2 = udiv i32 %tmp1, %num 14; CHECK-NEXT: --> ((%val * %num) /u %num) U: full-set S: full-set 15; CHECK-NEXT: Determining loop execution counts for: @mul 16; 17 %tmp1 = mul i32 %val, %num 18 %tmp2 = udiv i32 %tmp1, %num 19 ret i32 %tmp2 20} 21 22; Or, it could be any number of equivalent patterns with mask: 23; a) x & (1 << nbits) - 1 24; b) x & ~(-1 << nbits) 25; c) x & (-1 >> (32 - y)) 26; d) x << (32 - y) >> (32 - y) 27 28define i32 @mask_a(i32 %val, i32 %numlowbits) nounwind { 29; CHECK-LABEL: 'mask_a' 30; CHECK-NEXT: Classifying expressions for: @mask_a 31; CHECK-NEXT: %onebit = shl i32 1, %numlowbits 32; CHECK-NEXT: --> %onebit U: full-set S: full-set 33; CHECK-NEXT: %mask = add nsw i32 %onebit, -1 34; CHECK-NEXT: --> (-1 + %onebit) U: full-set S: full-set 35; CHECK-NEXT: %masked = and i32 %mask, %val 36; CHECK-NEXT: --> %masked U: full-set S: full-set 37; CHECK-NEXT: Determining loop execution counts for: @mask_a 38; 39 %onebit = shl i32 1, %numlowbits 40 %mask = add nsw i32 %onebit, -1 41 %masked = and i32 %mask, %val 42 ret i32 %masked 43} 44 45define i32 @mask_b(i32 %val, i32 %numlowbits) nounwind { 46; CHECK-LABEL: 'mask_b' 47; CHECK-NEXT: Classifying expressions for: @mask_b 48; CHECK-NEXT: %notmask = shl i32 -1, %numlowbits 49; CHECK-NEXT: --> %notmask U: full-set S: full-set 50; CHECK-NEXT: %mask = xor i32 %notmask, -1 51; CHECK-NEXT: --> (-1 + (-1 * %notmask)) U: full-set S: full-set 52; CHECK-NEXT: %masked = and i32 %mask, %val 53; CHECK-NEXT: --> %masked U: full-set S: full-set 54; CHECK-NEXT: Determining loop execution counts for: @mask_b 55; 56 %notmask = shl i32 -1, %numlowbits 57 %mask = xor i32 %notmask, -1 58 %masked = and i32 %mask, %val 59 ret i32 %masked 60} 61 62define i32 @mask_c(i32 %val, i32 %numlowbits) nounwind { 63; CHECK-LABEL: 'mask_c' 64; CHECK-NEXT: Classifying expressions for: @mask_c 65; CHECK-NEXT: %numhighbits = sub i32 32, %numlowbits 66; CHECK-NEXT: --> (32 + (-1 * %numlowbits)) U: full-set S: full-set 67; CHECK-NEXT: %mask = lshr i32 -1, %numhighbits 68; CHECK-NEXT: --> %mask U: full-set S: full-set 69; CHECK-NEXT: %masked = and i32 %mask, %val 70; CHECK-NEXT: --> %masked U: full-set S: full-set 71; CHECK-NEXT: Determining loop execution counts for: @mask_c 72; 73 %numhighbits = sub i32 32, %numlowbits 74 %mask = lshr i32 -1, %numhighbits 75 %masked = and i32 %mask, %val 76 ret i32 %masked 77} 78 79define i32 @mask_d(i32 %val, i32 %numlowbits) nounwind { 80; CHECK-LABEL: 'mask_d' 81; CHECK-NEXT: Classifying expressions for: @mask_d 82; CHECK-NEXT: %numhighbits = sub i32 32, %numlowbits 83; CHECK-NEXT: --> (32 + (-1 * %numlowbits)) U: full-set S: full-set 84; CHECK-NEXT: %highbitscleared = shl i32 %val, %numhighbits 85; CHECK-NEXT: --> %highbitscleared U: full-set S: full-set 86; CHECK-NEXT: %masked = lshr i32 %highbitscleared, %numhighbits 87; CHECK-NEXT: --> %masked U: full-set S: full-set 88; CHECK-NEXT: Determining loop execution counts for: @mask_d 89; 90 %numhighbits = sub i32 32, %numlowbits 91 %highbitscleared = shl i32 %val, %numhighbits 92 %masked = lshr i32 %highbitscleared, %numhighbits 93 ret i32 %masked 94} 95