brintos

brintos / llvm-project-archived public Read only

0
0
Text · 38.2 KiB · b02da21 Raw
1044 lines · plain
1; NOTE: Assertions have been autogenerated by utils/update_llc_test_checks.py2; RUN: llc -mtriple=x86_64-pc-linux -x86-cmov-converter=true -verify-machineinstrs -disable-block-placement < %s | FileCheck -allow-deprecated-dag-overlap %s3; RUN: llc -mtriple=x86_64-pc-linux -x86-cmov-converter=true -x86-cmov-converter-force-all=true -verify-machineinstrs -disable-block-placement < %s | FileCheck -allow-deprecated-dag-overlap %s -check-prefix=CHECK-FORCEALL4 5;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;6;; This test checks that x86-cmov-converter optimization transform CMOV7;; instruction into branches when it is profitable.8;; There are 5 cases below:9;;   1. CmovInCriticalPath:10;;        CMOV depends on the condition and it is in the hot path.11;;        Thus, it worths transforming.12;;13;;   2. CmovNotInCriticalPath:14;;        Similar test like in (1), just that CMOV is not in the hot path.15;;        Thus, it does not worth transforming.16;;17;;   3. MaxIndex:18;;        Maximum calculation algorithm that is looking for the max index,19;;        calculating CMOV value is cheaper than calculating CMOV condition.20;;        Thus, it worths transforming.21;;22;;   4. MaxValue:23;;        Maximum calculation algorithm that is looking for the max value,24;;        calculating CMOV value is not cheaper than calculating CMOV condition.25;;        Thus, it does not worth transforming.26;;27;;   5. BinarySearch:28;;        Usually, binary search CMOV is not predicted.29;;        Thus, it does not worth transforming.30;;31;; Test was created using the following command line:32;; > clang -S -O2 -m64 -fno-vectorize -fno-unroll-loops -emit-llvm foo.c -o -33;; Where foo.c is:34;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;35;;void CmovInHotPath(int n, int a, int b, int *c, int *d) {36;;  for (int i = 0; i < n; i++) {37;;    int t = c[i] + 1;38;;    if (cptr a > b)39;;      t = 10;40;;    c[i] = (c[i] + 1) * t;41;;  }42;;}43;;44;;45;;void CmovNotInHotPath(int n, int a, int b, int *c, int *d) {46;;  for (int i = 0; i < n; i++) {47;;    int t = c[i];48;;    if (cptr a > b)49;;      t = 10;50;;    c[i] = t;51;;    d[i] /= b;52;;  }53;;}54;;55;;56;;int MaxIndex(int n, int *a) {57;;  int t = 0;58;;  for (int i = 1; i < n; i++) {59;;    if (a[i] > a[t])60;;      t = i;61;;  }62;;  return t;63;;}64;;65;;66;;int MaxValue(int n, int *a) {67;;  int t = a[0];68;;  for (int i = 1; i < n; i++) {69;;    if (a[i] > t)70;;      t = a[i];71;;  }72;;  return t;73;;}74;;75;;typedef struct Node Node;76;;struct Node {77;;  unsigned Val;78;;  Node *Right;79;;  Node *Left;80;;};81;;82;;unsigned BinarySearch(unsigned Mask, Node *Curr, Node *Next) {83;;  while (Curr->Val > Next->Val) {84;;    Curr = Next;85;;    if (Mask & (0x1 << Curr->Val))86;;      Next = Curr->Right;87;;    else88;;      Next = Curr->Left;89;;  }90;;  return Curr->Val;91;;}92;;93;;94;;void SmallGainPerLoop(int n, int a, int b, int *c, int *d) {95;;  for (int i = 0; i < n; i++) {96;;    int t = c[i];97;;    if (cptr a > b)98;;      t = 10;99;;    c[i] = t;100;;  }101;;}102;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;103 104%struct.Node = type { i32, ptr, ptr }105 106define void @CmovInHotPath(i32 %n, i32 %a, i32 %b, ptr nocapture %c, ptr nocapture readnone %d) #0 {107; CHECK-LABEL: CmovInHotPath:108; CHECK:       # %bb.0: # %entry109; CHECK-NEXT:    testl %edi, %edi110; CHECK-NEXT:    jle .LBB0_5111; CHECK-NEXT:  # %bb.1: # %for.body.preheader112; CHECK-NEXT:    movl %edi, %eax113; CHECK-NEXT:    xorl %edi, %edi114; CHECK-NEXT:  .LBB0_2: # %for.body115; CHECK-NEXT:    # =>This Inner Loop Header: Depth=1116; CHECK-NEXT:    movl (%rcx,%rdi,4), %r10d117; CHECK-NEXT:    leal 1(%r10), %r8d118; CHECK-NEXT:    imull %esi, %r10d119; CHECK-NEXT:    movl $10, %r9d120; CHECK-NEXT:    cmpl %edx, %r10d121; CHECK-NEXT:    jg .LBB0_4122; CHECK-NEXT:  # %bb.3: # %for.body123; CHECK-NEXT:    # in Loop: Header=BB0_2 Depth=1124; CHECK-NEXT:    movl %r8d, %r9d125; CHECK-NEXT:  .LBB0_4: # %for.body126; CHECK-NEXT:    # in Loop: Header=BB0_2 Depth=1127; CHECK-NEXT:    imull %r8d, %r9d128; CHECK-NEXT:    movl %r9d, (%rcx,%rdi,4)129; CHECK-NEXT:    addq $1, %rdi130; CHECK-NEXT:    cmpq %rdi, %rax131; CHECK-NEXT:    jne .LBB0_2132; CHECK-NEXT:  .LBB0_5: # %for.cond.cleanup133; CHECK-NEXT:    retq134;135; CHECK-FORCEALL-LABEL: CmovInHotPath:136; CHECK-FORCEALL:       # %bb.0: # %entry137; CHECK-FORCEALL-NEXT:    testl %edi, %edi138; CHECK-FORCEALL-NEXT:    jle .LBB0_5139; CHECK-FORCEALL-NEXT:  # %bb.1: # %for.body.preheader140; CHECK-FORCEALL-NEXT:    movl %edi, %eax141; CHECK-FORCEALL-NEXT:    xorl %edi, %edi142; CHECK-FORCEALL-NEXT:  .LBB0_2: # %for.body143; CHECK-FORCEALL-NEXT:    # =>This Inner Loop Header: Depth=1144; CHECK-FORCEALL-NEXT:    movl (%rcx,%rdi,4), %r10d145; CHECK-FORCEALL-NEXT:    leal 1(%r10), %r8d146; CHECK-FORCEALL-NEXT:    imull %esi, %r10d147; CHECK-FORCEALL-NEXT:    movl $10, %r9d148; CHECK-FORCEALL-NEXT:    cmpl %edx, %r10d149; CHECK-FORCEALL-NEXT:    jg .LBB0_4150; CHECK-FORCEALL-NEXT:  # %bb.3: # %for.body151; CHECK-FORCEALL-NEXT:    # in Loop: Header=BB0_2 Depth=1152; CHECK-FORCEALL-NEXT:    movl %r8d, %r9d153; CHECK-FORCEALL-NEXT:  .LBB0_4: # %for.body154; CHECK-FORCEALL-NEXT:    # in Loop: Header=BB0_2 Depth=1155; CHECK-FORCEALL-NEXT:    imull %r8d, %r9d156; CHECK-FORCEALL-NEXT:    movl %r9d, (%rcx,%rdi,4)157; CHECK-FORCEALL-NEXT:    addq $1, %rdi158; CHECK-FORCEALL-NEXT:    cmpq %rdi, %rax159; CHECK-FORCEALL-NEXT:    jne .LBB0_2160; CHECK-FORCEALL-NEXT:  .LBB0_5: # %for.cond.cleanup161; CHECK-FORCEALL-NEXT:    retq162entry:163  %cmp14 = icmp sgt i32 %n, 0164  br i1 %cmp14, label %for.body.preheader, label %for.cond.cleanup165 166for.body.preheader:                               ; preds = %entry167  %wide.trip.count = zext i32 %n to i64168  br label %for.body169 170for.cond.cleanup:                                 ; preds = %for.body, %entry171  ret void172 173for.body:                                         ; preds = %for.body.preheader, %for.body174  %indvars.iv = phi i64 [ %indvars.iv.next, %for.body ], [ 0, %for.body.preheader ]175  %arrayidx = getelementptr inbounds i32, ptr %c, i64 %indvars.iv176  %0 = load i32, ptr %arrayidx, align 4177  %add = add nsw i32 %0, 1178  %mul = mul nsw i32 %0, %a179  %cmp3 = icmp sgt i32 %mul, %b180  %. = select i1 %cmp3, i32 10, i32 %add181  %mul7 = mul nsw i32 %., %add182  store i32 %mul7, ptr %arrayidx, align 4183  %indvars.iv.next = add nuw nsw i64 %indvars.iv, 1184  %exitcond = icmp eq i64 %indvars.iv.next, %wide.trip.count185  br i1 %exitcond, label %for.cond.cleanup, label %for.body186}187 188define void @CmovNotInHotPath(i32 %n, i32 %a, i32 %b, ptr nocapture %c, ptr nocapture %d) #0 {189; CHECK-LABEL: CmovNotInHotPath:190; CHECK:       # %bb.0: # %entry191; CHECK-NEXT:    testl %edi, %edi192; CHECK-NEXT:    jle .LBB1_3193; CHECK-NEXT:  # %bb.1: # %for.body.preheader194; CHECK-NEXT:    movl %edx, %r9d195; CHECK-NEXT:    movl %edi, %edi196; CHECK-NEXT:    xorl %r10d, %r10d197; CHECK-NEXT:    movl $10, %r11d198; CHECK-NEXT:  .LBB1_2: # %for.body199; CHECK-NEXT:    # =>This Inner Loop Header: Depth=1200; CHECK-NEXT:    movl (%rcx,%r10,4), %eax201; CHECK-NEXT:    movl %eax, %edx202; CHECK-NEXT:    imull %esi, %edx203; CHECK-NEXT:    cmpl %r9d, %edx204; CHECK-NEXT:    cmovgl %r11d, %eax205; CHECK-NEXT:    movl %eax, (%rcx,%r10,4)206; CHECK-NEXT:    movl (%r8,%r10,4), %eax207; CHECK-NEXT:    cltd208; CHECK-NEXT:    idivl %r9d209; CHECK-NEXT:    movl %eax, (%r8,%r10,4)210; CHECK-NEXT:    addq $1, %r10211; CHECK-NEXT:    cmpq %r10, %rdi212; CHECK-NEXT:    jne .LBB1_2213; CHECK-NEXT:  .LBB1_3: # %for.cond.cleanup214; CHECK-NEXT:    retq215;216; CHECK-FORCEALL-LABEL: CmovNotInHotPath:217; CHECK-FORCEALL:       # %bb.0: # %entry218; CHECK-FORCEALL-NEXT:    testl %edi, %edi219; CHECK-FORCEALL-NEXT:    jle .LBB1_5220; CHECK-FORCEALL-NEXT:  # %bb.1: # %for.body.preheader221; CHECK-FORCEALL-NEXT:    movl %edx, %r9d222; CHECK-FORCEALL-NEXT:    movl %edi, %edi223; CHECK-FORCEALL-NEXT:    xorl %r10d, %r10d224; CHECK-FORCEALL-NEXT:  .LBB1_2: # %for.body225; CHECK-FORCEALL-NEXT:    # =>This Inner Loop Header: Depth=1226; CHECK-FORCEALL-NEXT:    movl (%rcx,%r10,4), %eax227; CHECK-FORCEALL-NEXT:    movl %eax, %r11d228; CHECK-FORCEALL-NEXT:    imull %esi, %r11d229; CHECK-FORCEALL-NEXT:    movl $10, %edx230; CHECK-FORCEALL-NEXT:    cmpl %r9d, %r11d231; CHECK-FORCEALL-NEXT:    jg .LBB1_4232; CHECK-FORCEALL-NEXT:  # %bb.3: # %for.body233; CHECK-FORCEALL-NEXT:    # in Loop: Header=BB1_2 Depth=1234; CHECK-FORCEALL-NEXT:    movl %eax, %edx235; CHECK-FORCEALL-NEXT:  .LBB1_4: # %for.body236; CHECK-FORCEALL-NEXT:    # in Loop: Header=BB1_2 Depth=1237; CHECK-FORCEALL-NEXT:    movl %edx, (%rcx,%r10,4)238; CHECK-FORCEALL-NEXT:    movl (%r8,%r10,4), %eax239; CHECK-FORCEALL-NEXT:    cltd240; CHECK-FORCEALL-NEXT:    idivl %r9d241; CHECK-FORCEALL-NEXT:    movl %eax, (%r8,%r10,4)242; CHECK-FORCEALL-NEXT:    addq $1, %r10243; CHECK-FORCEALL-NEXT:    cmpq %r10, %rdi244; CHECK-FORCEALL-NEXT:    jne .LBB1_2245; CHECK-FORCEALL-NEXT:  .LBB1_5: # %for.cond.cleanup246; CHECK-FORCEALL-NEXT:    retq247entry:248  %cmp18 = icmp sgt i32 %n, 0249  br i1 %cmp18, label %for.body.preheader, label %for.cond.cleanup250 251for.body.preheader:                               ; preds = %entry252  %wide.trip.count = zext i32 %n to i64253  br label %for.body254 255for.cond.cleanup:                                 ; preds = %for.body, %entry256  ret void257 258for.body:                                         ; preds = %for.body.preheader, %for.body259  %indvars.iv = phi i64 [ %indvars.iv.next, %for.body ], [ 0, %for.body.preheader ]260  %arrayidx = getelementptr inbounds i32, ptr %c, i64 %indvars.iv261  %0 = load i32, ptr %arrayidx, align 4262  %mul = mul nsw i32 %0, %a263  %cmp3 = icmp sgt i32 %mul, %b264  %. = select i1 %cmp3, i32 10, i32 %0265  store i32 %., ptr %arrayidx, align 4266  %arrayidx7 = getelementptr inbounds i32, ptr %d, i64 %indvars.iv267  %1 = load i32, ptr %arrayidx7, align 4268  %div = sdiv i32 %1, %b269  store i32 %div, ptr %arrayidx7, align 4270  %indvars.iv.next = add nuw nsw i64 %indvars.iv, 1271  %exitcond = icmp eq i64 %indvars.iv.next, %wide.trip.count272  br i1 %exitcond, label %for.cond.cleanup, label %for.body273}274 275define i32 @MaxIndex(i32 %n, ptr nocapture readonly %a) #0 {276; CHECK-LABEL: MaxIndex:277; CHECK:       # %bb.0: # %entry278; CHECK-NEXT:    xorl %eax, %eax279; CHECK-NEXT:    cmpl $2, %edi280; CHECK-NEXT:    jl .LBB2_5281; CHECK-NEXT:  # %bb.1: # %for.body.preheader282; CHECK-NEXT:    movl %edi, %ecx283; CHECK-NEXT:    xorl %edi, %edi284; CHECK-NEXT:    movl $1, %edx285; CHECK-NEXT:  .LBB2_2: # %for.body286; CHECK-NEXT:    # =>This Inner Loop Header: Depth=1287; CHECK-NEXT:    movl (%rsi,%rdx,4), %r8d288; CHECK-NEXT:    movslq %edi, %r9289; CHECK-NEXT:    movl %edx, %eax290; CHECK-NEXT:    cmpl (%rsi,%r9,4), %r8d291; CHECK-NEXT:    jg .LBB2_4292; CHECK-NEXT:  # %bb.3: # %for.body293; CHECK-NEXT:    # in Loop: Header=BB2_2 Depth=1294; CHECK-NEXT:    movl %edi, %eax295; CHECK-NEXT:  .LBB2_4: # %for.body296; CHECK-NEXT:    # in Loop: Header=BB2_2 Depth=1297; CHECK-NEXT:    addq $1, %rdx298; CHECK-NEXT:    movl %eax, %edi299; CHECK-NEXT:    cmpq %rdx, %rcx300; CHECK-NEXT:    jne .LBB2_2301; CHECK-NEXT:  .LBB2_5: # %for.cond.cleanup302; CHECK-NEXT:    retq303;304; CHECK-FORCEALL-LABEL: MaxIndex:305; CHECK-FORCEALL:       # %bb.0: # %entry306; CHECK-FORCEALL-NEXT:    xorl %eax, %eax307; CHECK-FORCEALL-NEXT:    cmpl $2, %edi308; CHECK-FORCEALL-NEXT:    jl .LBB2_5309; CHECK-FORCEALL-NEXT:  # %bb.1: # %for.body.preheader310; CHECK-FORCEALL-NEXT:    movl %edi, %ecx311; CHECK-FORCEALL-NEXT:    xorl %edi, %edi312; CHECK-FORCEALL-NEXT:    movl $1, %edx313; CHECK-FORCEALL-NEXT:  .LBB2_2: # %for.body314; CHECK-FORCEALL-NEXT:    # =>This Inner Loop Header: Depth=1315; CHECK-FORCEALL-NEXT:    movl (%rsi,%rdx,4), %r8d316; CHECK-FORCEALL-NEXT:    movslq %edi, %r9317; CHECK-FORCEALL-NEXT:    movl %edx, %eax318; CHECK-FORCEALL-NEXT:    cmpl (%rsi,%r9,4), %r8d319; CHECK-FORCEALL-NEXT:    jg .LBB2_4320; CHECK-FORCEALL-NEXT:  # %bb.3: # %for.body321; CHECK-FORCEALL-NEXT:    # in Loop: Header=BB2_2 Depth=1322; CHECK-FORCEALL-NEXT:    movl %edi, %eax323; CHECK-FORCEALL-NEXT:  .LBB2_4: # %for.body324; CHECK-FORCEALL-NEXT:    # in Loop: Header=BB2_2 Depth=1325; CHECK-FORCEALL-NEXT:    addq $1, %rdx326; CHECK-FORCEALL-NEXT:    movl %eax, %edi327; CHECK-FORCEALL-NEXT:    cmpq %rdx, %rcx328; CHECK-FORCEALL-NEXT:    jne .LBB2_2329; CHECK-FORCEALL-NEXT:  .LBB2_5: # %for.cond.cleanup330; CHECK-FORCEALL-NEXT:    retq331entry:332  %cmp14 = icmp sgt i32 %n, 1333  br i1 %cmp14, label %for.body.preheader, label %for.cond.cleanup334 335for.body.preheader:                               ; preds = %entry336  %wide.trip.count = zext i32 %n to i64337  br label %for.body338 339for.cond.cleanup:                                 ; preds = %for.body, %entry340  %t.0.lcssa = phi i32 [ 0, %entry ], [ %i.0.t.0, %for.body ]341  ret i32 %t.0.lcssa342 343for.body:                                         ; preds = %for.body.preheader, %for.body344  %indvars.iv = phi i64 [ %indvars.iv.next, %for.body ], [ 1, %for.body.preheader ]345  %t.015 = phi i32 [ %i.0.t.0, %for.body ], [ 0, %for.body.preheader ]346  %arrayidx = getelementptr inbounds i32, ptr %a, i64 %indvars.iv347  %0 = load i32, ptr %arrayidx, align 4348  %idxprom1 = sext i32 %t.015 to i64349  %arrayidx2 = getelementptr inbounds i32, ptr %a, i64 %idxprom1350  %1 = load i32, ptr %arrayidx2, align 4351  %cmp3 = icmp sgt i32 %0, %1352  %2 = trunc i64 %indvars.iv to i32353  %i.0.t.0 = select i1 %cmp3, i32 %2, i32 %t.015354  %indvars.iv.next = add nuw nsw i64 %indvars.iv, 1355  %exitcond = icmp eq i64 %indvars.iv.next, %wide.trip.count356  br i1 %exitcond, label %for.cond.cleanup, label %for.body357}358 359; If cmov instruction is marked as unpredictable, do not convert it to branch.360define i32 @MaxIndex_unpredictable(i32 %n, ptr nocapture readonly %a) #0 {361; CHECK-LABEL: MaxIndex_unpredictable:362; CHECK:       # %bb.0: # %entry363; CHECK-NEXT:    xorl %eax, %eax364; CHECK-NEXT:    cmpl $2, %edi365; CHECK-NEXT:    jl .LBB3_3366; CHECK-NEXT:  # %bb.1: # %for.body.preheader367; CHECK-NEXT:    movl %edi, %ecx368; CHECK-NEXT:    xorl %eax, %eax369; CHECK-NEXT:    movl $1, %edx370; CHECK-NEXT:  .LBB3_2: # %for.body371; CHECK-NEXT:    # =>This Inner Loop Header: Depth=1372; CHECK-NEXT:    movl (%rsi,%rdx,4), %edi373; CHECK-NEXT:    cltq374; CHECK-NEXT:    cmpl (%rsi,%rax,4), %edi375; CHECK-NEXT:    cmovgl %edx, %eax376; CHECK-NEXT:    addq $1, %rdx377; CHECK-NEXT:    cmpq %rdx, %rcx378; CHECK-NEXT:    jne .LBB3_2379; CHECK-NEXT:  .LBB3_3: # %for.cond.cleanup380; CHECK-NEXT:    # kill: def $eax killed $eax killed $rax381; CHECK-NEXT:    retq382;383; CHECK-FORCEALL-LABEL: MaxIndex_unpredictable:384; CHECK-FORCEALL:       # %bb.0: # %entry385; CHECK-FORCEALL-NEXT:    xorl %eax, %eax386; CHECK-FORCEALL-NEXT:    cmpl $2, %edi387; CHECK-FORCEALL-NEXT:    jl .LBB3_3388; CHECK-FORCEALL-NEXT:  # %bb.1: # %for.body.preheader389; CHECK-FORCEALL-NEXT:    movl %edi, %ecx390; CHECK-FORCEALL-NEXT:    xorl %eax, %eax391; CHECK-FORCEALL-NEXT:    movl $1, %edx392; CHECK-FORCEALL-NEXT:  .LBB3_2: # %for.body393; CHECK-FORCEALL-NEXT:    # =>This Inner Loop Header: Depth=1394; CHECK-FORCEALL-NEXT:    movl (%rsi,%rdx,4), %edi395; CHECK-FORCEALL-NEXT:    cltq396; CHECK-FORCEALL-NEXT:    cmpl (%rsi,%rax,4), %edi397; CHECK-FORCEALL-NEXT:    cmovgl %edx, %eax398; CHECK-FORCEALL-NEXT:    addq $1, %rdx399; CHECK-FORCEALL-NEXT:    cmpq %rdx, %rcx400; CHECK-FORCEALL-NEXT:    jne .LBB3_2401; CHECK-FORCEALL-NEXT:  .LBB3_3: # %for.cond.cleanup402; CHECK-FORCEALL-NEXT:    # kill: def $eax killed $eax killed $rax403; CHECK-FORCEALL-NEXT:    retq404entry:405  %cmp14 = icmp sgt i32 %n, 1406  br i1 %cmp14, label %for.body.preheader, label %for.cond.cleanup407 408for.body.preheader:                               ; preds = %entry409  %wide.trip.count = zext i32 %n to i64410  br label %for.body411 412for.cond.cleanup:                                 ; preds = %for.body, %entry413  %t.0.lcssa = phi i32 [ 0, %entry ], [ %i.0.t.0, %for.body ]414  ret i32 %t.0.lcssa415 416for.body:                                         ; preds = %for.body.preheader, %for.body417  %indvars.iv = phi i64 [ %indvars.iv.next, %for.body ], [ 1, %for.body.preheader ]418  %t.015 = phi i32 [ %i.0.t.0, %for.body ], [ 0, %for.body.preheader ]419  %arrayidx = getelementptr inbounds i32, ptr %a, i64 %indvars.iv420  %0 = load i32, ptr %arrayidx, align 4421  %idxprom1 = sext i32 %t.015 to i64422  %arrayidx2 = getelementptr inbounds i32, ptr %a, i64 %idxprom1423  %1 = load i32, ptr %arrayidx2, align 4424  %cmp3 = icmp sgt i32 %0, %1425  %2 = trunc i64 %indvars.iv to i32426  %i.0.t.0 = select i1 %cmp3, i32 %2, i32 %t.015, !unpredictable !0427  %indvars.iv.next = add nuw nsw i64 %indvars.iv, 1428  %exitcond = icmp eq i64 %indvars.iv.next, %wide.trip.count429  br i1 %exitcond, label %for.cond.cleanup, label %for.body430}431 432define i32 @MaxValue(i32 %n, ptr nocapture readonly %a) #0 {433; CHECK-LABEL: MaxValue:434; CHECK:       # %bb.0: # %entry435; CHECK-NEXT:    movl (%rsi), %eax436; CHECK-NEXT:    cmpl $2, %edi437; CHECK-NEXT:    jl .LBB4_3438; CHECK-NEXT:  # %bb.1: # %for.body.preheader439; CHECK-NEXT:    movl %edi, %ecx440; CHECK-NEXT:    movl $1, %edx441; CHECK-NEXT:  .LBB4_2: # %for.body442; CHECK-NEXT:    # =>This Inner Loop Header: Depth=1443; CHECK-NEXT:    movl (%rsi,%rdx,4), %edi444; CHECK-NEXT:    cmpl %eax, %edi445; CHECK-NEXT:    cmovgl %edi, %eax446; CHECK-NEXT:    addq $1, %rdx447; CHECK-NEXT:    cmpq %rdx, %rcx448; CHECK-NEXT:    jne .LBB4_2449; CHECK-NEXT:  .LBB4_3: # %for.cond.cleanup450; CHECK-NEXT:    retq451;452; CHECK-FORCEALL-LABEL: MaxValue:453; CHECK-FORCEALL:       # %bb.0: # %entry454; CHECK-FORCEALL-NEXT:    movl (%rsi), %r8d455; CHECK-FORCEALL-NEXT:    cmpl $2, %edi456; CHECK-FORCEALL-NEXT:    jge .LBB4_3457; CHECK-FORCEALL-NEXT:  # %bb.1:458; CHECK-FORCEALL-NEXT:    movl %r8d, %eax459; CHECK-FORCEALL-NEXT:  .LBB4_2: # %for.cond.cleanup460; CHECK-FORCEALL-NEXT:    retq461; CHECK-FORCEALL-NEXT:  .LBB4_3: # %for.body.preheader462; CHECK-FORCEALL-NEXT:    movl %edi, %ecx463; CHECK-FORCEALL-NEXT:    movl $1, %edx464; CHECK-FORCEALL-NEXT:  .LBB4_4: # %for.body465; CHECK-FORCEALL-NEXT:    # =>This Inner Loop Header: Depth=1466; CHECK-FORCEALL-NEXT:    movl (%rsi,%rdx,4), %eax467; CHECK-FORCEALL-NEXT:    cmpl %r8d, %eax468; CHECK-FORCEALL-NEXT:    jg .LBB4_6469; CHECK-FORCEALL-NEXT:  # %bb.5: # %for.body470; CHECK-FORCEALL-NEXT:    # in Loop: Header=BB4_4 Depth=1471; CHECK-FORCEALL-NEXT:    movl %r8d, %eax472; CHECK-FORCEALL-NEXT:  .LBB4_6: # %for.body473; CHECK-FORCEALL-NEXT:    # in Loop: Header=BB4_4 Depth=1474; CHECK-FORCEALL-NEXT:    addq $1, %rdx475; CHECK-FORCEALL-NEXT:    movl %eax, %r8d476; CHECK-FORCEALL-NEXT:    cmpq %rdx, %rcx477; CHECK-FORCEALL-NEXT:    je .LBB4_2478; CHECK-FORCEALL-NEXT:    jmp .LBB4_4479entry:480  %0 = load i32, ptr %a, align 4481  %cmp13 = icmp sgt i32 %n, 1482  br i1 %cmp13, label %for.body.preheader, label %for.cond.cleanup483 484for.body.preheader:                               ; preds = %entry485  %wide.trip.count = zext i32 %n to i64486  br label %for.body487 488for.cond.cleanup:                                 ; preds = %for.body, %entry489  %t.0.lcssa = phi i32 [ %0, %entry ], [ %.t.0, %for.body ]490  ret i32 %t.0.lcssa491 492for.body:                                         ; preds = %for.body.preheader, %for.body493  %indvars.iv = phi i64 [ %indvars.iv.next, %for.body ], [ 1, %for.body.preheader ]494  %t.014 = phi i32 [ %.t.0, %for.body ], [ %0, %for.body.preheader ]495  %arrayidx1 = getelementptr inbounds i32, ptr %a, i64 %indvars.iv496  %1 = load i32, ptr %arrayidx1, align 4497  %cmp2 = icmp sgt i32 %1, %t.014498  %.t.0 = select i1 %cmp2, i32 %1, i32 %t.014499  %indvars.iv.next = add nuw nsw i64 %indvars.iv, 1500  %exitcond = icmp eq i64 %indvars.iv.next, %wide.trip.count501  br i1 %exitcond, label %for.cond.cleanup, label %for.body502}503 504define i32 @BinarySearch(i32 %Mask, ptr nocapture readonly %Curr, ptr nocapture readonly %Next) #0 {505; CHECK-LABEL: BinarySearch:506; CHECK:       # %bb.0: # %entry507; CHECK-NEXT:    movl (%rsi), %eax508; CHECK-NEXT:    jmp .LBB5_2509; CHECK-NEXT:  .LBB5_1: # %while.body510; CHECK-NEXT:    # in Loop: Header=BB5_2 Depth=1511; CHECK-NEXT:    movl %ecx, %eax512; CHECK-NEXT:    xorl %ecx, %ecx513; CHECK-NEXT:    btl %eax, %edi514; CHECK-NEXT:    setae %cl515; CHECK-NEXT:    movq 8(%rdx,%rcx,8), %rdx516; CHECK-NEXT:  .LBB5_2: # %while.body517; CHECK-NEXT:    # =>This Inner Loop Header: Depth=1518; CHECK-NEXT:    movl (%rdx), %ecx519; CHECK-NEXT:    cmpl %ecx, %eax520; CHECK-NEXT:    ja .LBB5_1521; CHECK-NEXT:  # %bb.3: # %while.end522; CHECK-NEXT:    retq523;524; CHECK-FORCEALL-LABEL: BinarySearch:525; CHECK-FORCEALL:       # %bb.0: # %entry526; CHECK-FORCEALL-NEXT:    movl (%rsi), %eax527; CHECK-FORCEALL-NEXT:    jmp .LBB5_2528; CHECK-FORCEALL-NEXT:  .LBB5_1: # %while.body529; CHECK-FORCEALL-NEXT:    # in Loop: Header=BB5_2 Depth=1530; CHECK-FORCEALL-NEXT:    movl %ecx, %eax531; CHECK-FORCEALL-NEXT:    xorl %ecx, %ecx532; CHECK-FORCEALL-NEXT:    btl %eax, %edi533; CHECK-FORCEALL-NEXT:    setae %cl534; CHECK-FORCEALL-NEXT:    movq 8(%rdx,%rcx,8), %rdx535; CHECK-FORCEALL-NEXT:  .LBB5_2: # %while.body536; CHECK-FORCEALL-NEXT:    # =>This Inner Loop Header: Depth=1537; CHECK-FORCEALL-NEXT:    movl (%rdx), %ecx538; CHECK-FORCEALL-NEXT:    cmpl %ecx, %eax539; CHECK-FORCEALL-NEXT:    ja .LBB5_1540; CHECK-FORCEALL-NEXT:  # %bb.3: # %while.end541; CHECK-FORCEALL-NEXT:    retq542entry:543  %0 = load i32, ptr %Curr, align 8544  %1 = load i32, ptr %Next, align 8545  %cmp10 = icmp ugt i32 %0, %1546  br i1 %cmp10, label %while.body, label %while.end547 548while.body:                                       ; preds = %entry, %while.body549  %2 = phi i32 [ %4, %while.body ], [ %1, %entry ]550  %Next.addr.011 = phi ptr [ %3, %while.body ], [ %Next, %entry ]551  %shl = shl i32 1, %2552  %and = and i32 %shl, %Mask553  %tobool = icmp eq i32 %and, 0554  %Left = getelementptr inbounds %struct.Node, ptr %Next.addr.011, i64 0, i32 2555  %Right = getelementptr inbounds %struct.Node, ptr %Next.addr.011, i64 0, i32 1556  %Left.sink = select i1 %tobool, ptr %Left, ptr %Right557  %3 = load ptr, ptr %Left.sink, align 8558  %4 = load i32, ptr %3, align 8559  %cmp = icmp ugt i32 %2, %4560  br i1 %cmp, label %while.body, label %while.end561 562while.end:                                        ; preds = %while.body, %entry563  %.lcssa = phi i32 [ %0, %entry ], [ %2, %while.body ]564  ret i32 %.lcssa565}566 567;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;568;; The following test checks that x86-cmov-converter optimization transforms569;; CMOV instructions into branch correctly.570;;571;; MBB:572;;   cond = cmp ...573;;   v1 = CMOVgt t1, f1, cond574;;   v2 = CMOVle s1, f2, cond575;;576;; Where: t1 = 11, f1 = 22, f2 = a577;;578;; After CMOV transformation579;; -------------------------580;; MBB:581;;   cond = cmp ...582;;   ja %SinkMBB583;;584;; FalseMBB:585;;   jmp %SinkMBB586;;587;; SinkMBB:588;;   %v1 = phi[%f1, %FalseMBB], [%t1, %MBB]589;;   %v2 = phi[%f1, %FalseMBB], [%f2, %MBB] ; For CMOV with OppCC switch590;;                                          ; true-value with false-value591;;                                          ; Phi instruction cannot use592;;                                          ; previous Phi instruction result593;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;594 595define void @Transform(ptr%arr, ptr%arr2, i32 %a, i32 %b, i32 %c, i32 %n) #0 {596; CHECK-LABEL: Transform:597; CHECK:       # %bb.0: # %entry598; CHECK-NEXT:    movb $1, %al599; CHECK-NEXT:    testb %al, %al600; CHECK-NEXT:    jne .LBB6_5601; CHECK-NEXT:  # %bb.1: # %while.body.preheader602; CHECK-NEXT:    movl %edx, %ecx603; CHECK-NEXT:    xorl %esi, %esi604; CHECK-NEXT:  .LBB6_2: # %while.body605; CHECK-NEXT:    # =>This Inner Loop Header: Depth=1606; CHECK-NEXT:    movslq %esi, %rsi607; CHECK-NEXT:    movl (%rdi,%rsi,4), %eax608; CHECK-NEXT:    xorl %edx, %edx609; CHECK-NEXT:    divl %ecx610; CHECK-NEXT:    movl %eax, %edx611; CHECK-NEXT:    movl $11, %eax612; CHECK-NEXT:    movl %ecx, %r8d613; CHECK-NEXT:    cmpl %ecx, %edx614; CHECK-NEXT:    ja .LBB6_4615; CHECK-NEXT:  # %bb.3: # %while.body616; CHECK-NEXT:    # in Loop: Header=BB6_2 Depth=1617; CHECK-NEXT:    movl $22, %eax618; CHECK-NEXT:    movl $22, %r8d619; CHECK-NEXT:  .LBB6_4: # %while.body620; CHECK-NEXT:    # in Loop: Header=BB6_2 Depth=1621; CHECK-NEXT:    xorl %edx, %edx622; CHECK-NEXT:    divl %r8d623; CHECK-NEXT:    movl %edx, (%rdi,%rsi,4)624; CHECK-NEXT:    addl $1, %esi625; CHECK-NEXT:    cmpl %r9d, %esi626; CHECK-NEXT:    ja .LBB6_2627; CHECK-NEXT:  .LBB6_5: # %while.end628; CHECK-NEXT:    retq629;630; CHECK-FORCEALL-LABEL: Transform:631; CHECK-FORCEALL:       # %bb.0: # %entry632; CHECK-FORCEALL-NEXT:    movb $1, %al633; CHECK-FORCEALL-NEXT:    testb %al, %al634; CHECK-FORCEALL-NEXT:    jne .LBB6_5635; CHECK-FORCEALL-NEXT:  # %bb.1: # %while.body.preheader636; CHECK-FORCEALL-NEXT:    movl %edx, %ecx637; CHECK-FORCEALL-NEXT:    xorl %esi, %esi638; CHECK-FORCEALL-NEXT:  .LBB6_2: # %while.body639; CHECK-FORCEALL-NEXT:    # =>This Inner Loop Header: Depth=1640; CHECK-FORCEALL-NEXT:    movslq %esi, %rsi641; CHECK-FORCEALL-NEXT:    movl (%rdi,%rsi,4), %eax642; CHECK-FORCEALL-NEXT:    xorl %edx, %edx643; CHECK-FORCEALL-NEXT:    divl %ecx644; CHECK-FORCEALL-NEXT:    movl %eax, %edx645; CHECK-FORCEALL-NEXT:    movl $11, %eax646; CHECK-FORCEALL-NEXT:    movl %ecx, %r8d647; CHECK-FORCEALL-NEXT:    cmpl %ecx, %edx648; CHECK-FORCEALL-NEXT:    ja .LBB6_4649; CHECK-FORCEALL-NEXT:  # %bb.3: # %while.body650; CHECK-FORCEALL-NEXT:    # in Loop: Header=BB6_2 Depth=1651; CHECK-FORCEALL-NEXT:    movl $22, %eax652; CHECK-FORCEALL-NEXT:    movl $22, %r8d653; CHECK-FORCEALL-NEXT:  .LBB6_4: # %while.body654; CHECK-FORCEALL-NEXT:    # in Loop: Header=BB6_2 Depth=1655; CHECK-FORCEALL-NEXT:    xorl %edx, %edx656; CHECK-FORCEALL-NEXT:    divl %r8d657; CHECK-FORCEALL-NEXT:    movl %edx, (%rdi,%rsi,4)658; CHECK-FORCEALL-NEXT:    addl $1, %esi659; CHECK-FORCEALL-NEXT:    cmpl %r9d, %esi660; CHECK-FORCEALL-NEXT:    ja .LBB6_2661; CHECK-FORCEALL-NEXT:  .LBB6_5: # %while.end662; CHECK-FORCEALL-NEXT:    retq663entry:664  %cmp10 = icmp ugt i32 0, %n665  br i1 %cmp10, label %while.body, label %while.end666 667while.body:                                       ; preds = %entry, %while.body668  %i = phi i32 [ %i_inc, %while.body ], [ 0, %entry ]669  %arr_i = getelementptr inbounds i32, ptr %arr, i32 %i670  %x = load i32, ptr %arr_i, align 4671  %div = udiv i32 %x, %a672  %cond = icmp ugt i32 %div, %a673  %condOpp = icmp ule i32 %div, %a674  %s1 = select i1 %cond, i32 11, i32 22675  %s2 = select i1 %condOpp, i32 %s1, i32 %a676  %sum = urem i32 %s1, %s2677  store i32 %sum, ptr %arr_i, align 4678  %i_inc = add i32 %i, 1679  %cmp = icmp ugt i32 %i_inc, %n680  br i1 %cmp, label %while.body, label %while.end681 682while.end:                                        ; preds = %while.body, %entry683  ret void684}685 686; Test that we always will convert a cmov with a memory operand into a branch,687; even outside of a loop.688define i32 @test_cmov_memoperand(i32 %a, i32 %b, i32 %x, ptr %y) #0 {689; CHECK-LABEL: test_cmov_memoperand:690; CHECK:       # %bb.0: # %entry691; CHECK-NEXT:    movl %edx, %eax692; CHECK-NEXT:    cmpl %esi, %edi693; CHECK-NEXT:    ja .LBB7_2694; CHECK-NEXT:  # %bb.1: # %entry695; CHECK-NEXT:    movl (%rcx), %eax696; CHECK-NEXT:  .LBB7_2: # %entry697; CHECK-NEXT:    retq698;699; CHECK-FORCEALL-LABEL: test_cmov_memoperand:700; CHECK-FORCEALL:       # %bb.0: # %entry701; CHECK-FORCEALL-NEXT:    movl %edx, %eax702; CHECK-FORCEALL-NEXT:    cmpl %esi, %edi703; CHECK-FORCEALL-NEXT:    ja .LBB7_2704; CHECK-FORCEALL-NEXT:  # %bb.1: # %entry705; CHECK-FORCEALL-NEXT:    movl (%rcx), %eax706; CHECK-FORCEALL-NEXT:  .LBB7_2: # %entry707; CHECK-FORCEALL-NEXT:    retq708entry:709  %cond = icmp ugt i32 %a, %b710  %load = load i32, ptr %y711  %z = select i1 %cond, i32 %x, i32 %load712  ret i32 %z713}714 715; If cmov instruction is marked as unpredictable, do not convert it to branch.716define i32 @test_cmov_memoperand_unpredictable(i32 %a, i32 %b, i32 %x, ptr %y) #0 {717; CHECK-LABEL: test_cmov_memoperand_unpredictable:718; CHECK:       # %bb.0: # %entry719; CHECK-NEXT:    movl %edx, %eax720; CHECK-NEXT:    cmpl %esi, %edi721; CHECK-NEXT:    cmovbel (%rcx), %eax722; CHECK-NEXT:    retq723;724; CHECK-FORCEALL-LABEL: test_cmov_memoperand_unpredictable:725; CHECK-FORCEALL:       # %bb.0: # %entry726; CHECK-FORCEALL-NEXT:    movl %edx, %eax727; CHECK-FORCEALL-NEXT:    cmpl %esi, %edi728; CHECK-FORCEALL-NEXT:    cmovbel (%rcx), %eax729; CHECK-FORCEALL-NEXT:    retq730entry:731  %cond = icmp ugt i32 %a, %b732  %load = load i32, ptr %y733  %z = select i1 %cond, i32 %x, i32 %load, !unpredictable !0734  ret i32 %z735}736 737; Test that we can convert a group of cmovs where only one has a memory738; operand.739define i32 @test_cmov_memoperand_in_group(i32 %a, i32 %b, i32 %x, ptr %y.ptr) #0 {740; CHECK-LABEL: test_cmov_memoperand_in_group:741; CHECK:       # %bb.0: # %entry742; CHECK-NEXT:    movl %edx, %eax743; CHECK-NEXT:    movl %edx, %r8d744; CHECK-NEXT:    cmpl %esi, %edi745; CHECK-NEXT:    ja .LBB9_2746; CHECK-NEXT:  # %bb.1: # %entry747; CHECK-NEXT:    movl (%rcx), %edx748; CHECK-NEXT:    movl %edi, %eax749; CHECK-NEXT:    movl %esi, %r8d750; CHECK-NEXT:  .LBB9_2: # %entry751; CHECK-NEXT:    addl %r8d, %eax752; CHECK-NEXT:    addl %edx, %eax753; CHECK-NEXT:    retq754;755; CHECK-FORCEALL-LABEL: test_cmov_memoperand_in_group:756; CHECK-FORCEALL:       # %bb.0: # %entry757; CHECK-FORCEALL-NEXT:    movl %edx, %eax758; CHECK-FORCEALL-NEXT:    movl %edx, %r8d759; CHECK-FORCEALL-NEXT:    cmpl %esi, %edi760; CHECK-FORCEALL-NEXT:    ja .LBB9_2761; CHECK-FORCEALL-NEXT:  # %bb.1: # %entry762; CHECK-FORCEALL-NEXT:    movl (%rcx), %edx763; CHECK-FORCEALL-NEXT:    movl %edi, %eax764; CHECK-FORCEALL-NEXT:    movl %esi, %r8d765; CHECK-FORCEALL-NEXT:  .LBB9_2: # %entry766; CHECK-FORCEALL-NEXT:    addl %r8d, %eax767; CHECK-FORCEALL-NEXT:    addl %edx, %eax768; CHECK-FORCEALL-NEXT:    retq769entry:770  %cond = icmp ugt i32 %a, %b771  %y = load i32, ptr %y.ptr772  %z1 = select i1 %cond, i32 %x, i32 %a773  %z2 = select i1 %cond, i32 %x, i32 %y774  %z3 = select i1 %cond, i32 %x, i32 %b775  %s1 = add i32 %z1, %z2776  %s2 = add i32 %s1, %z3777  ret i32 %s2778}779 780; Same as before but with operands reversed in the select with a load.781define i32 @test_cmov_memoperand_in_group2(i32 %a, i32 %b, i32 %x, ptr %y.ptr) #0 {782; CHECK-LABEL: test_cmov_memoperand_in_group2:783; CHECK:       # %bb.0: # %entry784; CHECK-NEXT:    movl %edx, %eax785; CHECK-NEXT:    movl %edx, %r8d786; CHECK-NEXT:    cmpl %esi, %edi787; CHECK-NEXT:    jbe .LBB10_2788; CHECK-NEXT:  # %bb.1: # %entry789; CHECK-NEXT:    movl (%rcx), %edx790; CHECK-NEXT:    movl %edi, %eax791; CHECK-NEXT:    movl %esi, %r8d792; CHECK-NEXT:  .LBB10_2: # %entry793; CHECK-NEXT:    addl %r8d, %eax794; CHECK-NEXT:    addl %edx, %eax795; CHECK-NEXT:    retq796;797; CHECK-FORCEALL-LABEL: test_cmov_memoperand_in_group2:798; CHECK-FORCEALL:       # %bb.0: # %entry799; CHECK-FORCEALL-NEXT:    movl %edx, %eax800; CHECK-FORCEALL-NEXT:    movl %edx, %r8d801; CHECK-FORCEALL-NEXT:    cmpl %esi, %edi802; CHECK-FORCEALL-NEXT:    jbe .LBB10_2803; CHECK-FORCEALL-NEXT:  # %bb.1: # %entry804; CHECK-FORCEALL-NEXT:    movl (%rcx), %edx805; CHECK-FORCEALL-NEXT:    movl %edi, %eax806; CHECK-FORCEALL-NEXT:    movl %esi, %r8d807; CHECK-FORCEALL-NEXT:  .LBB10_2: # %entry808; CHECK-FORCEALL-NEXT:    addl %r8d, %eax809; CHECK-FORCEALL-NEXT:    addl %edx, %eax810; CHECK-FORCEALL-NEXT:    retq811entry:812  %cond = icmp ugt i32 %a, %b813  %y = load i32, ptr %y.ptr814  %z2 = select i1 %cond, i32 %a, i32 %x815  %z1 = select i1 %cond, i32 %y, i32 %x816  %z3 = select i1 %cond, i32 %b, i32 %x817  %s1 = add i32 %z1, %z2818  %s2 = add i32 %s1, %z3819  ret i32 %s2820}821 822; Test that we don't convert a group of cmovs with conflicting directions of823; loads.824define i32 @test_cmov_memoperand_conflicting_dir(i32 %a, i32 %b, i32 %x, ptr %y1.ptr, ptr %y2.ptr) #0 {825; CHECK-LABEL: test_cmov_memoperand_conflicting_dir:826; CHECK:       # %bb.0: # %entry827; CHECK-NEXT:    cmpl %esi, %edi828; CHECK-NEXT:    movl (%rcx), %eax829; CHECK-NEXT:    cmoval %edx, %eax830; CHECK-NEXT:    cmoval (%r8), %edx831; CHECK-NEXT:    addl %edx, %eax832; CHECK-NEXT:    retq833;834; CHECK-FORCEALL-LABEL: test_cmov_memoperand_conflicting_dir:835; CHECK-FORCEALL:       # %bb.0: # %entry836; CHECK-FORCEALL-NEXT:    cmpl %esi, %edi837; CHECK-FORCEALL-NEXT:    movl (%rcx), %eax838; CHECK-FORCEALL-NEXT:    cmoval %edx, %eax839; CHECK-FORCEALL-NEXT:    cmoval (%r8), %edx840; CHECK-FORCEALL-NEXT:    addl %edx, %eax841; CHECK-FORCEALL-NEXT:    retq842entry:843  %cond = icmp ugt i32 %a, %b844  %y1 = load i32, ptr %y1.ptr845  %y2 = load i32, ptr %y2.ptr846  %z1 = select i1 %cond, i32 %x, i32 %y1847  %z2 = select i1 %cond, i32 %y2, i32 %x848  %s1 = add i32 %z1, %z2849  ret i32 %s1850}851 852; Test that we can convert a group of cmovs where only one has a memory853; operand and where that memory operand's registers come from a prior cmov in854; the group.855define i32 @test_cmov_memoperand_in_group_reuse_for_addr(i32 %a, i32 %b, ptr %x, ptr %y) #0 {856; CHECK-LABEL: test_cmov_memoperand_in_group_reuse_for_addr:857; CHECK:       # %bb.0: # %entry858; CHECK-NEXT:    movl %edi, %eax859; CHECK-NEXT:    cmpl %esi, %edi860; CHECK-NEXT:    ja .LBB12_2861; CHECK-NEXT:  # %bb.1: # %entry862; CHECK-NEXT:    movl (%rcx), %eax863; CHECK-NEXT:  .LBB12_2: # %entry864; CHECK-NEXT:    retq865;866; CHECK-FORCEALL-LABEL: test_cmov_memoperand_in_group_reuse_for_addr:867; CHECK-FORCEALL:       # %bb.0: # %entry868; CHECK-FORCEALL-NEXT:    movl %edi, %eax869; CHECK-FORCEALL-NEXT:    cmpl %esi, %edi870; CHECK-FORCEALL-NEXT:    ja .LBB12_2871; CHECK-FORCEALL-NEXT:  # %bb.1: # %entry872; CHECK-FORCEALL-NEXT:    movl (%rcx), %eax873; CHECK-FORCEALL-NEXT:  .LBB12_2: # %entry874; CHECK-FORCEALL-NEXT:    retq875entry:876  %cond = icmp ugt i32 %a, %b877  %p = select i1 %cond, ptr %x, ptr %y878  %load = load i32, ptr %p879  %z = select i1 %cond, i32 %a, i32 %load880  ret i32 %z881}882 883; Test that we can convert a group of two cmovs with memory operands where one884; uses the result of the other as part of the address.885define i32 @test_cmov_memoperand_in_group_reuse_for_addr2(i32 %a, i32 %b, ptr %x, ptr %y) #0 {886; CHECK-LABEL: test_cmov_memoperand_in_group_reuse_for_addr2:887; CHECK:       # %bb.0: # %entry888; CHECK-NEXT:    movl %edi, %eax889; CHECK-NEXT:    cmpl %esi, %edi890; CHECK-NEXT:    ja .LBB13_2891; CHECK-NEXT:  # %bb.1: # %entry892; CHECK-NEXT:    movq (%rcx), %rax893; CHECK-NEXT:    movl (%rax), %eax894; CHECK-NEXT:  .LBB13_2: # %entry895; CHECK-NEXT:    retq896;897; CHECK-FORCEALL-LABEL: test_cmov_memoperand_in_group_reuse_for_addr2:898; CHECK-FORCEALL:       # %bb.0: # %entry899; CHECK-FORCEALL-NEXT:    movl %edi, %eax900; CHECK-FORCEALL-NEXT:    cmpl %esi, %edi901; CHECK-FORCEALL-NEXT:    ja .LBB13_2902; CHECK-FORCEALL-NEXT:  # %bb.1: # %entry903; CHECK-FORCEALL-NEXT:    movq (%rcx), %rax904; CHECK-FORCEALL-NEXT:    movl (%rax), %eax905; CHECK-FORCEALL-NEXT:  .LBB13_2: # %entry906; CHECK-FORCEALL-NEXT:    retq907entry:908  %cond = icmp ugt i32 %a, %b909  %load1 = load ptr, ptr %y910  %p = select i1 %cond, ptr %x, ptr %load1911  %load2 = load i32, ptr %p912  %z = select i1 %cond, i32 %a, i32 %load2913  ret i32 %z914}915 916; Test that we can convert a group of cmovs where only one has a memory917; operand and where that memory operand's registers come from a prior cmov and918; where that cmov gets *its* input from a prior cmov in the group.919define i32 @test_cmov_memoperand_in_group_reuse_for_addr3(i32 %a, i32 %b, ptr %x, ptr %y, ptr %z) #0 {920; CHECK-LABEL: test_cmov_memoperand_in_group_reuse_for_addr3:921; CHECK:       # %bb.0: # %entry922; CHECK-NEXT:    movl %edi, %eax923; CHECK-NEXT:    cmpl %esi, %edi924; CHECK-NEXT:    ja .LBB14_2925; CHECK-NEXT:  # %bb.1: # %entry926; CHECK-NEXT:    movl (%rcx), %eax927; CHECK-NEXT:  .LBB14_2: # %entry928; CHECK-NEXT:    retq929;930; CHECK-FORCEALL-LABEL: test_cmov_memoperand_in_group_reuse_for_addr3:931; CHECK-FORCEALL:       # %bb.0: # %entry932; CHECK-FORCEALL-NEXT:    movl %edi, %eax933; CHECK-FORCEALL-NEXT:    cmpl %esi, %edi934; CHECK-FORCEALL-NEXT:    ja .LBB14_2935; CHECK-FORCEALL-NEXT:  # %bb.1: # %entry936; CHECK-FORCEALL-NEXT:    movl (%rcx), %eax937; CHECK-FORCEALL-NEXT:  .LBB14_2: # %entry938; CHECK-FORCEALL-NEXT:    retq939entry:940  %cond = icmp ugt i32 %a, %b941  %p = select i1 %cond, ptr %x, ptr %y942  %p2 = select i1 %cond, ptr %z, ptr %p943  %load = load i32, ptr %p2944  %r = select i1 %cond, i32 %a, i32 %load945  ret i32 %r946}947 948@begin = external global ptr949@end = external global ptr950 951define void @test_memoperand_loop(i32 %data) #0 {952; CHECK-LABEL: test_memoperand_loop:953; CHECK:       # %bb.0: # %entry954; CHECK-NEXT:    movq begin@GOTPCREL(%rip), %rax955; CHECK-NEXT:    movq (%rax), %rcx956; CHECK-NEXT:    movq end@GOTPCREL(%rip), %rdx957; CHECK-NEXT:    movq (%rdx), %rdx958; CHECK-NEXT:    xorl %esi, %esi959; CHECK-NEXT:    movq %rcx, %r8960; CHECK-NEXT:  .LBB15_1: # %loop.body961; CHECK-NEXT:    # =>This Inner Loop Header: Depth=1962; CHECK-NEXT:    addq $8, %r8963; CHECK-NEXT:    cmpq %rdx, %r8964; CHECK-NEXT:    ja .LBB15_3965; CHECK-NEXT:  # %bb.2: # %loop.body966; CHECK-NEXT:    # in Loop: Header=BB15_1 Depth=1967; CHECK-NEXT:    movq (%rax), %r8968; CHECK-NEXT:  .LBB15_3: # %loop.body969; CHECK-NEXT:    # in Loop: Header=BB15_1 Depth=1970; CHECK-NEXT:    movl %edi, (%r8)971; CHECK-NEXT:    addq $8, %r8972; CHECK-NEXT:    cmpq %rdx, %r8973; CHECK-NEXT:    ja .LBB15_5974; CHECK-NEXT:  # %bb.4: # %loop.body975; CHECK-NEXT:    # in Loop: Header=BB15_1 Depth=1976; CHECK-NEXT:    movq %rcx, %r8977; CHECK-NEXT:  .LBB15_5: # %loop.body978; CHECK-NEXT:    # in Loop: Header=BB15_1 Depth=1979; CHECK-NEXT:    movl %edi, (%r8)980; CHECK-NEXT:    addl $1, %esi981; CHECK-NEXT:    cmpl $1024, %esi # imm = 0x400982; CHECK-NEXT:    jl .LBB15_1983; CHECK-NEXT:  # %bb.6: # %exit984; CHECK-NEXT:    retq985;986; CHECK-FORCEALL-LABEL: test_memoperand_loop:987; CHECK-FORCEALL:       # %bb.0: # %entry988; CHECK-FORCEALL-NEXT:    movq begin@GOTPCREL(%rip), %rax989; CHECK-FORCEALL-NEXT:    movq (%rax), %rcx990; CHECK-FORCEALL-NEXT:    movq end@GOTPCREL(%rip), %rdx991; CHECK-FORCEALL-NEXT:    movq (%rdx), %rdx992; CHECK-FORCEALL-NEXT:    xorl %esi, %esi993; CHECK-FORCEALL-NEXT:    movq %rcx, %r8994; CHECK-FORCEALL-NEXT:  .LBB15_1: # %loop.body995; CHECK-FORCEALL-NEXT:    # =>This Inner Loop Header: Depth=1996; CHECK-FORCEALL-NEXT:    addq $8, %r8997; CHECK-FORCEALL-NEXT:    cmpq %rdx, %r8998; CHECK-FORCEALL-NEXT:    ja .LBB15_3999; CHECK-FORCEALL-NEXT:  # %bb.2: # %loop.body1000; CHECK-FORCEALL-NEXT:    # in Loop: Header=BB15_1 Depth=11001; CHECK-FORCEALL-NEXT:    movq (%rax), %r81002; CHECK-FORCEALL-NEXT:  .LBB15_3: # %loop.body1003; CHECK-FORCEALL-NEXT:    # in Loop: Header=BB15_1 Depth=11004; CHECK-FORCEALL-NEXT:    movl %edi, (%r8)1005; CHECK-FORCEALL-NEXT:    addq $8, %r81006; CHECK-FORCEALL-NEXT:    cmpq %rdx, %r81007; CHECK-FORCEALL-NEXT:    ja .LBB15_51008; CHECK-FORCEALL-NEXT:  # %bb.4: # %loop.body1009; CHECK-FORCEALL-NEXT:    # in Loop: Header=BB15_1 Depth=11010; CHECK-FORCEALL-NEXT:    movq %rcx, %r81011; CHECK-FORCEALL-NEXT:  .LBB15_5: # %loop.body1012; CHECK-FORCEALL-NEXT:    # in Loop: Header=BB15_1 Depth=11013; CHECK-FORCEALL-NEXT:    movl %edi, (%r8)1014; CHECK-FORCEALL-NEXT:    addl $1, %esi1015; CHECK-FORCEALL-NEXT:    cmpl $1024, %esi # imm = 0x4001016; CHECK-FORCEALL-NEXT:    jl .LBB15_11017; CHECK-FORCEALL-NEXT:  # %bb.6: # %exit1018; CHECK-FORCEALL-NEXT:    retq1019entry:1020  %begin = load ptr, ptr @begin, align 81021  %end = load ptr, ptr @end, align 81022  br label %loop.body1023loop.body:1024  %phi.iv = phi i32 [ 0, %entry ], [ %iv.next, %loop.body ]1025  %phi.ptr = phi ptr [ %begin, %entry ], [ %dst2, %loop.body ]1026  %gep1 = getelementptr inbounds i32, ptr%phi.ptr, i64 21027  %cmp1 = icmp ugt ptr %gep1, %end1028  %begin_dup = load ptr, ptr @begin, align 81029  %dst1 = select i1 %cmp1, ptr %gep1, ptr %begin_dup1030  store i32 %data, ptr%dst1, align 41031  %gep2 = getelementptr inbounds i32, ptr%dst1, i64 21032  %cmp2 = icmp ugt ptr %gep2, %end1033  %dst2 = select i1 %cmp2, ptr %gep2, ptr %begin1034  store i32 %data, ptr%dst2, align 41035  %iv.next = add i32 %phi.iv, 11036  %cond = icmp slt i32 %iv.next, 10241037  br i1 %cond, label %loop.body, label %exit1038exit:1039  ret void1040}1041 1042attributes #0 = {"target-cpu"="x86-64" "tune-cpu"="x86-64"}1043!0 = !{}1044