%merge.cond.2 = phi i1 [false, %if.true.2], [true, %if.false.2]
ret i1 %merge.cond.2
}
+
+; if (x && !y) ret 42; ret 3
+
+define i32 @logical_and_not(i1 %x, i1 %y) {
+; CHECK-LABEL: @logical_and_not(
+; CHECK-NEXT: entry:
+; CHECK-NEXT: [[NOTY:%.*]] = xor i1 [[Y:%.*]], true
+; CHECK-NEXT: [[AND:%.*]] = select i1 [[X:%.*]], i1 [[NOTY]], i1 false
+; CHECK-NEXT: br i1 [[AND]], label [[T:%.*]], label [[F:%.*]]
+; CHECK: t:
+; CHECK-NEXT: ret i32 42
+; CHECK: f:
+; CHECK-NEXT: ret i32 3
+;
+entry:
+ %noty = xor i1 %y, true
+ %and = select i1 %x, i1 %noty, i1 false
+ br i1 %and, label %t, label %f
+
+t:
+ ret i32 42
+
+f:
+ ret i32 3
+}
+
+; if (x && y || !x) ret 3; ret 42
+
+define i32 @logical_and_or(i1 %x, i1 %y) {
+; CHECK-LABEL: @logical_and_or(
+; CHECK-NEXT: entry:
+; CHECK-NEXT: [[NOT_X:%.*]] = xor i1 [[X:%.*]], true
+; CHECK-NEXT: [[AND:%.*]] = select i1 [[NOT_X]], i1 true, i1 [[Y:%.*]]
+; CHECK-NEXT: br i1 [[AND]], label [[F:%.*]], label [[T:%.*]]
+; CHECK: t:
+; CHECK-NEXT: ret i32 42
+; CHECK: f:
+; CHECK-NEXT: ret i32 3
+;
+entry:
+ %and = select i1 %x, i1 %y, i1 true
+ br i1 %and, label %f, label %t
+
+t:
+ ret i32 42
+
+f:
+ ret i32 3
+}
+
+; if (!x || y) ret 3; ret 42
+
+define i32 @logical_or_not(i1 %x, i1 %y) {
+; CHECK-LABEL: @logical_or_not(
+; CHECK-NEXT: entry:
+; CHECK-NEXT: [[NOTX:%.*]] = xor i1 [[X:%.*]], true
+; CHECK-NEXT: [[AND:%.*]] = select i1 [[NOTX]], i1 true, i1 [[Y:%.*]]
+; CHECK-NEXT: br i1 [[AND]], label [[F:%.*]], label [[T:%.*]]
+; CHECK: t:
+; CHECK-NEXT: ret i32 42
+; CHECK: f:
+; CHECK-NEXT: ret i32 3
+;
+entry:
+ %notx = xor i1 %x, true
+ %and = select i1 %notx, i1 true, i1 %y
+ br i1 %and, label %f, label %t
+
+t:
+ ret i32 42
+
+f:
+ ret i32 3
+}
; CHECK-NEXT: br i1 [[CMP]], label [[IF_END:%.*]], label [[IF_THEN:%.*]]
; CHECK: if.then:
; CHECK-NEXT: store i32 [[OR]], i32* [[ARRAYIDX]], align 4
-; CHECK-NEXT: call void @foo()
+; CHECK-NEXT: tail call void @foo()
; CHECK-NEXT: br label [[IF_END]]
; CHECK: if.end:
; CHECK-NEXT: [[TMP1:%.*]] = xor i1 [[CMP]], true
; CHECK-NEXT: br i1 [[CMP_1]], label [[IF_END_1:%.*]], label [[IF_THEN_1:%.*]]
; CHECK: if.then.1:
; CHECK-NEXT: store i32 [[OR]], i32* [[C]], align 4
-; CHECK-NEXT: call void @foo()
+; CHECK-NEXT: tail call void @foo()
; CHECK-NEXT: br label [[IF_END_1]]
; CHECK: if.end.1:
; CHECK-NEXT: [[CHANGED_1_OFF0_1:%.*]] = phi i1 [ true, [[IF_THEN_1]] ], [ [[TMP1]], [[IF_END]] ]
ret double %max
}
+define i1 @PR58313(i1 %lhs, i1 %rhs) {
+; CHECK-LABEL: @PR58313(
+; CHECK-NEXT: andandend:
+; CHECK-NEXT: [[TMP0:%.*]] = xor i1 [[RHS:%.*]], true
+; CHECK-NEXT: [[ANDANDVAL:%.*]] = select i1 [[LHS:%.*]], i1 [[TMP0]], i1 false
+; CHECK-NEXT: br i1 [[ANDANDVAL]], label [[OROREND:%.*]], label [[OROR:%.*]]
+; CHECK: oror:
+; CHECK-NEXT: [[TMP1:%.*]] = xor i1 [[LHS]], true
+; CHECK-NEXT: [[ANDANDVAL3:%.*]] = select i1 [[TMP1]], i1 [[RHS]], i1 false
+; CHECK-NEXT: br label [[OROREND]]
+; CHECK: ororend:
+; CHECK-NEXT: [[ORORVAL:%.*]] = phi i1 [ true, [[ANDANDEND:%.*]] ], [ [[ANDANDVAL3]], [[OROR]] ]
+; CHECK-NEXT: ret i1 [[ORORVAL]]
+;
+andandend:
+ %0 = xor i1 %rhs, true
+ %andandval = select i1 %lhs, i1 %0, i1 false
+ br i1 %andandval, label %ororend, label %oror
+
+oror:
+ %1 = xor i1 %lhs, true
+ %andandval3 = select i1 %1, i1 %rhs, i1 false
+ br label %ororend
+
+ororend:
+ %ororval = phi i1 [ true, %andandend ], [ %andandval3, %oror ]
+ ret i1 %ororval
+}
+