255 lines · plain
1; NOTE: Assertions have been autogenerated by utils/update_test_checks.py2; RUN: opt -S -passes=verify,iroutliner -ir-outlining-no-cost < %s | FileCheck %s3 4; This test checks that commutative instructions where the operands are5; swapped are outlined as the same function.6 7; It also checks that non-commutative instructions outlined as different8; functions when the operands are swapped;9 10; These are identical functions, except that in the flipped functions,11; the operands in the adds are commuted. However, since add instructions12; are commutative, we should still outline from all four as the same13; instruction.14 15define void @outline_from_add1() {16; CHECK-LABEL: @outline_from_add1(17; CHECK-NEXT: entry:18; CHECK-NEXT: [[A:%.*]] = alloca i32, align 419; CHECK-NEXT: [[B:%.*]] = alloca i32, align 420; CHECK-NEXT: [[C:%.*]] = alloca i32, align 421; CHECK-NEXT: call void @outlined_ir_func_0(ptr [[A]], ptr [[B]], ptr [[C]])22; CHECK-NEXT: ret void23;24entry:25 %a = alloca i32, align 426 %b = alloca i32, align 427 %c = alloca i32, align 428 store i32 2, ptr %a, align 429 store i32 3, ptr %b, align 430 store i32 4, ptr %c, align 431 %al = load i32, ptr %a32 %bl = load i32, ptr %b33 %cl = load i32, ptr %c34 %0 = add i32 %al, %bl35 %1 = add i32 %al, %cl36 %2 = add i32 %bl, %cl37 ret void38}39 40define void @outline_from_add2() {41; CHECK-LABEL: @outline_from_add2(42; CHECK-NEXT: entry:43; CHECK-NEXT: [[A:%.*]] = alloca i32, align 444; CHECK-NEXT: [[B:%.*]] = alloca i32, align 445; CHECK-NEXT: [[C:%.*]] = alloca i32, align 446; CHECK-NEXT: call void @outlined_ir_func_0(ptr [[A]], ptr [[B]], ptr [[C]])47; CHECK-NEXT: ret void48;49entry:50 %a = alloca i32, align 451 %b = alloca i32, align 452 %c = alloca i32, align 453 store i32 2, ptr %a, align 454 store i32 3, ptr %b, align 455 store i32 4, ptr %c, align 456 %al = load i32, ptr %a57 %bl = load i32, ptr %b58 %cl = load i32, ptr %c59 %0 = add i32 %al, %bl60 %1 = add i32 %al, %cl61 %2 = add i32 %bl, %cl62 ret void63}64 65define void @outline_from_flipped_add3() {66; CHECK-LABEL: @outline_from_flipped_add3(67; CHECK-NEXT: entry:68; CHECK-NEXT: [[A:%.*]] = alloca i32, align 469; CHECK-NEXT: [[B:%.*]] = alloca i32, align 470; CHECK-NEXT: [[C:%.*]] = alloca i32, align 471; CHECK-NEXT: call void @outlined_ir_func_0(ptr [[A]], ptr [[B]], ptr [[C]])72; CHECK-NEXT: ret void73;74entry:75 %a = alloca i32, align 476 %b = alloca i32, align 477 %c = alloca i32, align 478 store i32 2, ptr %a, align 479 store i32 3, ptr %b, align 480 store i32 4, ptr %c, align 481 %al = load i32, ptr %a82 %bl = load i32, ptr %b83 %cl = load i32, ptr %c84 %0 = add i32 %bl, %al85 %1 = add i32 %cl, %al86 %2 = add i32 %cl, %bl87 ret void88}89 90define void @outline_from_flipped_add4() {91; CHECK-LABEL: @outline_from_flipped_add4(92; CHECK-NEXT: entry:93; CHECK-NEXT: [[A:%.*]] = alloca i32, align 494; CHECK-NEXT: [[B:%.*]] = alloca i32, align 495; CHECK-NEXT: [[C:%.*]] = alloca i32, align 496; CHECK-NEXT: call void @outlined_ir_func_0(ptr [[A]], ptr [[B]], ptr [[C]])97; CHECK-NEXT: ret void98;99entry:100 %a = alloca i32, align 4101 %b = alloca i32, align 4102 %c = alloca i32, align 4103 store i32 2, ptr %a, align 4104 store i32 3, ptr %b, align 4105 store i32 4, ptr %c, align 4106 %al = load i32, ptr %a107 %bl = load i32, ptr %b108 %cl = load i32, ptr %c109 %0 = add i32 %bl, %al110 %1 = add i32 %cl, %al111 %2 = add i32 %cl, %bl112 ret void113}114 115; These are identical functions, except that in the flipped functions,116; the operands in the subtractions are commuted. Since subtraction117; instructions are not commutative, we should outline the first two functions118; differently than the second two functions.119 120define void @outline_from_sub1() {121; CHECK-LABEL: @outline_from_sub1(122; CHECK-NEXT: entry:123; CHECK-NEXT: [[A:%.*]] = alloca i32, align 4124; CHECK-NEXT: [[B:%.*]] = alloca i32, align 4125; CHECK-NEXT: [[C:%.*]] = alloca i32, align 4126; CHECK-NEXT: call void @outlined_ir_func_2(ptr [[A]], ptr [[B]], ptr [[C]])127; CHECK-NEXT: ret void128;129entry:130 %a = alloca i32, align 4131 %b = alloca i32, align 4132 %c = alloca i32, align 4133 store i32 2, ptr %a, align 4134 store i32 3, ptr %b, align 4135 store i32 4, ptr %c, align 4136 %al = load i32, ptr %a137 %bl = load i32, ptr %b138 %cl = load i32, ptr %c139 %0 = sub i32 %al, %bl140 %1 = sub i32 %al, %cl141 %2 = sub i32 %bl, %cl142 ret void143}144 145define void @outline_from_sub2() {146; CHECK-LABEL: @outline_from_sub2(147; CHECK-NEXT: entry:148; CHECK-NEXT: [[A:%.*]] = alloca i32, align 4149; CHECK-NEXT: [[B:%.*]] = alloca i32, align 4150; CHECK-NEXT: [[C:%.*]] = alloca i32, align 4151; CHECK-NEXT: call void @outlined_ir_func_2(ptr [[A]], ptr [[B]], ptr [[C]])152; CHECK-NEXT: ret void153;154entry:155 %a = alloca i32, align 4156 %b = alloca i32, align 4157 %c = alloca i32, align 4158 store i32 2, ptr %a, align 4159 store i32 3, ptr %b, align 4160 store i32 4, ptr %c, align 4161 %al = load i32, ptr %a162 %bl = load i32, ptr %b163 %cl = load i32, ptr %c164 %0 = sub i32 %al, %bl165 %1 = sub i32 %al, %cl166 %2 = sub i32 %bl, %cl167 ret void168}169 170define void @dontoutline_from_flipped_sub3() {171; CHECK-LABEL: @dontoutline_from_flipped_sub3(172; CHECK-NEXT: entry:173; CHECK-NEXT: [[A:%.*]] = alloca i32, align 4174; CHECK-NEXT: [[B:%.*]] = alloca i32, align 4175; CHECK-NEXT: [[C:%.*]] = alloca i32, align 4176; CHECK-NEXT: call void @outlined_ir_func_1(ptr [[A]], ptr [[B]], ptr [[C]])177; CHECK-NEXT: ret void178;179entry:180 %a = alloca i32, align 4181 %b = alloca i32, align 4182 %c = alloca i32, align 4183 store i32 2, ptr %a, align 4184 store i32 3, ptr %b, align 4185 store i32 4, ptr %c, align 4186 %al = load i32, ptr %a187 %bl = load i32, ptr %b188 %cl = load i32, ptr %c189 %0 = sub i32 %bl, %al190 %1 = sub i32 %cl, %al191 %2 = sub i32 %cl, %bl192 ret void193}194 195define void @dontoutline_from_flipped_sub4() {196; CHECK-LABEL: @dontoutline_from_flipped_sub4(197; CHECK-NEXT: entry:198; CHECK-NEXT: [[A:%.*]] = alloca i32, align 4199; CHECK-NEXT: [[B:%.*]] = alloca i32, align 4200; CHECK-NEXT: [[C:%.*]] = alloca i32, align 4201; CHECK-NEXT: call void @outlined_ir_func_1(ptr [[A]], ptr [[B]], ptr [[C]])202; CHECK-NEXT: ret void203;204entry:205 %a = alloca i32, align 4206 %b = alloca i32, align 4207 %c = alloca i32, align 4208 store i32 2, ptr %a, align 4209 store i32 3, ptr %b, align 4210 store i32 4, ptr %c, align 4211 %al = load i32, ptr %a212 %bl = load i32, ptr %b213 %cl = load i32, ptr %c214 %0 = sub i32 %bl, %al215 %1 = sub i32 %cl, %al216 %2 = sub i32 %cl, %bl217 ret void218}219 220; CHECK: define internal void @outlined_ir_func_0(ptr [[ARG0:%.*]], ptr [[ARG1:%.*]], ptr [[ARG2:%.*]]) #0 {221; CHECK: entry_to_outline:222; CHECK-NEXT: store i32 2, ptr [[ARG0]], align 4223; CHECK-NEXT: store i32 3, ptr [[ARG1]], align 4224; CHECK-NEXT: store i32 4, ptr [[ARG2]], align 4225; CHECK-NEXT: [[AL:%.*]] = load i32, ptr [[ARG0]], align 4226; CHECK-NEXT: [[BL:%.*]] = load i32, ptr [[ARG1]], align 4227; CHECK-NEXT: [[CL:%.*]] = load i32, ptr [[ARG2]], align 4228; CHECK-NEXT: [[TMP0:%.*]] = add i32 [[AL]], [[BL]]229; CHECK-NEXT: [[TMP1:%.*]] = add i32 [[AL]], [[CL]]230; CHECK-NEXT: [[TMP2:%.*]] = add i32 [[BL]], [[CL]]231 232; CHECK: define internal void @outlined_ir_func_1(ptr [[ARG0:%.*]], ptr [[ARG1:%.*]], ptr [[ARG2:%.*]]) #0 {233; CHECK: entry_to_outline:234; CHECK-NEXT: store i32 2, ptr [[ARG0]], align 4235; CHECK-NEXT: store i32 3, ptr [[ARG1]], align 4236; CHECK-NEXT: store i32 4, ptr [[ARG2]], align 4237; CHECK-NEXT: [[AL:%.*]] = load i32, ptr [[ARG0]], align 4238; CHECK-NEXT: [[BL:%.*]] = load i32, ptr [[ARG1]], align 4239; CHECK-NEXT: [[CL:%.*]] = load i32, ptr [[ARG2]], align 4240; CHECK-NEXT: [[TMP0:%.*]] = sub i32 [[BL]], [[AL]]241; CHECK-NEXT: [[TMP1:%.*]] = sub i32 [[CL]], [[AL]]242; CHECK-NEXT: [[TMP2:%.*]] = sub i32 [[CL]], [[BL]]243 244; CHECK: define internal void @outlined_ir_func_2(ptr [[ARG0:%.*]], ptr [[ARG1:%.*]], ptr [[ARG2:%.*]]) #0 {245; CHECK: entry_to_outline:246; CHECK-NEXT: store i32 2, ptr [[ARG0]], align 4247; CHECK-NEXT: store i32 3, ptr [[ARG1]], align 4248; CHECK-NEXT: store i32 4, ptr [[ARG2]], align 4249; CHECK-NEXT: [[AL:%.*]] = load i32, ptr [[ARG0]], align 4250; CHECK-NEXT: [[BL:%.*]] = load i32, ptr [[ARG1]], align 4251; CHECK-NEXT: [[CL:%.*]] = load i32, ptr [[ARG2]], align 4252; CHECK-NEXT: [[TMP0:%.*]] = sub i32 [[AL]], [[BL]]253; CHECK-NEXT: [[TMP1:%.*]] = sub i32 [[AL]], [[CL]]254; CHECK-NEXT: [[TMP2:%.*]] = sub i32 [[BL]], [[CL]]255