1; RUN: opt < %s -slsr -gvn -dce -S | FileCheck %s 2 3target datalayout = "e-i64:64-v16:16-v32:32-n16:32:64" 4 5define void @slsr1(i32 %b, i32 %s) { 6; CHECK-LABEL: @slsr1( 7 ; foo(b * s); 8 %mul0 = mul i32 %b, %s 9; CHECK: mul i32 10; CHECK-NOT: mul i32 11 call void @foo(i32 %mul0) 12 13 ; foo((b + 1) * s); 14 %b1 = add i32 %b, 1 15 %mul1 = mul i32 %b1, %s 16 call void @foo(i32 %mul1) 17 18 ; foo((b + 2) * s); 19 %b2 = add i32 %b, 2 20 %mul2 = mul i32 %b2, %s 21 call void @foo(i32 %mul2) 22 23 ret void 24} 25 26; foo(a * b) 27; foo((a + 1) * b) 28; foo(a * (b + 1)) 29; foo((a + 1) * (b + 1)) 30define void @slsr2(i32 %a, i32 %b) { 31; CHECK-LABEL: @slsr2( 32 %a1 = add i32 %a, 1 33 %b1 = add i32 %b, 1 34 %mul0 = mul i32 %a, %b 35; CHECK: mul i32 36; CHECK-NOT: mul i32 37 %mul1 = mul i32 %a1, %b 38 %mul2 = mul i32 %a, %b1 39 %mul3 = mul i32 %a1, %b1 40 41 call void @foo(i32 %mul0) 42 call void @foo(i32 %mul1) 43 call void @foo(i32 %mul2) 44 call void @foo(i32 %mul3) 45 46 ret void 47} 48 49; The bump is a multiple of the stride. 50; 51; foo(b * s); 52; foo((b + 2) * s); 53; foo((b + 4) * s); 54; => 55; mul0 = b * s; 56; bump = s * 2; 57; mul1 = mul0 + bump; // GVN ensures mul1 and mul2 use the same bump. 58; mul2 = mul1 + bump; 59define void @slsr3(i32 %b, i32 %s) { 60; CHECK-LABEL: @slsr3( 61 %mul0 = mul i32 %b, %s 62; CHECK: mul i32 63 call void @foo(i32 %mul0) 64 65 %b1 = add i32 %b, 2 66 %mul1 = mul i32 %b1, %s 67; CHECK: [[BUMP:%[a-zA-Z0-9]+]] = shl i32 %s, 1 68; CHECK: %mul1 = add i32 %mul0, [[BUMP]] 69 call void @foo(i32 %mul1) 70 71 %b2 = add i32 %b, 4 72 %mul2 = mul i32 %b2, %s 73; CHECK: %mul2 = add i32 %mul1, [[BUMP]] 74 call void @foo(i32 %mul2) 75 76 ret void 77} 78 79; Do not rewrite a candidate if its potential basis does not dominate it. 80; 81; if (cond) 82; foo(a * b); 83; foo((a + 1) * b); 84define void @not_dominate(i1 %cond, i32 %a, i32 %b) { 85; CHECK-LABEL: @not_dominate( 86entry: 87 %a1 = add i32 %a, 1 88 br i1 %cond, label %then, label %merge 89 90then: 91 %mul0 = mul i32 %a, %b 92; CHECK: %mul0 = mul i32 %a, %b 93 call void @foo(i32 %mul0) 94 br label %merge 95 96merge: 97 %mul1 = mul i32 %a1, %b 98; CHECK: %mul1 = mul i32 %a1, %b 99 call void @foo(i32 %mul1) 100 ret void 101} 102 103declare void @foo(i32) 104