diff --git a/llvm/test/Transforms/ConstraintElimination/or.ll b/llvm/test/Transforms/ConstraintElimination/or.ll --- a/llvm/test/Transforms/ConstraintElimination/or.ll +++ b/llvm/test/Transforms/ConstraintElimination/or.ll @@ -431,3 +431,364 @@ ret i1 %res.9 } + +define void @test_or_as_add_ult(i8 %init_val, i8 %high) { +; CHECK-LABEL: @test_or_as_add_ult( +; CHECK-NEXT: entry: +; CHECK-NEXT: [[START:%.*]] = shl nuw nsw i8 [[INIT_VAL:%.*]], 2 +; CHECK-NEXT: [[START_PLUS_3:%.*]] = add nuw i8 [[START]], 3 +; CHECK-NEXT: [[C_1:%.*]] = icmp uge i8 [[START_PLUS_3]], [[HIGH:%.*]] +; CHECK-NEXT: br i1 [[C_1]], label [[THEN:%.*]], label [[END:%.*]] +; CHECK: then: +; CHECK-NEXT: [[F_0:%.*]] = icmp ult i8 [[START]], [[HIGH]] +; CHECK-NEXT: call void @use(i1 [[F_0]]) +; CHECK-NEXT: [[I_1:%.*]] = or i8 [[START]], 1 +; CHECK-NEXT: [[F_1:%.*]] = icmp ult i8 [[I_1]], [[HIGH]] +; CHECK-NEXT: call void @use(i1 [[F_1]]) +; CHECK-NEXT: [[I_2:%.*]] = or i8 [[START]], 2 +; CHECK-NEXT: [[F_2:%.*]] = icmp ult i8 [[I_2]], [[HIGH]] +; CHECK-NEXT: call void @use(i1 [[F_2]]) +; CHECK-NEXT: ret void +; CHECK: end: +; CHECK-NEXT: [[T_0:%.*]] = icmp ult i8 [[START]], [[HIGH]] +; CHECK-NEXT: call void @use(i1 true) +; CHECK-NEXT: [[START_1:%.*]] = or i8 [[START]], 1 +; CHECK-NEXT: [[T_1:%.*]] = icmp ult i8 [[START_1]], [[HIGH]] +; CHECK-NEXT: call void @use(i1 [[T_1]]) +; CHECK-NEXT: [[START_2:%.*]] = or i8 [[START]], 2 +; CHECK-NEXT: [[T_2:%.*]] = icmp ult i8 [[START_2]], [[HIGH]] +; CHECK-NEXT: call void @use(i1 [[T_2]]) +; CHECK-NEXT: [[START_3:%.*]] = or i8 [[START]], 3 +; CHECK-NEXT: [[T_3:%.*]] = icmp ult i8 [[START_3]], [[HIGH]] +; CHECK-NEXT: call void @use(i1 [[T_3]]) +; CHECK-NEXT: [[START_4:%.*]] = or i8 [[START]], 4 +; CHECK-NEXT: [[C_4:%.*]] = icmp ult i8 [[START_4]], [[HIGH]] +; CHECK-NEXT: call void @use(i1 [[C_4]]) +; CHECK-NEXT: ret void +; +entry: + %start = shl nuw nsw i8 %init_val, 2 + %start.plus.3 = add nuw i8 %start, 3 + %c.1 = icmp uge i8 %start.plus.3, %high + br i1 %c.1, label %then, label %end + +then: ; preds = %entry + %f.0 = icmp ult i8 %start, %high + call void @use(i1 %f.0) + %i.1 = or i8 %start, 1 + %f.1 = icmp ult i8 %i.1, %high + call void @use(i1 %f.1) + %i.2 = or i8 %start, 2 + %f.2 = icmp ult i8 %i.2, %high + call void @use(i1 %f.2) + ret void + +end: ; preds = %entry + %t.0 = icmp ult i8 %start, %high + call void @use(i1 %t.0) + %start.1 = or i8 %start, 1 + %t.1 = icmp ult i8 %start.1, %high + call void @use(i1 %t.1) + %start.2 = or i8 %start, 2 + %t.2 = icmp ult i8 %start.2, %high + call void @use(i1 %t.2) + %start.3 = or i8 %start, 3 + %t.3 = icmp ult i8 %start.3, %high + call void @use(i1 %t.3) + %start.4 = or i8 %start, 4 + %c.4 = icmp ult i8 %start.4, %high + call void @use(i1 %c.4) + ret void +} + +define void @test_or_as_add_ule(i8 %init_val, i8 %high) { +; CHECK-LABEL: @test_or_as_add_ule( +; CHECK-NEXT: entry: +; CHECK-NEXT: [[START:%.*]] = shl nuw nsw i8 [[INIT_VAL:%.*]], 2 +; CHECK-NEXT: [[START_PLUS_3:%.*]] = add nuw i8 [[START]], 3 +; CHECK-NEXT: [[C_1:%.*]] = icmp uge i8 [[START_PLUS_3]], [[HIGH:%.*]] +; CHECK-NEXT: br i1 [[C_1]], label [[THEN:%.*]], label [[END:%.*]] +; CHECK: then: +; CHECK-NEXT: [[F_0:%.*]] = icmp ule i8 [[START]], [[HIGH]] +; CHECK-NEXT: call void @use(i1 [[F_0]]) +; CHECK-NEXT: [[I_1:%.*]] = or i8 [[START]], 1 +; CHECK-NEXT: [[F_1:%.*]] = icmp ule i8 [[I_1]], [[HIGH]] +; CHECK-NEXT: call void @use(i1 [[F_1]]) +; CHECK-NEXT: [[I_2:%.*]] = or i8 [[START]], 2 +; CHECK-NEXT: [[F_2:%.*]] = icmp ule i8 [[I_2]], [[HIGH]] +; CHECK-NEXT: call void @use(i1 [[F_2]]) +; CHECK-NEXT: ret void +; CHECK: end: +; CHECK-NEXT: [[T_0:%.*]] = icmp ule i8 [[START]], [[HIGH]] +; CHECK-NEXT: call void @use(i1 true) +; CHECK-NEXT: [[START_1:%.*]] = or i8 [[START]], 1 +; CHECK-NEXT: [[T_1:%.*]] = icmp ule i8 [[START_1]], [[HIGH]] +; CHECK-NEXT: call void @use(i1 [[T_1]]) +; CHECK-NEXT: [[START_2:%.*]] = or i8 [[START]], 2 +; CHECK-NEXT: [[T_2:%.*]] = icmp ule i8 [[START_2]], [[HIGH]] +; CHECK-NEXT: call void @use(i1 [[T_2]]) +; CHECK-NEXT: [[START_3:%.*]] = or i8 [[START]], 3 +; CHECK-NEXT: [[T_3:%.*]] = icmp ule i8 [[START_3]], [[HIGH]] +; CHECK-NEXT: call void @use(i1 [[T_3]]) +; CHECK-NEXT: [[START_4:%.*]] = or i8 [[START]], 4 +; CHECK-NEXT: [[T_4:%.*]] = icmp ule i8 [[START_4]], [[HIGH]] +; CHECK-NEXT: call void @use(i1 [[T_4]]) +; CHECK-NEXT: [[START_5:%.*]] = or i8 [[START]], 5 +; CHECK-NEXT: [[C_5:%.*]] = icmp ule i8 [[START_5]], [[HIGH]] +; CHECK-NEXT: call void @use(i1 [[C_5]]) +; CHECK-NEXT: ret void +; +entry: + %start = shl nuw nsw i8 %init_val, 2 + %start.plus.3 = add nuw i8 %start, 3 + %c.1 = icmp uge i8 %start.plus.3, %high + br i1 %c.1, label %then, label %end + +then: ; preds = %entry + %f.0 = icmp ule i8 %start, %high + call void @use(i1 %f.0) + %i.1 = or i8 %start, 1 + %f.1 = icmp ule i8 %i.1, %high + call void @use(i1 %f.1) + %i.2 = or i8 %start, 2 + %f.2 = icmp ule i8 %i.2, %high + call void @use(i1 %f.2) + ret void + +end: ; preds = %entry + %t.0 = icmp ule i8 %start, %high + call void @use(i1 %t.0) + %start.1 = or i8 %start, 1 + %t.1 = icmp ule i8 %start.1, %high + call void @use(i1 %t.1) + %start.2 = or i8 %start, 2 + %t.2 = icmp ule i8 %start.2, %high + call void @use(i1 %t.2) + %start.3 = or i8 %start, 3 + %t.3 = icmp ule i8 %start.3, %high + call void @use(i1 %t.3) + %start.4 = or i8 %start, 4 + %t.4 = icmp ule i8 %start.4, %high + call void @use(i1 %t.4) + %start.5 = or i8 %start, 5 + %c.5 = icmp ule i8 %start.5, %high + call void @use(i1 %c.5) + + ret void +} + +define void @test_or_as_add_ugt(i8 %init_val, i8 %high) { +; CHECK-LABEL: @test_or_as_add_ugt( +; CHECK-NEXT: entry: +; CHECK-NEXT: [[START:%.*]] = shl nuw nsw i8 [[INIT_VAL:%.*]], 2 +; CHECK-NEXT: [[START_PLUS_3:%.*]] = add nuw i8 [[START]], 3 +; CHECK-NEXT: [[C_1:%.*]] = icmp uge i8 [[START_PLUS_3]], [[HIGH:%.*]] +; CHECK-NEXT: br i1 [[C_1]], label [[THEN:%.*]], label [[END:%.*]] +; CHECK: then: +; CHECK-NEXT: [[T_0:%.*]] = icmp ugt i8 [[START]], [[HIGH]] +; CHECK-NEXT: call void @use(i1 [[T_0]]) +; CHECK-NEXT: [[I_1:%.*]] = or i8 [[START]], 1 +; CHECK-NEXT: [[T_1:%.*]] = icmp ugt i8 [[I_1]], [[HIGH]] +; CHECK-NEXT: call void @use(i1 [[T_1]]) +; CHECK-NEXT: [[I_2:%.*]] = or i8 [[START]], 2 +; CHECK-NEXT: [[T_2:%.*]] = icmp ugt i8 [[I_2]], [[HIGH]] +; CHECK-NEXT: call void @use(i1 [[T_2]]) +; CHECK-NEXT: ret void +; CHECK: end: +; CHECK-NEXT: [[F_0:%.*]] = icmp ugt i8 [[START]], [[HIGH]] +; CHECK-NEXT: call void @use(i1 false) +; CHECK-NEXT: [[START_1:%.*]] = or i8 [[START]], 1 +; CHECK-NEXT: [[F_1:%.*]] = icmp ugt i8 [[START_1]], [[HIGH]] +; CHECK-NEXT: call void @use(i1 [[F_1]]) +; CHECK-NEXT: [[START_2:%.*]] = or i8 [[START]], 2 +; CHECK-NEXT: [[F_2:%.*]] = icmp ugt i8 [[START_2]], [[HIGH]] +; CHECK-NEXT: call void @use(i1 [[F_2]]) +; CHECK-NEXT: [[START_3:%.*]] = or i8 [[START]], 3 +; CHECK-NEXT: [[F_3:%.*]] = icmp ugt i8 [[START_3]], [[HIGH]] +; CHECK-NEXT: call void @use(i1 [[F_3]]) +; CHECK-NEXT: [[START_4:%.*]] = or i8 [[START]], 4 +; CHECK-NEXT: [[F_4:%.*]] = icmp ugt i8 [[START_4]], [[HIGH]] +; CHECK-NEXT: call void @use(i1 [[F_4]]) +; CHECK-NEXT: [[START_5:%.*]] = or i8 [[START]], 5 +; CHECK-NEXT: [[C_5:%.*]] = icmp ugt i8 [[START_5]], [[HIGH]] +; CHECK-NEXT: call void @use(i1 [[C_5]]) +; CHECK-NEXT: ret void +; +entry: + %start = shl nuw nsw i8 %init_val, 2 + %start.plus.3 = add nuw i8 %start, 3 + %c.1 = icmp uge i8 %start.plus.3, %high + br i1 %c.1, label %then, label %end + +then: ; preds = %entry + %t.0 = icmp ugt i8 %start, %high + call void @use(i1 %t.0) + %i.1 = or i8 %start, 1 + %t.1 = icmp ugt i8 %i.1, %high + call void @use(i1 %t.1) + %i.2 = or i8 %start, 2 + %t.2 = icmp ugt i8 %i.2, %high + call void @use(i1 %t.2) + ret void + +end: ; preds = %entry + %f.0 = icmp ugt i8 %start, %high + call void @use(i1 %f.0) + %start.1 = or i8 %start, 1 + %f.1 = icmp ugt i8 %start.1, %high + call void @use(i1 %f.1) + %start.2 = or i8 %start, 2 + %f.2 = icmp ugt i8 %start.2, %high + call void @use(i1 %f.2) + %start.3 = or i8 %start, 3 + %f.3 = icmp ugt i8 %start.3, %high + call void @use(i1 %f.3) + %start.4 = or i8 %start, 4 + %f.4 = icmp ugt i8 %start.4, %high + call void @use(i1 %f.4) + %start.5 = or i8 %start, 5 + %c.5 = icmp ugt i8 %start.5, %high + call void @use(i1 %c.5) + ret void +} + +define void @test_or_as_add_uge(i8 %init_val, i8 %high) { +; CHECK-LABEL: @test_or_as_add_uge( +; CHECK-NEXT: entry: +; CHECK-NEXT: [[START:%.*]] = shl nuw nsw i8 [[INIT_VAL:%.*]], 2 +; CHECK-NEXT: [[START_PLUS_3:%.*]] = add nuw i8 [[START]], 3 +; CHECK-NEXT: [[C_1:%.*]] = icmp uge i8 [[START_PLUS_3]], [[HIGH:%.*]] +; CHECK-NEXT: br i1 [[C_1]], label [[THEN:%.*]], label [[END:%.*]] +; CHECK: then: +; CHECK-NEXT: [[T_0:%.*]] = icmp ugt i8 [[START]], [[HIGH]] +; CHECK-NEXT: call void @use(i1 [[T_0]]) +; CHECK-NEXT: [[I_1:%.*]] = or i8 [[START]], 1 +; CHECK-NEXT: [[T_1:%.*]] = icmp uge i8 [[I_1]], [[HIGH]] +; CHECK-NEXT: call void @use(i1 [[T_1]]) +; CHECK-NEXT: [[I_2:%.*]] = or i8 [[START]], 2 +; CHECK-NEXT: [[T_2:%.*]] = icmp uge i8 [[I_2]], [[HIGH]] +; CHECK-NEXT: call void @use(i1 [[T_2]]) +; CHECK-NEXT: ret void +; CHECK: end: +; CHECK-NEXT: [[F_0:%.*]] = icmp ugt i8 [[START]], [[HIGH]] +; CHECK-NEXT: call void @use(i1 false) +; CHECK-NEXT: [[START_1:%.*]] = or i8 [[START]], 1 +; CHECK-NEXT: [[F_1:%.*]] = icmp uge i8 [[START_1]], [[HIGH]] +; CHECK-NEXT: call void @use(i1 [[F_1]]) +; CHECK-NEXT: [[START_2:%.*]] = or i8 [[START]], 2 +; CHECK-NEXT: [[F_2:%.*]] = icmp uge i8 [[START_2]], [[HIGH]] +; CHECK-NEXT: call void @use(i1 [[F_2]]) +; CHECK-NEXT: [[START_3:%.*]] = or i8 [[START]], 3 +; CHECK-NEXT: [[F_3:%.*]] = icmp uge i8 [[START_3]], [[HIGH]] +; CHECK-NEXT: call void @use(i1 [[F_3]]) +; CHECK-NEXT: [[START_4:%.*]] = or i8 [[START]], 4 +; CHECK-NEXT: [[C_4:%.*]] = icmp uge i8 [[START_4]], [[HIGH]] +; CHECK-NEXT: call void @use(i1 [[C_4]]) +; CHECK-NEXT: [[START_5:%.*]] = or i8 [[START]], 5 +; CHECK-NEXT: [[C_5:%.*]] = icmp uge i8 [[START_5]], [[HIGH]] +; CHECK-NEXT: call void @use(i1 [[C_5]]) +; CHECK-NEXT: ret void +; +entry: + %start = shl nuw nsw i8 %init_val, 2 + %start.plus.3 = add nuw i8 %start, 3 + %c.1 = icmp uge i8 %start.plus.3, %high + br i1 %c.1, label %then, label %end + +then: ; preds = %entry + %t.0 = icmp ugt i8 %start, %high + call void @use(i1 %t.0) + %i.1 = or i8 %start, 1 + %t.1 = icmp uge i8 %i.1, %high + call void @use(i1 %t.1) + %i.2 = or i8 %start, 2 + %t.2 = icmp uge i8 %i.2, %high + call void @use(i1 %t.2) + ret void + +end: ; preds = %entry + %f.0 = icmp ugt i8 %start, %high + call void @use(i1 %f.0) + %start.1 = or i8 %start, 1 + %f.1 = icmp uge i8 %start.1, %high + call void @use(i1 %f.1) + %start.2 = or i8 %start, 2 + %f.2 = icmp uge i8 %start.2, %high + call void @use(i1 %f.2) + %start.3 = or i8 %start, 3 + %f.3 = icmp uge i8 %start.3, %high + call void @use(i1 %f.3) + %start.4 = or i8 %start, 4 + %c.4 = icmp uge i8 %start.4, %high + call void @use(i1 %c.4) + %start.5 = or i8 %start, 5 + %c.5 = icmp uge i8 %start.5, %high + call void @use(i1 %c.5) + ret void +} + +define void @test_not_decompose(i8 %start, i8 %high) { +; CHECK-LABEL: @test_not_decompose( +; CHECK-NEXT: entry: +; CHECK-NEXT: [[START_PLUS_3:%.*]] = add nuw i8 [[START:%.*]], 3 +; CHECK-NEXT: [[C_1:%.*]] = icmp uge i8 [[START_PLUS_3]], [[HIGH:%.*]] +; CHECK-NEXT: br i1 [[C_1]], label [[THEN:%.*]], label [[END:%.*]] +; CHECK: then: +; CHECK-NEXT: [[I_1:%.*]] = or i8 [[START]], 1 +; CHECK-NEXT: [[T_1:%.*]] = icmp uge i8 [[I_1]], [[HIGH]] +; CHECK-NEXT: call void @use(i1 [[T_1]]) +; CHECK-NEXT: [[I_2:%.*]] = or i8 [[START]], 2 +; CHECK-NEXT: [[T_2:%.*]] = icmp uge i8 [[I_2]], [[HIGH]] +; CHECK-NEXT: call void @use(i1 [[T_2]]) +; CHECK-NEXT: ret void +; CHECK: end: +; CHECK-NEXT: [[START_1:%.*]] = or i8 [[START]], 1 +; CHECK-NEXT: [[F_1:%.*]] = icmp uge i8 [[START_1]], [[HIGH]] +; CHECK-NEXT: call void @use(i1 [[F_1]]) +; CHECK-NEXT: [[START_2:%.*]] = or i8 [[START]], 2 +; CHECK-NEXT: [[F_2:%.*]] = icmp uge i8 [[START_2]], [[HIGH]] +; CHECK-NEXT: call void @use(i1 [[F_2]]) +; CHECK-NEXT: [[START_3:%.*]] = or i8 [[START]], 3 +; CHECK-NEXT: [[F_3:%.*]] = icmp uge i8 [[START_3]], [[HIGH]] +; CHECK-NEXT: call void @use(i1 [[F_3]]) +; CHECK-NEXT: [[START_4:%.*]] = or i8 [[START]], 4 +; CHECK-NEXT: [[C_4:%.*]] = icmp uge i8 [[START_4]], [[HIGH]] +; CHECK-NEXT: call void @use(i1 [[C_4]]) +; CHECK-NEXT: [[START_5:%.*]] = or i8 [[START]], 5 +; CHECK-NEXT: [[C_5:%.*]] = icmp uge i8 [[START_5]], [[HIGH]] +; CHECK-NEXT: call void @use(i1 [[C_5]]) +; CHECK-NEXT: ret void +; +entry: + %start.plus.3 = add nuw i8 %start, 3 + %c.1 = icmp uge i8 %start.plus.3, %high + br i1 %c.1, label %then, label %end + +then: ; preds = %entry + %i.1 = or i8 %start, 1 + %t.1 = icmp uge i8 %i.1, %high + call void @use(i1 %t.1) + %i.2 = or i8 %start, 2 + %t.2 = icmp uge i8 %i.2, %high + call void @use(i1 %t.2) + ret void + +end: ; preds = %entry + %start.1 = or i8 %start, 1 + %f.1 = icmp uge i8 %start.1, %high + call void @use(i1 %f.1) + %start.2 = or i8 %start, 2 + %f.2 = icmp uge i8 %start.2, %high + call void @use(i1 %f.2) + %start.3 = or i8 %start, 3 + %f.3 = icmp uge i8 %start.3, %high + call void @use(i1 %f.3) + %start.4 = or i8 %start, 4 + %c.4 = icmp uge i8 %start.4, %high + call void @use(i1 %c.4) + %start.5 = or i8 %start, 5 + %c.5 = icmp uge i8 %start.5, %high + call void @use(i1 %c.5) + + ret void +}