brintos

brintos / llvm-project-archived public Read only

0
0
Text · 5.9 KiB · cd40aa9 Raw
168 lines · plain
1; NOTE: Assertions have been autogenerated by utils/update_test_checks.py UTC_ARGS: --version 52; RUN: opt < %s -passes=instcombine -S | FileCheck %s3 4declare void @use(i8 %value);5 6; Since we know that any comparison of ucmp/scmp with a constant will result in7; a comparison of ucmp/scmp's operands, we can propagate such a comparison8; through the phi node and let the next iteration of instcombine simplify it.9define i1 @icmp_of_phi_of_scmp_with_constant(i1 %c, i16 %x, i16 %y)10; CHECK-LABEL: define i1 @icmp_of_phi_of_scmp_with_constant(11; CHECK-SAME: i1 [[C:%.*]], i16 [[X:%.*]], i16 [[Y:%.*]]) {12; CHECK-NEXT:  [[ENTRY:.*:]]13; CHECK-NEXT:    br i1 [[C]], label %[[TRUE:.*]], label %[[FALSE:.*]]14; CHECK:       [[TRUE]]:15; CHECK-NEXT:    [[TMP0:%.*]] = icmp slt i16 [[X]], [[Y]]16; CHECK-NEXT:    br label %[[EXIT:.*]]17; CHECK:       [[FALSE]]:18; CHECK-NEXT:    [[TMP1:%.*]] = icmp slt i16 [[Y]], [[X]]19; CHECK-NEXT:    br label %[[EXIT]]20; CHECK:       [[EXIT]]:21; CHECK-NEXT:    [[R:%.*]] = phi i1 [ [[TMP0]], %[[TRUE]] ], [ [[TMP1]], %[[FALSE]] ]22; CHECK-NEXT:    ret i1 [[R]]23;24{25entry:26  br i1 %c, label %true, label %false27true:28  %cmp1 = call i8 @llvm.scmp(i16 %x, i16 %y)29  br label %exit30false:31  %cmp2 = call i8 @llvm.scmp(i16 %y, i16 %x)32  br label %exit33exit:34  %phi = phi i8 [%cmp1, %true], [%cmp2, %false]35  %r = icmp slt i8 %phi, 036  ret i1 %r37}38 39; When one of the incoming values is ucmp/scmp and the other is not we can still perform the transformation40define i1 @icmp_of_phi_of_one_scmp_with_constant(i1 %c, i16 %x, i16 %y, i8 %false_val)41; CHECK-LABEL: define i1 @icmp_of_phi_of_one_scmp_with_constant(42; CHECK-SAME: i1 [[C:%.*]], i16 [[X:%.*]], i16 [[Y:%.*]], i8 [[FALSE_VAL:%.*]]) {43; CHECK-NEXT:  [[ENTRY:.*:]]44; CHECK-NEXT:    br i1 [[C]], label %[[TRUE:.*]], label %[[FALSE:.*]]45; CHECK:       [[TRUE]]:46; CHECK-NEXT:    [[TMP0:%.*]] = icmp slt i16 [[X]], [[Y]]47; CHECK-NEXT:    br label %[[EXIT:.*]]48; CHECK:       [[FALSE]]:49; CHECK-NEXT:    [[TMP1:%.*]] = icmp slt i8 [[FALSE_VAL]], 050; CHECK-NEXT:    br label %[[EXIT]]51; CHECK:       [[EXIT]]:52; CHECK-NEXT:    [[PHI:%.*]] = phi i1 [ [[TMP0]], %[[TRUE]] ], [ [[TMP1]], %[[FALSE]] ]53; CHECK-NEXT:    ret i1 [[PHI]]54;55{56entry:57  br i1 %c, label %true, label %false58true:59  %cmp1 = call i8 @llvm.scmp(i16 %x, i16 %y)60  br label %exit61false:62  br label %exit63exit:64  %phi = phi i8 [%cmp1, %true], [%false_val, %false]65  %r = icmp slt i8 %phi, 066  ret i1 %r67}68 69; Negative test: the RHS of comparison that uses the phi node is not constant70define i1 @icmp_of_phi_of_scmp_with_non_constant(i1 %c, i16 %x, i16 %y, i8 %cmp)71; CHECK-LABEL: define i1 @icmp_of_phi_of_scmp_with_non_constant(72; CHECK-SAME: i1 [[C:%.*]], i16 [[X:%.*]], i16 [[Y:%.*]], i8 [[CMP:%.*]]) {73; CHECK-NEXT:  [[ENTRY:.*:]]74; CHECK-NEXT:    br i1 [[C]], label %[[TRUE:.*]], label %[[FALSE:.*]]75; CHECK:       [[TRUE]]:76; CHECK-NEXT:    [[CMP1:%.*]] = call i8 @llvm.scmp.i8.i16(i16 [[X]], i16 [[Y]])77; CHECK-NEXT:    br label %[[EXIT:.*]]78; CHECK:       [[FALSE]]:79; CHECK-NEXT:    [[CMP2:%.*]] = call i8 @llvm.scmp.i8.i16(i16 [[Y]], i16 [[X]])80; CHECK-NEXT:    br label %[[EXIT]]81; CHECK:       [[EXIT]]:82; CHECK-NEXT:    [[PHI:%.*]] = phi i8 [ [[CMP1]], %[[TRUE]] ], [ [[CMP2]], %[[FALSE]] ]83; CHECK-NEXT:    [[R:%.*]] = icmp slt i8 [[PHI]], [[CMP]]84; CHECK-NEXT:    ret i1 [[R]]85;86{87entry:88  br i1 %c, label %true, label %false89true:90  %cmp1 = call i8 @llvm.scmp(i16 %x, i16 %y)91  br label %exit92false:93  %cmp2 = call i8 @llvm.scmp(i16 %y, i16 %x)94  br label %exit95exit:96  %phi = phi i8 [%cmp1, %true], [%cmp2, %false]97  %r = icmp slt i8 %phi, %cmp98  ret i1 %r99}100 101; Negative test: more than one incoming value of the phi node is not one-use102define i1 @icmp_of_phi_of_scmp_with_constant_not_one_use(i1 %c, i16 %x, i16 %y)103; CHECK-LABEL: define i1 @icmp_of_phi_of_scmp_with_constant_not_one_use(104; CHECK-SAME: i1 [[C:%.*]], i16 [[X:%.*]], i16 [[Y:%.*]]) {105; CHECK-NEXT:  [[ENTRY:.*:]]106; CHECK-NEXT:    br i1 [[C]], label %[[TRUE:.*]], label %[[FALSE:.*]]107; CHECK:       [[TRUE]]:108; CHECK-NEXT:    [[CMP1:%.*]] = call i8 @llvm.scmp.i8.i16(i16 [[X]], i16 [[Y]])109; CHECK-NEXT:    call void @use(i8 [[CMP1]])110; CHECK-NEXT:    br label %[[EXIT:.*]]111; CHECK:       [[FALSE]]:112; CHECK-NEXT:    [[CMP2:%.*]] = call i8 @llvm.scmp.i8.i16(i16 [[Y]], i16 [[X]])113; CHECK-NEXT:    call void @use(i8 [[CMP2]])114; CHECK-NEXT:    br label %[[EXIT]]115; CHECK:       [[EXIT]]:116; CHECK-NEXT:    [[PHI:%.*]] = phi i8 [ [[CMP1]], %[[TRUE]] ], [ [[CMP2]], %[[FALSE]] ]117; CHECK-NEXT:    [[R:%.*]] = icmp slt i8 [[PHI]], 0118; CHECK-NEXT:    ret i1 [[R]]119;120{121entry:122  br i1 %c, label %true, label %false123true:124  %cmp1 = call i8 @llvm.scmp(i16 %x, i16 %y)125  call void @use(i8 %cmp1)126  br label %exit127false:128  %cmp2 = call i8 @llvm.scmp(i16 %y, i16 %x)129  call void @use(i8 %cmp2)130  br label %exit131exit:132  %phi = phi i8 [%cmp1, %true], [%cmp2, %false]133  %r = icmp slt i8 %phi, 0134  ret i1 %r135}136 137; Same as the first transformation, but the phi node uses the result of scmp twice. This verifies that we don't clone values more than once per block138define i1 @icmp_of_phi_of_scmp_with_constant_one_user_two_uses(i8 %c, i16 %x, i16 %y, i8 %false_val) {139; CHECK-LABEL: define i1 @icmp_of_phi_of_scmp_with_constant_one_user_two_uses(140; CHECK-SAME: i8 [[C:%.*]], i16 [[X:%.*]], i16 [[Y:%.*]], i8 [[FALSE_VAL:%.*]]) {141; CHECK-NEXT:  [[ENTRY:.*]]:142; CHECK-NEXT:    [[TMP0:%.*]] = icmp slt i16 [[X]], [[Y]]143; CHECK-NEXT:    switch i8 [[C]], label %[[BB_2:.*]] [144; CHECK-NEXT:      i8 0, label %[[BB:.*]]145; CHECK-NEXT:      i8 1, label %[[BB]]146; CHECK-NEXT:    ]147; CHECK:       [[BB_2]]:148; CHECK-NEXT:    br label %[[BB]]149; CHECK:       [[BB]]:150; CHECK-NEXT:    [[R:%.*]] = phi i1 [ [[TMP0]], %[[ENTRY]] ], [ [[TMP0]], %[[ENTRY]] ], [ false, %[[BB_2]] ]151; CHECK-NEXT:    ret i1 [[R]]152;153entry:154  %cmp = call i8 @llvm.scmp(i16 %x, i16 %y)155  switch i8 %c, label %bb_2 [156  i8 0, label %bb157  i8 1, label %bb158  ]159 160bb_2:161  br label %bb162 163bb:164  %phi = phi i8 [ %cmp, %entry ], [ %cmp, %entry ], [ 0, %bb_2 ]165  %r = icmp slt i8 %phi, 0166  ret i1 %r167}168