; RUN: llc -verify-machineinstrs < %s -mtriple=powerpc64-unknown-linux-gnu | FileCheck %s ; RUN: llc -verify-machineinstrs < %s -mtriple=powerpc64le-unknown-linux-gnu | FileCheck %s ; Test cases for compare elimination in PPCMIPeephole pass define void @func1(i32 signext %a) { ; We should have only one compare instruction ; CHECK-LABEL: @func1 ; CHECK: cmp ; CHECK-NOT: cmp ; CHECK: blr entry: %cmp = icmp eq i32 %a, 100 br i1 %cmp, label %if.then, label %if.else if.then: tail call void @dummy1() br label %if.end3 if.else: %cmp1 = icmp slt i32 %a, 100 br i1 %cmp1, label %if.then2, label %if.end3 if.then2: tail call void @dummy2() br label %if.end3 if.end3: ret void } define void @func2(i32 signext %a) { ; CHECK-LABEL: @func2 ; CHECK: cmp ; CHECK-NOT: cmp ; CHECK: blr entry: %cmp = icmp slt i32 %a, 100 br i1 %cmp, label %if.then, label %if.else if.then: tail call void @dummy1() br label %if.end3 if.else: %cmp1 = icmp eq i32 %a, 100 br i1 %cmp1, label %if.end3, label %if.then2 if.then2: tail call void @dummy2() br label %if.end3 if.end3: ret void } define void @func3(i32 signext %a) { ; CHECK-LABEL: @func3 ; CHECK: cmp ; CHECK-NOT: cmp ; CHECK: blr entry: %cmp = icmp sgt i32 %a, 100 br i1 %cmp, label %if.then, label %if.else if.then: tail call void @dummy1() br label %if.end3 if.else: %cmp1 = icmp eq i32 %a, 100 br i1 %cmp1, label %if.then2, label %if.end3 if.then2: tail call void @dummy2() br label %if.end3 if.end3: ret void } define void @func4(i32 zeroext %a) { ; CHECK-LABEL: @func4 ; CHECK: cmp ; CHECK-NOT: cmp ; CHECK: blr entry: %cmp = icmp eq i32 %a, 100 br i1 %cmp, label %if.then, label %if.else if.then: tail call void @dummy1() br label %if.end3 if.else: %cmp1 = icmp ult i32 %a, 100 br i1 %cmp1, label %if.then2, label %if.end3 if.then2: tail call void @dummy2() br label %if.end3 if.end3: ret void } define void @func5(i32 zeroext %a) { ; CHECK-LABEL: @func5 ; CHECK: cmp ; CHECK-NOT: cmp ; CHECK: blr entry: %cmp = icmp ult i32 %a, 100 br i1 %cmp, label %if.then, label %if.else if.then: tail call void @dummy1() br label %if.end3 if.else: %cmp1 = icmp eq i32 %a, 100 br i1 %cmp1, label %if.end3, label %if.then2 if.then2: tail call void @dummy2() br label %if.end3 if.end3: ret void } define void @func6(i32 zeroext %a) { ; CHECK-LABEL: @func6 ; CHECK: cmp ; CHECK-NOT: cmp ; CHECK: blr entry: %cmp = icmp ugt i32 %a, 100 br i1 %cmp, label %if.then, label %if.else if.then: tail call void @dummy1() br label %if.end3 if.else: %cmp1 = icmp eq i32 %a, 100 br i1 %cmp1, label %if.then2, label %if.end3 if.then2: tail call void @dummy2() br label %if.end3 if.end3: ret void } define void @func7(i64 %a) { ; CHECK-LABEL: @func7 ; CHECK: cmp ; CHECK-NOT: cmp ; CHECK: blr entry: %cmp = icmp eq i64 %a, 100 br i1 %cmp, label %if.then, label %if.else if.then: tail call void @dummy1() br label %if.end3 if.else: %cmp1 = icmp slt i64 %a, 100 br i1 %cmp1, label %if.then2, label %if.end3 if.then2: tail call void @dummy2() br label %if.end3 if.end3: ret void } define void @func8(i64 %a) { ; CHECK-LABEL: @func8 ; CHECK: cmp ; CHECK-NOT: cmp ; CHECK: blr entry: %cmp = icmp slt i64 %a, 100 br i1 %cmp, label %if.then, label %if.else if.then: tail call void @dummy1() br label %if.end3 if.else: %cmp1 = icmp eq i64 %a, 100 br i1 %cmp1, label %if.end3, label %if.then2 if.then2: tail call void @dummy2() br label %if.end3 if.end3: ret void } define void @func9(i64 %a) { ; CHECK-LABEL: @func9 ; CHECK: cmp ; CHECK-NOT: cmp ; CHECK: blr entry: %cmp = icmp sgt i64 %a, 100 br i1 %cmp, label %if.then, label %if.else if.then: tail call void @dummy1() br label %if.end3 if.else: %cmp1 = icmp eq i64 %a, 100 br i1 %cmp1, label %if.then2, label %if.end3 if.then2: tail call void @dummy2() br label %if.end3 if.end3: ret void } define void @func10(i64 %a) { ; CHECK-LABEL: @func10 ; CHECK: cmp ; CHECK-NOT: cmp ; CHECK: blr entry: %cmp = icmp eq i64 %a, 100 br i1 %cmp, label %if.then, label %if.else if.then: tail call void @dummy1() br label %if.end3 if.else: %cmp1 = icmp ult i64 %a, 100 br i1 %cmp1, label %if.then2, label %if.end3 if.then2: tail call void @dummy2() br label %if.end3 if.end3: ret void } define void @func11(i64 %a) { ; CHECK-LABEL: @func11 ; CHECK: cmp ; CHECK-NOT: cmp ; CHECK: blr entry: %cmp = icmp ult i64 %a, 100 br i1 %cmp, label %if.then, label %if.else if.then: tail call void @dummy1() br label %if.end3 if.else: %cmp1 = icmp eq i64 %a, 100 br i1 %cmp1, label %if.end3, label %if.then2 if.then2: tail call void @dummy2() br label %if.end3 if.end3: ret void } define void @func12(i64 %a) { ; CHECK-LABEL: @func12 ; CHECK: cmp ; CHECK-NOT: cmp ; CHECK: blr entry: %cmp = icmp ugt i64 %a, 100 br i1 %cmp, label %if.then, label %if.else if.then: tail call void @dummy1() br label %if.end3 if.else: %cmp1 = icmp eq i64 %a, 100 br i1 %cmp1, label %if.then2, label %if.end3 if.then2: tail call void @dummy2() br label %if.end3 if.end3: ret void } define void @func13(i32 signext %a, i32 signext %b) { ; CHECK-LABEL: @func13 ; CHECK: cmp ; CHECK-NOT: cmp ; CHECK: blr entry: %cmp = icmp eq i32 %a, %b br i1 %cmp, label %if.then, label %if.else if.then: tail call void @dummy1() br label %if.end3 if.else: %cmp1 = icmp slt i32 %a, %b br i1 %cmp1, label %if.then2, label %if.end3 if.then2: tail call void @dummy2() br label %if.end3 if.end3: ret void } define void @func14(i32 signext %a, i32 signext %b) { ; CHECK-LABEL: @func14 ; CHECK: cmp ; CHECK-NOT: cmp ; CHECK: blr entry: %cmp = icmp slt i32 %a, %b br i1 %cmp, label %if.then, label %if.else if.then: tail call void @dummy1() br label %if.end3 if.else: %cmp1 = icmp sgt i32 %a, %b br i1 %cmp1, label %if.then2, label %if.end3 if.then2: tail call void @dummy2() br label %if.end3 if.end3: ret void } define void @func15(i32 signext %a, i32 signext %b) { ; CHECK-LABEL: @func15 ; CHECK: cmp ; CHECK-NOT: cmp ; CHECK: blr entry: %cmp = icmp slt i32 %b, %a br i1 %cmp, label %if.then, label %if.else if.then: tail call void @dummy1() br label %if.end3 if.else: %cmp1 = icmp eq i32 %a, %b br i1 %cmp1, label %if.then2, label %if.end3 if.then2: tail call void @dummy2() br label %if.end3 if.end3: ret void } define void @func16(i32 zeroext %a, i32 zeroext %b) { ; CHECK-LABEL: @func16 ; CHECK: cmp ; CHECK-NOT: cmp ; CHECK: blr entry: %cmp = icmp eq i32 %a, %b br i1 %cmp, label %if.then, label %if.else if.then: tail call void @dummy1() br label %if.end3 if.else: %cmp1 = icmp ult i32 %a, %b br i1 %cmp1, label %if.then2, label %if.end3 if.then2: tail call void @dummy2() br label %if.end3 if.end3: ret void } define void @func17(i32 zeroext %a, i32 zeroext %b) { ; CHECK-LABEL: @func17 ; CHECK: cmp ; CHECK-NOT: cmp ; CHECK: blr entry: %cmp = icmp ult i32 %a, %b br i1 %cmp, label %if.then, label %if.else if.then: tail call void @dummy1() br label %if.end3 if.else: %cmp1 = icmp ugt i32 %a, %b br i1 %cmp1, label %if.then2, label %if.end3 if.then2: tail call void @dummy2() br label %if.end3 if.end3: ret void } define void @func18(i32 zeroext %a, i32 zeroext %b) { ; CHECK-LABEL: @func18 ; CHECK: cmp ; CHECK-NOT: cmp ; CHECK: blr entry: %cmp = icmp ult i32 %b, %a br i1 %cmp, label %if.then, label %if.else if.then: tail call void @dummy1() br label %if.end3 if.else: %cmp1 = icmp eq i32 %a, %b br i1 %cmp1, label %if.then2, label %if.end3 if.then2: tail call void @dummy2() br label %if.end3 if.end3: ret void } define void @func19(i64 %a, i64 %b) { ; CHECK-LABEL: @func19 ; CHECK: cmp ; CHECK-NOT: cmp ; CHECK: blr entry: %cmp = icmp eq i64 %a, %b br i1 %cmp, label %if.then, label %if.else if.then: tail call void @dummy1() br label %if.end3 if.else: %cmp1 = icmp slt i64 %a, %b br i1 %cmp1, label %if.then2, label %if.end3 if.then2: tail call void @dummy2() br label %if.end3 if.end3: ret void } define void @func20(i64 %a, i64 %b) { ; CHECK-LABEL: @func20 ; CHECK: cmp ; CHECK-NOT: cmp ; CHECK: blr entry: %cmp = icmp slt i64 %a, %b br i1 %cmp, label %if.then, label %if.else if.then: tail call void @dummy1() br label %if.end3 if.else: %cmp1 = icmp sgt i64 %a, %b br i1 %cmp1, label %if.then2, label %if.end3 if.then2: tail call void @dummy2() br label %if.end3 if.end3: ret void } define void @func21(i64 %a, i64 %b) { ; CHECK-LABEL: @func21 ; CHECK: cmp ; CHECK-NOT: cmp ; CHECK: blr entry: %cmp = icmp slt i64 %b, %a br i1 %cmp, label %if.then, label %if.else if.then: tail call void @dummy1() br label %if.end3 if.else: %cmp1 = icmp eq i64 %a, %b br i1 %cmp1, label %if.then2, label %if.end3 if.then2: tail call void @dummy2() br label %if.end3 if.end3: ret void } define void @func22(i64 %a, i64 %b) { ; CHECK-LABEL: @func22 ; CHECK: cmp ; CHECK-NOT: cmp ; CHECK: blr entry: %cmp = icmp eq i64 %a, %b br i1 %cmp, label %if.then, label %if.else if.then: tail call void @dummy1() br label %if.end3 if.else: %cmp1 = icmp ult i64 %a, %b br i1 %cmp1, label %if.then2, label %if.end3 if.then2: tail call void @dummy2() br label %if.end3 if.end3: ret void } define void @func23(i64 %a, i64 %b) { ; CHECK-LABEL: @func23 ; CHECK: cmp ; CHECK-NOT: cmp ; CHECK: blr entry: %cmp = icmp ult i64 %a, %b br i1 %cmp, label %if.then, label %if.else if.then: tail call void @dummy1() br label %if.end3 if.else: %cmp1 = icmp ugt i64 %a, %b br i1 %cmp1, label %if.then2, label %if.end3 if.then2: tail call void @dummy2() br label %if.end3 if.end3: ret void } define void @func24(i64 %a, i64 %b) { ; CHECK-LABEL: @func24 ; CHECK: cmp ; CHECK-NOT: cmp ; CHECK: blr entry: %cmp = icmp ult i64 %b, %a br i1 %cmp, label %if.then, label %if.else if.then: tail call void @dummy1() br label %if.end3 if.else: %cmp1 = icmp eq i64 %a, %b br i1 %cmp1, label %if.then2, label %if.end3 if.then2: tail call void @dummy2() br label %if.end3 if.end3: ret void } define void @func25(i64 %a, i64 %b) { ; CHECK-LABEL: @func25 ; CHECK: cmp ; CHECK-NOT: cmp ; CHECK: blr entry: %cmp = icmp slt i64 %b, %a br i1 %cmp, label %if.then, label %if.else, !prof !1 if.then: tail call void @dummy1() br label %if.end6 if.else: %cmp2 = icmp eq i64 %a, %b br i1 %cmp2, label %if.then4, label %if.else5 if.then4: tail call void @dummy2() br label %if.end6 if.else5: tail call void @dummy3() br label %if.end6 if.end6: ret void } define void @func26(i32 signext %a) { ; CHECK-LABEL: @func26 ; CHECK: cmp ; CHECK-NOT: cmp ; CHECK: blr entry: %cmp = icmp sgt i32 %a, 0 br i1 %cmp, label %if.then, label %if.else, !prof !2 if.then: tail call void @dummy1() br label %if.end9 if.else: %cmp2 = icmp eq i32 %a, 0 br i1 %cmp2, label %if.then7, label %if.else8, !prof !2 if.then7: tail call void @dummy2() br label %if.end9 if.else8: tail call void @dummy3() br label %if.end9 if.end9: ret void } @g1 = external local_unnamed_addr global i32, align 4 @g2 = external local_unnamed_addr global i32, align 4 define void @func27(i32 signext %a) { ; CHECK-LABEL: @func27 ; CHECK: cmp ; CHECK: beq ; CHECK-NOT: cmp ; CHECK: bgelr ; CHECK: blr entry: %cmp = icmp eq i32 %a, 0 br i1 %cmp, label %if.end3.sink.split, label %if.else if.else: %cmp1 = icmp slt i32 %a, 0 br i1 %cmp1, label %if.end3.sink.split, label %if.end if.end3.sink.split: %g2.sink = phi i32* [ @g2, %if.else ], [ @g1, %entry ] store i32 0, i32* %g2.sink, align 4 br label %if.end if.end: ret void } ; partially redundant case define void @func28(i32 signext %a) { ; CHECK-LABEL: @func28 ; CHECK: cmplwi [[REG1:[0-9]+]], [[REG2:[0-9]+]] ; CHECK: .[[LABEL1:[A-Z0-9_]+]]: ; CHECK-NOT: cmp ; CHECK: bne 0, .[[LABEL2:[A-Z0-9_]+]] ; CHECK: bl dummy1 ; CHECK: .[[LABEL2]]: ; CHECK: cmpwi [[REG1]], [[REG2]] ; CHECK: bgt 0, .[[LABEL1]] ; CHECK: blr entry: br label %do.body do.body: %a.addr.0 = phi i32 [ %a, %entry ], [ %call, %if.end ] %cmp = icmp eq i32 %a.addr.0, 0 br i1 %cmp, label %if.then, label %if.end if.then: tail call void @dummy1() #2 br label %if.end if.end: %call = tail call signext i32 @func(i32 signext %a.addr.0) #2 %cmp1 = icmp sgt i32 %call, 0 br i1 %cmp1, label %do.body, label %do.end do.end: ret void } define void @func29(i32 signext %a) { ; We cannot merge two compares due to difference in sign extension behaviors. ; equivalent C code example: ; int a = .. ; ; if (a == -1) dummy1(); ; if (a == (uint16_t)-1) dummy2(); ; CHECK-LABEL: @func29 ; CHECK: cmp ; CHECK: cmp ; CHECK: blr entry: %cmp = icmp eq i32 %a, -1 br i1 %cmp, label %if.then, label %if.else if.then: tail call void @dummy1() br label %if.end3 if.else: %cmp1 = icmp eq i32 %a, 65535 br i1 %cmp1, label %if.then2, label %if.end3 if.then2: tail call void @dummy2() br label %if.end3 if.end3: ret void } declare void @dummy1() declare void @dummy2() declare void @dummy3() declare signext i32 @func(i32 signext) !1 = !{!"branch_weights", i32 2000, i32 1} !2 = !{!"branch_weights", i32 1, i32 2000}