| ; RUN: llc < %s -mtriple=s390x-linux-gnu -mcpu=z14 | FileCheck %s | |
| ; | |
| ; Check that signed comparisons against 0 are only eliminated if the "nsw" | |
| ; flag is present on the defining add (with register) instruction. For an | |
| ; equality comparison, add logical can be used. | |
| define i32 @fun0(i32 %arg, i32 %arg2, i32 %arg3) { | |
| ; CHECK-LABEL: fun0: | |
| ; CHECK: jle .LBB0_2{{$}} | |
| ; CHECK: je .LBB0_4{{$}} | |
| bb: | |
| %tmp2 = add nsw i32 %arg, %arg2 | |
| %tmp3 = icmp sgt i32 %tmp2, 0 | |
| br i1 %tmp3, label %bb3, label %bb1 | |
| bb1: | |
| %tmp4 = add nsw i32 %arg, %arg3 | |
| %tmp5 = icmp eq i32 %tmp4, 0 | |
| br i1 %tmp5, label %bb4, label %bb2 | |
| bb2: | |
| ret i32 0 | |
| bb3: | |
| ret i32 1 | |
| bb4: | |
| ret i32 2 | |
| } | |
| ; No "nsw" flag | |
| define i32 @fun1(i32 %arg, i32 %arg2, i32 %arg3) { | |
| ; CHECK-LABEL: fun1: | |
| ; CHECK: cijle | |
| ; CHECK: alr | |
| ; CHECK: jhe | |
| bb: | |
| %tmp2 = add i32 %arg, %arg2 | |
| %tmp3 = icmp sgt i32 %tmp2, 0 | |
| br i1 %tmp3, label %bb3, label %bb1 | |
| bb1: | |
| %tmp4 = add i32 %arg, %arg3 | |
| %tmp5 = icmp eq i32 %tmp4, 0 | |
| br i1 %tmp5, label %bb4, label %bb2 | |
| bb2: | |
| ret i32 0 | |
| bb3: | |
| ret i32 1 | |
| bb4: | |
| ret i32 2 | |
| } | |
| ; "nuw" flag | |
| define i32 @fun2(i32 %arg, i32 %arg2, i32 %arg3) { | |
| ; CHECK-LABEL: fun2: | |
| ; CHECK: cijle | |
| ; CHECK: alr | |
| ; CHECK: jhe | |
| bb: | |
| %tmp2 = add nuw i32 %arg, %arg2 | |
| %tmp3 = icmp sgt i32 %tmp2, 0 | |
| br i1 %tmp3, label %bb3, label %bb1 | |
| bb1: | |
| %tmp4 = add nuw i32 %arg, %arg3 | |
| %tmp5 = icmp eq i32 %tmp4, 0 | |
| br i1 %tmp5, label %bb4, label %bb2 | |
| bb2: | |
| ret i32 0 | |
| bb3: | |
| ret i32 1 | |
| bb4: | |
| ret i32 2 | |
| } | |
| ; Subtraction does not produce the value of zero in case of overflow, so | |
| ; "nsw" is not needed for the equality check against zero. | |
| define i32 @fun3(i32 %arg, i32 %arg2, i32 %arg3) { | |
| ; CHECK-LABEL: fun3: | |
| ; CHECK: jle .LBB3_2{{$}} | |
| ; CHECK: je .LBB3_4{{$}} | |
| bb: | |
| %tmp2 = sub nsw i32 %arg, %arg2 | |
| %tmp3 = icmp sgt i32 %tmp2, 0 | |
| br i1 %tmp3, label %bb3, label %bb1 | |
| bb1: | |
| %tmp4 = sub nsw i32 %arg, %arg3 | |
| %tmp5 = icmp eq i32 %tmp4, 0 | |
| br i1 %tmp5, label %bb4, label %bb2 | |
| bb2: | |
| ret i32 0 | |
| bb3: | |
| ret i32 1 | |
| bb4: | |
| ret i32 2 | |
| } | |
| ; No "nsw" flag | |
| define i32 @fun4(i32 %arg, i32 %arg2, i32 %arg3) { | |
| ; CHECK-LABEL: fun4: | |
| ; CHECK: cijle | |
| ; CHECK: je .LBB4_4{{$}} | |
| bb: | |
| %tmp2 = sub i32 %arg, %arg2 | |
| %tmp3 = icmp sgt i32 %tmp2, 0 | |
| br i1 %tmp3, label %bb3, label %bb1 | |
| bb1: | |
| %tmp4 = sub i32 %arg, %arg3 | |
| %tmp5 = icmp eq i32 %tmp4, 0 | |
| br i1 %tmp5, label %bb4, label %bb2 | |
| bb2: | |
| ret i32 0 | |
| bb3: | |
| ret i32 1 | |
| bb4: | |
| ret i32 2 | |
| } | |
| ; "nuw" flag | |
| define i32 @fun5(i32 %arg, i32 %arg2, i32 %arg3) { | |
| ; CHECK-LABEL: fun5: | |
| ; CHECK: cijle | |
| ; CHECK: je .LBB5_4{{$}} | |
| bb: | |
| %tmp2 = sub nuw i32 %arg, %arg2 | |
| %tmp3 = icmp sgt i32 %tmp2, 0 | |
| br i1 %tmp3, label %bb3, label %bb1 | |
| bb1: | |
| %tmp4 = sub nuw i32 %arg, %arg3 | |
| %tmp5 = icmp eq i32 %tmp4, 0 | |
| br i1 %tmp5, label %bb4, label %bb2 | |
| bb2: | |
| ret i32 0 | |
| bb3: | |
| ret i32 1 | |
| bb4: | |
| ret i32 2 | |
| } |